Prompt工程 入门 Prompt工程 Zero-shot Few-shot System Prompt

Prompt 工程基础:从 Zero-shot 到 Few-shot 的系统化方法

AIEng Hub
阅读约 20 分钟

什么是 Prompt 工程?

Prompt 工程(Prompt Engineering)是设计和优化输入提示(Prompt)以引导大语言模型(LLM)产生期望输出的技术和方法。

┌─────────────────────────────────────────────────────────────┐
│                    Prompt 工程的核心                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   输入 (Prompt)                    输出 (Response)          │
│   ┌───────────────────┐           ┌───────────────────┐    │
│   │ 指令               │           │                   │    │
│   │ 上下文             │    →     │   LLM             │    │
│   │ 示例               │           │                   │    │
│   │ 格式要求           │           │   生成结果        │    │
│   │ 约束条件           │           │                   │    │
│   └───────────────────┘           └───────────────────┘    │
│                                                             │
│   Prompt 工程 = 设计最优输入结构 + 优化输出质量               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

为什么 Prompt 工程重要?

  • 成本效益:比微调模型成本低得多
  • 快速迭代:无需重新训练即可优化
  • 通用性强:适用于各种 LLM
  • 效果可观:好的 Prompt 能显著提升输出质量

Prompt 的基本结构

1. 核心组件

# prompt_structure.py
class PromptComponents:
    """Prompt 核心组件"""
    
    @staticmethod
    def create_basic_prompt(
        instruction: str,
        context: str = "",
        examples: list = None,
        output_format: str = "",
        constraints: list = None
    ) -> str:
        """创建基础 Prompt"""
        
        prompt_parts = []
        
        # 1. 指令(必需)
        prompt_parts.append(f"指令:{instruction}")
        
        # 2. 上下文(可选)
        if context:
            prompt_parts.append(f"\n背景信息:\n{context}")
        
        # 3. 示例(可选)
        if examples:
            prompt_parts.append("\n示例:")
            for i, example in enumerate(examples, 1):
                prompt_parts.append(f"\n示例{i}:")
                prompt_parts.append(f"输入:{example['input']}")
                prompt_parts.append(f"输出:{example['output']}")
        
        # 4. 输出格式(可选)
        if output_format:
            prompt_parts.append(f"\n输出格式:\n{output_format}")
        
        # 5. 约束条件(可选)
        if constraints:
            prompt_parts.append("\n约束条件:")
            for constraint in constraints:
                prompt_parts.append(f"- {constraint}")
        
        # 6. 实际输入
        prompt_parts.append("\n现在请处理以下输入:")
        
        return "\n".join(prompt_parts)


# 使用示例
prompt = PromptComponents.create_basic_prompt(
    instruction="将以下中文文本翻译成英文",
    context="这是一段技术文档",
    examples=[
        {
            "input": "人工智能是计算机科学的一个分支",
            "output": "Artificial intelligence is a branch of computer science"
        }
    ],
    output_format="只输出翻译结果,不要解释",
    constraints=["保持专业术语准确", "语句通顺自然"]
)

print(prompt)

2. System Prompt

System Prompt 用于设定 AI 的角色和行为准则。

# system_prompt_examples.py
SYSTEM_PROMPTS = {
    "technical_writer": """你是一位资深技术文档工程师。你的职责是:
- 将复杂的技术概念解释得清晰易懂
- 使用准确的技术术语
- 提供具体的代码示例
- 保持客观中立的语气
- 结构清晰,层次分明""",
    
    "code_reviewer": """你是一位经验丰富的代码审查专家。请:
- 检查代码的正确性和效率
- 指出潜在的错误和风险
- 提供改进建议
- 关注代码可读性和维护性
- 遵循最佳实践""",
    
    "creative_writer": """你是一位创意写作助手。请:
- 提供富有创意的想法
- 使用生动的语言
- 保持内容的原创性
- 根据用户需求调整风格
- 鼓励创新思维""",
    
    "data_analyst": """你是一位数据分析师。请:
- 准确解读数据
- 提供数据驱动的见解
- 使用统计方法分析
- 可视化数据趋势
- 给出 actionable 的建议""",
}

def create_chat_prompt(system_prompt: str, user_message: str) -> list:
    """创建聊天格式的 Prompt"""
    return [
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_message}
    ]

Zero-shot Learning

Zero-shot 是指不提供示例,直接让模型完成任务。

1. 基础 Zero-shot

