Skip to content

提示工程系统方法论

提示工程(Prompt Engineering)是设计与优化输入文本以引导大语言模型产生期望输出的技术体系。本指南从方法论框架出发,覆盖生产环境的完整实践路径。

概述

提示工程不是"试错艺术",而是可以系统化、可测量、可复现的工程实践。一个优秀的提示系统需要:

  • 清晰的策略框架:理解何时使用何种技术
  • 可维护的结构:模板化、版本化、可测试
  • 可量化的优化:基于指标的迭代改进
  • 安全性的考量:防止注入、确保合规

1. 核心方法论框架

1.1 OpenAI 六大策略

OpenAI 官方提出的提示工程六大核心策略构成了方法论的基础:

策略一:编写清晰的指令

模型无法读取你的心思。如果输出太长,要求简短;如果输出太简单,要求专业级;如果格式不好,提供期望格式。

具体技巧

  • 在查询中包含详细信息以获得更相关的答案
  • 要求模型采用特定角色(系统提示)
  • 使用分隔符清晰标示输入的不同部分
  • 指定完成任务所需的步骤
  • 提供示例(few-shot prompting)
  • 指定输出的期望长度
❌ 差:"写一首关于秋天的诗"
✅ 好:"你是一位唐代诗人。写一首五言绝句描写秋天,
      要求押韵,体现萧瑟与收获的双重意境。
      格式:每句五个字,共四句。"

策略二:提供参考文本

让模型基于提供的文本回答,而非依赖其内部知识(可减少幻觉)。

请基于以下文档回答用户问题。如果文档中没有相关信息,
请明确说明"根据提供的文档,我无法找到答案"。

<document>
{{DOCUMENT}}
</document>

<question>
{{QUESTION}}
</question>

策略三:将复杂任务拆分为子任务

复杂任务的错误率通常更高。将任务分解为一系列更简单的子任务。

模式:意图分类 → 路由到专门处理流程 → 各子任务独立处理 → 结果汇总

策略四:给模型"思考"的时间

要求模型在给出答案前先进行推理(Chain-of-Thought)。

请逐步解决这个问题,先解释你的推理过程,再给出最终答案。

问题:一个农场有鸡和兔,共 35 个头,94 只脚。
      鸡和兔各有多少只?

思考过程:

策略五:使用外部工具

  • 嵌入检索:将知识库向量化,检索相关片段作为上下文
  • 代码执行:让模型生成代码,执行后获取精确结果
  • Function Calling:赋予模型调用 API 的能力

策略六:系统地测试变更

建立评估基准,对提示的任何修改进行 A/B 测试。

1.2 Anthropic 清晰直接原则

Anthropic 强调清晰直接的提示风格:

  • 将提示视为指令而非对话
  • 避免不必要的寒暄,直接说明任务
  • 使用编号列表组织复杂指令
  • 使用 XML 标签结构化输入
xml
<document>{{DOCUMENT}}</document>
<instructions>
  1. 提取所有日期
  2. 格式化为 YYYY-MM-DD
  3. 按时间顺序排列
</instructions>
<output_format>
  JSON 数组,每个元素包含 "original" 和 "formatted" 字段
</output_format>

1.3 Google 企业级最佳实践

Google 提出的企业级提示工程七大原则:

  1. 明确且具体的指令:避免歧义,每个词都应有明确目的
  2. 提供上下文:背景信息显著提高准确性
  3. 使用示例:Few-shot 学习是最可靠的提升方式
  4. 迭代优化:测试-评估-改进循环
  5. 控制输出格式:明确期望的响应结构
  6. 处理边缘情况:设计异常处理逻辑
  7. 监控和评估:持续跟踪性能指标

2. 提示技术类型学

2.1 Zero-shot vs Few-shot

技术定义适用场景示例数量
Zero-shot直接下达指令,不提供示例通用任务、简单分类0
One-shot提供 1 个示例格式明确的任务1
Few-shot提供 2-10 个示例复杂模式、风格迁移2-10
Many-shot提供数十个示例高难度任务、领域适配10-100+

Few-shot 设计原则

  • 示例应覆盖输入分布的多样性
  • 示例顺序:简单 → 复杂( priming 效应)
  • 标签分布应与真实分布一致
  • 示例格式必须与测试时完全一致

2.2 Chain-of-Thought (CoT)

要求模型展示推理过程,显著提升复杂任务表现。

手动 CoT

问题:Roger 有 5 个网球,又买了 2 罐,每罐 3 个。
      他现在有多少个?

让我们一步步思考:
Roger 开始有 5 个球。
2 罐,每罐 3 个 = 6 个球。
5 + 6 = 11。
答案:11

自动 CoT (Auto-CoT)

  • 自动从训练数据中采样多样化的问题-推理链对
  • 无需人工编写推理链

2.3 System Prompt 设计

System Prompt 定义了模型的全局行为约束,通常包含四层组件:

┌─────────────────────────────────────┐
│  角色定义 (Role)                      │
│  "你是一位资深 Python 工程师..."       │
├─────────────────────────────────────┤
│  任务描述 (Task)                      │
│  "你的任务是审查代码并提供改进建议..."   │
├─────────────────────────────────────┤
│  约束条件 (Constraints)               │
│  "- 只关注安全问题\n- 使用中文回复"      │
├─────────────────────────────────────┤
│  输出格式 (Format)                    │
│  "按严重程度排序,使用 Markdown 列表"    │
└─────────────────────────────────────┘

3. 生产环境实践

3.1 提示模板设计

使用模板引擎(如 Jinja2)管理提示:

python
from jinja2 import Template

prompt_template = Template("""
你是一位{{ role }}。请根据以下背景信息回答问题。

<背景>
{{ context }}
</背景>

<问题>
{{ question }}
</问题>

要求:
{% for constraint in constraints %}
- {{ constraint }}
{% endfor %}

{% if examples %}
<示例>
{% for ex in examples %}
输入:{{ ex.input }}
输出:{{ ex.output }}

{% endfor %}
</示例>
{% endif %}
""")

prompt = prompt_template.render(
    role="技术专家",
    context="...",
    question="...",
    constraints=["使用中文", "控制在 200 字内"],
    examples=[...]
)

3.2 变量管理

将提示中的动态内容抽象为变量:

变量类型说明示例
输入变量用户提供的动态内容
配置变量系统配置项
上下文变量检索到的外部信息
状态变量对话历史或会话状态

3.3 版本控制

提示应像代码一样进行版本管理:

prompts/
├── v1.0.0/
│   ├── qa_prompt.j2
│   └── summarize_prompt.j2
├── v1.1.0/
│   ├── qa_prompt.j2      # 优化了 few-shot 示例
│   └── summarize_prompt.j2
└── versions.yaml         # 版本变更日志

语义化版本

  • MAJOR:提示逻辑重大变更,可能影响输出格式
  • MINOR:新增功能或优化,向后兼容
  • PATCH:修复问题,不影响输出结构

4. 高级设计模式

4.1 结构化输出

强制模型按指定格式输出,便于下游解析:

JSON Schema 模式

json
{
  "type": "json_schema",
  "json_schema": {
    "name": "qa_response",
    "schema": {
      "type": "object",
      "properties": {
        "answer": {"type": "string"},
        "confidence": {"type": "number", "minimum": 0, "maximum": 1},
        "sources": {
          "type": "array",
          "items": {"type": "string"}
        }
      },
      "required": ["answer", "confidence"]
    }
  }
}

XML 标签模式(Anthropic 推荐):

xml
<response>
  <answer>量子计算利用量子叠加和纠缠进行计算</answer>
  <confidence>0.95</confidence>
  <sources>
    <source>Nielsen & Chuang, Quantum Computation</source>
  </sources>
</response>

4.2 Function Calling / Tool Use

让模型自主决定何时调用外部工具:

python
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气信息",  # 关键:描述决定调用时机
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市名称,如'北京'"
                    }
                },
                "required": ["location"]
            }
        }
    }
]

设计原则

  1. 描述即契约:function description 是模型决定是否调用的唯一依据
  2. 参数精确:使用 enumpattern 等约束减少错误
  3. 错误传播:工具执行错误应反馈给模型处理
  4. 并行调用:支持同时调用多个独立工具

5. 对话系统管理

5.1 记忆类型选择

记忆类型特点适用场景
Buffer Memory保留完整历史短对话(< 10 轮)
Buffer Window保留最近 K 轮中等长度对话
Summary Memory渐进式摘要长对话
Entity Memory提取关键实体信息密集型对话
Vector Store语义检索历史超长对话

5.2 上下文压缩技术

当对话历史超过上下文窗口时,需要压缩:

  1. LLMLingua:使用小模型计算 token 困惑度,移除低信息量 token(压缩率 20x)
  2. Map-Reduce:分块摘要 → 合并摘要 → 递归摘要
  3. 滑动窗口:保留开头(系统提示)+ 最近 N 轮,丢弃中间
  4. 分层记忆:近期详细 + 远期摘要

6. 评测与优化

6.1 Prompt 测试框架

Promptfoo(开源,本地运行):

yaml
# promptfooconfig.yaml
prompts:
  - prompts/qa_prompt.txt
providers:
  - openai:gpt-4
  - anthropic:claude-3-sonnet
tests:
  - vars:
      question: "法国首都是哪里?"
    assert:
      - type: contains
        value: "巴黎"
  - vars:
      question: "2+2=?"
    assert:
      - type: equals
        value: "4"

LangSmith(LangChain 官方):

  • 全链路追踪:输入 → 提示 → 模型调用 → 输出
  • 数据集管理:收集测试用例,持续回归测试
  • 评估指标:自定义评分函数

6.2 关键评估指标

指标说明测量方式
准确率输出正确性人工标注 / 自动匹配
格式遵循率按指定格式输出的比例正则/JSON Schema 验证
延迟首 token 时间 / 总生成时间时间测量
Token 效率完成任务所需 token 数计数
用户满意度终端用户评分A/B 测试

7. 安全与防御

7.1 提示注入防御

技术原理实施难度
分隔符使用 XML/HTML/JSON 分隔用户输入
Spotlighting明确标注不可信内容
指令层次系统提示优先级高于用户输入
输出过滤后处理检查敏感内容
人机回环高风险操作人工确认

参考资源


相关页面

AI Knowledge Base — 持续积累