# zero_shot_prompts.py
class ZeroShotPrompts:
    """Zero-shot Prompt 模板"""
    
    @staticmethod
    def classify_sentiment(text: str) -> str:
        """情感分类"""
        return f"""分析以下文本的情感倾向(正面/负面/中性):

文本:{text}

情感:"""
    
    @staticmethod
    def extract_entities(text: str, entity_types: list) -> str:
        """实体抽取"""
        return f"""从以下文本中提取指定的实体类型:{', '.join(entity_types)}

文本:{text}

请以 JSON 格式返回提取结果。"""
    
    @staticmethod
    def summarize(text: str, max_length: int = 100) -> str:
        """文本摘要"""
        return f"""请对以下文本进行摘要,不超过{max_length}字:

{text}

摘要:"""
    
    @staticmethod
    def translate(text: str, target_lang: str) -> str:
        """文本翻译"""
        return f"""将以下文本翻译成{target_lang}

{text}

翻译结果:"""
    
    @staticmethod
    def generate_code(description: str, language: str) -> str:
        """代码生成"""
        return f"""请用{language}编写代码实现以下功能:

功能描述:{description}

要求:
- 代码清晰易读
- 添加必要的注释
- 包含错误处理
- 遵循最佳实践

代码:"""

# 使用示例
prompt = ZeroShotPrompts.classify_sentiment(
    "这款手机的电池续航太棒了,可以用一整天!"
)

2. 结构化 Zero-shot

# structured_zero_shot.py
def create_structured_prompt(task: str, input_data: dict, output_schema: dict) -> str:
    """创建结构化 Zero-shot Prompt"""
    
    prompt = f"""任务:{task}

输入数据:
{json.dumps(input_data, indent=2, ensure_ascii=False)}

请按照以下 JSON Schema 格式输出结果:
{json.dumps(output_schema, indent=2)}

要求:
1. 严格遵循 Schema 格式
2. 所有字段必须填写
3. 不要添加额外说明

输出:"""
    
    return prompt

# 使用示例
output_schema = {
    "type": "object",
    "properties": {
        "product_name": {"type": "string"},
        "category": {"type": "string"},
        "price": {"type": "number"},
        "features": {"type": "array", "items": {"type": "string"}},
        "pros": {"type": "array", "items": {"type": "string"}},
        "cons": {"type": "array", "items": {"type": "string"}}
    },
    "required": ["product_name", "category", "price", "features"]
}

prompt = create_structured_prompt(
    task="分析产品信息",
    input_data={"description": "iPhone 15 Pro,售价7999元,钛金属设计,A17 Pro芯片"},
    output_schema=output_schema
)

Few-shot Learning

Few-shot 通过提供少量示例来引导模型理解任务模式。

1. 基础 Few-shot

# few_shot_prompts.py
class FewShotPrompts:
    """Few-shot Prompt 模板"""
    
    @staticmethod
    def create_prompt(
        task_description: str,
        examples: list,
        test_input: str,
        num_examples: int = 3
    ) -> str:
        """创建 Few-shot Prompt"""
        
        prompt_parts = [f"任务:{task_description}\n"]
        
        # 添加示例
        for i, example in enumerate(examples[:num_examples], 1):
            prompt_parts.append(f"示例{i}:")
            prompt_parts.append(f"输入:{example['input']}")
            prompt_parts.append(f"输出:{example['output']}\n")
        
        # 添加测试输入
        prompt_parts.append("现在请处理:")
        prompt_parts.append(f"输入:{test_input}")
        prompt_parts.append("输出:")
        
        return "\n".join(prompt_parts)

# 情感分析 Few-shot
sentiment_examples = [
    {
        "input": "这部电影太精彩了,强烈推荐!",
        "output": "正面"
    },
    {
        "input": "服务态度很差,等了一个小时",
        "output": "负面"
    },
    {
        "input": "今天天气不错",
        "output": "中性"
    }
]

prompt = FewShotPrompts.create_prompt(
    task_description="判断文本的情感倾向(正面/负面/中性)",
    examples=sentiment_examples,
    test_input="这个产品的质量超出预期,性价比很高"
)

2. 多样本 Few-shot

# diverse_few_shot.py
def create_diverse_few_shot(
    task: str,
    examples: list,
    test_input: str
) -> str:
    """创建多样化的 Few-shot Prompt"""
    
    # 按类别组织示例
    categories = {}
    for ex in examples:
        cat = ex.get("category", "default")
        if cat not in categories:
            categories[cat] = []
        categories[cat].append(ex)
    
    prompt_parts = [f"任务:{task}\n"]
    prompt_parts.append("以下是不同类型的示例:\n")
    
    for category, cat_examples in categories.items():
        prompt_parts.append(f"\n{category}类型】")
        for i, ex in enumerate(cat_examples[:2], 1):
            prompt_parts.append(f"示例{i}:")
            prompt_parts.append(f"输入:{ex['input']}")
            prompt_parts.append(f"输出:{ex['output']}")
    
    prompt_parts.append(f"\n现在请处理:")
    prompt_parts.append(f"输入:{test_input}")
    prompt_parts.append("输出:")
    
    return "\n".join(prompt_parts)

# 文本转换任务示例
text_transform_examples = [
    {
        "input": "把这段文字改写成正式的商业邮件",
        "output": "尊敬的合作伙伴:\n\n您好!关于我们之前讨论的合作事宜...",
        "category": "正式化"
    },
    {
        "input": "用简洁的方式总结这段内容",
        "output": "核心要点:1. 提高效率 2. 降低成本 3. 改善体验",
        "category": "简化"
    },
    {
        "input": "把技术文档改写成通俗易懂的说明",
        "output": "简单来说,这个功能就像是...",
        "category": "通俗化"
    }
]

3. 动态 Few-shot

# dynamic_few_shot.py
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

class DynamicFewShot:
    """动态选择示例的 Few-shot"""
    
    def __init__(self, examples: list):
        self.examples = examples
        self.vectorizer = TfidfVectorizer()
        
        # 预计算示例的向量
        example_texts = [ex['input'] for ex in examples]
        self.example_vectors = self.vectorizer.fit_transform(example_texts)
    
    def get_similar_examples(self, query: str, k: int = 3) -> list:
        """获取与查询最相似的 k 个示例"""
        
        # 计算查询的向量
        query_vector = self.vectorizer.transform([query])
        
        # 计算相似度
        similarities = cosine_similarity(
            query_vector,
            self.example_vectors
        ).flatten()
        
        # 获取最相似的 k 个索引
        top_k_indices = np.argsort(similarities)[-k:][::-1]
        
        return [self.examples[i] for i in top_k_indices]
    
    def create_prompt(self, task: str, query: str, k: int = 3) -> str:
        """创建动态 Few-shot Prompt"""
        
        similar_examples = self.get_similar_examples(query, k)
        
        prompt_parts = [f"任务:{task}\n"]
        
        for i, example in enumerate(similar_examples, 1):
            prompt_parts.append(f"\n相似示例{i}:")
            prompt_parts.append(f"输入:{example['input']}")
            prompt_parts.append(f"输出:{example['output']}")
        
        prompt_parts.append(f"\n现在请处理:")
        prompt_parts.append(f"输入:{query}")
        prompt_parts.append("输出:")
        
        return "\n".join(prompt_parts)

# 使用示例
all_examples = [
    {"input": "帮我写一封请假邮件", "output": "..."},
    {"input": "写一封商务合作邮件", "output": "..."},
    # ... 更多示例
]

dynamic_fs = DynamicFewShot(all_examples)
prompt = dynamic_fs.create_prompt(
    task="撰写专业邮件",
    query="帮我写一封辞职邮件"
)

Prompt 设计原则

1. 清晰性原则

# clarity_principles.py
BAD_PROMPT = "写点东西"

GOOD_PROMPT = """请撰写一篇关于人工智能在医疗领域应用的技术博客文章。

要求:
- 字数:1000-1500字
- 结构:引言、3个应用案例、未来展望、结论
- 风格:专业但易懂,适合技术人员阅读
- 包含:具体的应用场景和数据支持"""

2. 具体性原则

# specificity_principles.py
VAGUE_PROMPT = "分析这段代码"

SPECIFIC_PROMPT = """请对以下 Python 函数进行代码审查:

```python
def calculate_average(numbers):
    total = sum(numbers)
    return total / len(numbers)

请从以下维度分析:

  1. 正确性:是否存在逻辑错误
  2. 健壮性:是否处理了边界情况
  3. 效率:时间复杂度和空间复杂度
  4. 可读性:命名和结构是否清晰
  5. 改进建议:具体的优化方案"""

### 3. 一致性原则

```python
# consistency_principles.py
CONSISTENT_PROMPT = """将以下句子翻译成法语。保持格式一致:

示例:
英文:Hello, how are you?
法文:Bonjour, comment allez-vous?

英文:{input}
法文:"""

常见任务模板

1. 文本分类

# classification_template.py
CLASSIFICATION_TEMPLATE = """请对以下文本进行分类。

分类类别:{categories}

示例:
{examples}

待分类文本:{text}

分类结果(只输出类别名称):"""

# 使用示例
classification_prompt = CLASSIFICATION_TEMPLATE.format(
    categories="科技、体育、娱乐、政治、经济",
    examples="""
文本:苹果公司发布新款iPhone
类别:科技

文本:湖人队赢得总冠军
类别:体育
""",
    text="特斯拉股价创新高"
)

2. 信息抽取

# extraction_template.py
EXTRACTION_TEMPLATE = """从以下文本中提取指定信息。

需要提取的字段:{fields}

示例:
文本:张三,电话:13800138000,邮箱:zhangsan@example.com
提取结果:
{example_output}

待处理文本:{text}

请以 JSON 格式输出提取结果:"""

# 使用示例
extraction_prompt = EXTRACTION_TEMPLATE.format(
    fields="姓名、电话、邮箱、地址",
    example_output='{"姓名": "张三", "电话": "13800138000", "邮箱": "zhangsan@example.com"}',
    text="李四,联系方式:13900139000,li si@company.com,地址:北京市海淀区"
)

3. 问答生成

# qa_template.py
QA_TEMPLATE = """基于以下上下文,回答问题。

上下文:
{context}

问题:{question}

请根据上下文提供准确的答案。如果上下文中没有相关信息,请回答"根据提供的信息无法回答"。

答案:"""

Prompt 优化技巧

1. 迭代优化

# iterative_optimization.py
def iterative_prompt_refinement(
    initial_prompt: str,
    test_cases: list,
    max_iterations: int = 5
) -> str:
    """迭代优化 Prompt"""
    
    prompt = initial_prompt
    
    for iteration in range(max_iterations):
        print(f"\n迭代 {iteration + 1}:")
        
        # 测试当前 Prompt
        results = []
        for test_case in test_cases:
            # 这里调用 LLM
            # result = llm.generate(prompt.format(**test_case['input']))
            # results.append(result)
            pass
        
        # 评估结果
        # score = evaluate_results(results, [tc['expected'] for tc in test_cases])
        
        # 根据评估结果优化 Prompt
        # prompt = refine_prompt(prompt, results)
        
        print(f"当前 Prompt:\n{prompt}\n")
    
    return prompt

2. A/B 测试

# ab_testing.py
import random

def ab_test_prompts(
    prompt_a: str,
    prompt_b: str,
    test_cases: list,
    evaluation_func
) -> dict:
    """A/B 测试两个 Prompt"""
    
    results = {
        "A": {"scores": [], "examples": []},
        "B": {"scores": [], "examples": []}
    }
    
    for test_case in test_cases:
        # 随机分配
        variant = random.choice(["A", "B"])
        prompt = prompt_a if variant == "A" else prompt_b
        
        # 生成结果
        # output = llm.generate(prompt.format(**test_case['input']))
        
        # 评估
        # score = evaluation_func(output, test_case['expected'])
        
        # results[variant]["scores"].append(score)
        # results[variant]["examples"].append({
        #     "input": test_case['input'],
        #     "output": output,
        #     "expected": test_case['expected']
        # })
    
    # 计算平均得分
    results["A"]["avg_score"] = sum(results["A"]["scores"]) / len(results["A"]["scores"])
    results["B"]["avg_score"] = sum(results["B"]["scores"]) / len(results["B"]["scores"])
    
    return results

最佳实践总结

Prompt 设计检查清单

  • 明确任务:清楚地描述需要模型做什么
  • 提供上下文:给出必要的背景信息
  • 使用示例:Few-shot 比 Zero-shot 更稳定
  • 指定格式:明确输出的结构和格式
  • 添加约束:说明限制条件和要求
  • 测试验证:用多个案例测试 Prompt 效果
  • 迭代优化:根据结果持续改进

常见错误

  1. 过于模糊:“写点东西” → “写一篇关于 X 的 Y 字文章”
  2. 缺乏示例:直接要求复杂任务而不给示例
  3. 忽略边界:没有说明异常情况的处理
  4. 格式混乱:输出格式要求不清晰
  5. 过度复杂:Prompt 过长,重点不突出

相关资源: