服务层级与速率限制:Priority / Standard / Batch 三层 SLA 完全指南
第四章:Prompt 设计基础:角色、指令、上下文的黄金结构
4.1 为什么 Prompt 工程值得系统学习
Prompt 不是"写几句话让 AI 干活"那么简单。一个设计良好的 prompt 可以让 Haiku 的表现接近 Sonnet,让 Sonnet 的输出质量接近 Opus。反之,一个糟糕的 prompt 会让即使是 Opus 也输出不稳定、不可靠的结果。
Anthropic 的内部研究表明,prompt 质量对输出结果的影响可以超过模型选择的影响。在许多任务上,花 2 小时优化 prompt 带来的收益,比花更多钱升级模型更显著。
本章介绍 Claude 最重要的 prompt 设计模式,重点是黄金三角结构:角色(Role)、指令(Instructions)、上下文(Context)。
4.2 System Prompt 的作用与优先级
System Prompt vs User Message
Claude 的对话结构包含两个主要输入位置:
[System Prompt]
↓ 更高优先级,定义全局行为
[User Messages]
↓ 较低优先级,具体任务请求
System prompt 的优先级高于 user message。如果 system prompt 说"只用中文回复",而用户用英文提问,Claude 会用中文回答。这个机制允许开发者建立不可被用户覆盖的行为边界。
System Prompt 的典型内容
一个结构良好的 system prompt 通常包含:
1. 角色定义(你是谁)
2. 核心指令(你应该做什么 / 不应该做什么)
3. 输出格式要求
4. 处理边界情况的规则
5. 示例(可选但有效)
System Prompt 的长度考量
System prompt 会被计入每次请求的输入 token。对于高频请求,一个 2000 token 的 system prompt 意味着每天额外消耗大量 token。
示例:
system prompt = 2000 tokens
日请求量 = 10,000 次
每日额外成本(Sonnet)= 2000 * 10000 / 1,000,000 * $3 = $60/天
建议:system prompt 应该足够完整,但不要包含冗余信息。
通常 500-1500 tokens 是合理范围,复杂系统可到 3000 tokens。
4.3 角色设定(Role):最被低估的技巧
为什么角色设定有效
角色设定(Persona Engineering)是最简单但常被忽视的 prompt 技巧。它的效果来自于模型训练中的关联性:当 Claude 被告知"你是一位资深安全工程师",它会调用训练数据中与安全工程师相关的知识模式、表达风格和思维框架。
这不是魔法,而是概率激活:描述一个专家的特征,会让模型输出在那个专家的"分布"上采样。
有效角色 vs 无效角色
无效角色(过于泛泛):
你是一个有帮助的 AI 助手。
这等于没说,因为这是 Claude 的默认行为。
有效角色(具体且有行为导向):
你是 TechCorp 的高级后端工程师,有 10 年分布式系统经验。
你专注于 Python 和 Go 生态。当分析代码问题时,你总是:
- 先识别根本原因,而不仅仅是症状
- 考虑生产环境中的扩展性影响
- 给出具体的、可执行的建议,而不是泛泛的原则
- 当有多种解决方案时,解释每种方案的权衡取舍
角色模板:不同场景的参考
技术助手模板:
你是 [公司名] 的技术文档工程师,专长是 [技术领域]。
你的目标用户是 [目标受众描述]。
你总是提供 [具体行为特征]。
你从不 [禁止行为]。
内容分析师模板:
你是一位专业的 [领域] 分析师,有 [经验特征]。
你的分析风格是 [风格描述:如 数据驱动、简洁直接]。
你擅长 [特定能力],在 [特定情况] 下会 [特定行为]。
客服代表模板:
你是 [品牌名] 的客服专家 [名字]。
你友善、专业,对 [产品/服务] 有深入了解。
你总是先理解客户的核心问题,然后提供精确的解决方案。
当无法解决时,你会明确说明并给出升级路径。
4.4 指令设计(Instructions):精确胜于冗长
三种指令表达方式的对比
方式一:描述性指令(效果一般)
"用专业的语气回答问题,提供有帮助的信息。"
太模糊,Claude 会按自己的理解执行,结果不一致。
方式二:禁止列表(效果中等)
"不要使用技术术语,不要太长,不要跑题。"
告诉模型"不做什么"比"做什么"更难执行。
方式三:正向、具体的行为指令(效果最佳)
"每个回复必须包含:
1. 一句话直接回答问题
2. 最多 3 个要点的解释
3. 一个实际应用的例子
总长度不超过 300 字。"
指令优先级排序技巧
当有多条指令时,Claude 需要知道哪条优先级更高。显式的优先级声明比隐式期望更有效:
你的响应规则(按优先级排序):
最高优先级:
- 永远不提供可能造成安全风险的信息
- 永远不在未经请求时收集用户个人信息
高优先级:
- 响应必须与用户问题直接相关
- 使用用户的语言(中文提问用中文回答)
普通优先级:
- 使用 Markdown 格式化长响应
- 在适当时提供代码示例
处理边界情况
好的 prompt 预见到边界情况并给出明确指导:
SYSTEM_PROMPT = """你是一个代码审查助手。
对于每个代码片段,你应该:
1. 识别 bugs 和逻辑错误
2. 指出性能问题
3. 提供改进建议
边界情况处理:
- 如果代码少于 5 行且明显正确:直接确认,不需要过度分析
- 如果代码包含安全漏洞(SQL 注入、XSS 等):在响应开头用 [安全警告] 标注
- 如果代码语言无法识别:询问用户是什么语言
- 如果提交的不是代码:礼貌地告知你只处理代码审查请求
响应格式:
问题概述: [一句话总结]
发现的问题:
- [问题描述 + 所在行号]
改进后的代码: [代码块]
解释: [改进说明]
"""
4.5 上下文提供(Context):给 Claude 它需要的信息
信息完整性原则
Claude 只知道你告诉它的。如果你的请求依赖于某个背景信息,但你没有提供,Claude 要么会猜测(风险),要么会询问(效率低)。
低效的上下文提供:
"修复这个函数的 bug"
Claude 不知道这个函数的预期行为是什么,也不知道现有的 test case 是什么。
高效的上下文提供:
"修复以下函数的 bug。
预期行为:将一个嵌套字典扁平化,key 用点号分隔。
例如:{"a": {"b": 1}} → {"a.b": 1}
当前代码:
[代码]
失败的测试用例:
flatten({"a": {"b": {"c": 1}}}) 返回 {"a.b.c": 1},但实际返回 {"a": {"b.c": 1}}
"
上下文位置策略
在超长 prompt 中,信息放置位置影响 Claude 的注意力分配:
最佳实践:
┌────────────────────────────────────┐
│ System Prompt(全局规则) │ ← 始终被关注
├────────────────────────────────────┤
│ 关键约束 / 最重要信息 │ ← 放在消息开头
├────────────────────────────────────┤
│ 背景信息 / 参考资料 │ ← 中间位置(可能被弱化)
├────────────────────────────────────┤
│ 具体任务要求 │ ← 放在消息结尾(最近记忆)
└────────────────────────────────────┘
结构化上下文的标签技巧
使用 XML 标签来组织长上下文,让 Claude 更容易区分不同类型的信息:
def build_analysis_prompt(
document: str,
requirements: list[str],
examples: list[dict]
) -> str:
examples_text = "\n".join(
f"<example>\n<input>{e['input']}</input>\n<output>{e['output']}</output>\n</example>"
for e in examples
)
requirements_text = "\n".join(f"- {r}" for r in requirements)
return f"""请分析以下文档并提取关键信息。
<requirements>
{requirements_text}
</requirements>
<examples>
{examples_text}
</examples>
<document>
{document}
</document>
根据以上要求和示例,请提取文档中的关键信息。"""
4.6 Few-Shot 示例:让模型"看见"你期望的结果
为什么 Few-Shot 有效
Few-shot 示例比抽象指令更有效,因为它通过演示而不是描述来传达期望。对于格式要求复杂的任务,几个好的示例往往抵得上数百字的格式说明。
Few-Shot 示例的构建原则
- 代表性:示例应覆盖任务的典型场景,不只是最简单的情况
- 多样性:包含边缘情况和不同类型的输入
- 正确性:示例中的输出必须是你期望的准确格式
- 数量:3-5 个通常足够;过多示例会占用大量 context 窗口
SYSTEM_PROMPT = """你是一个情感分类器。分析文本的情感并返回结构化结果。
示例:
输入: "这家餐厅的服务太慢了,等了40分钟才上菜,非常失望。"
输出: {"sentiment": "negative", "intensity": 0.8, "aspects": ["service", "wait_time"], "confidence": 0.95}
输入: "还行吧,没什么特别的,但也没有太大问题。"
输出: {"sentiment": "neutral", "intensity": 0.3, "aspects": ["overall"], "confidence": 0.85}
输入: "食物非常美味!特别是他们的招牌菜,强烈推荐!"
输出: {"sentiment": "positive", "intensity": 0.9, "aspects": ["food", "recommendation"], "confidence": 0.97}
规则:
- sentiment: "positive" | "negative" | "neutral" | "mixed"
- intensity: 0.0-1.0(情感强度)
- aspects: 文本涉及的方面列表
- confidence: 0.0-1.0(分类置信度)
只返回 JSON,不要其他内容。"""
动态 Few-Shot:相似性检索
对于复杂任务,可以动态选择与当前输入最相似的示例:
from anthropic import Anthropic
# 简化版本:实际应用中会用向量相似性检索
def select_relevant_examples(
query: str,
example_pool: list[dict],
n: int = 3
) -> list[dict]:
"""
从示例池中选择最相关的 n 个示例
简化实现:按关键词匹配;生产中应使用向量检索
"""
query_words = set(query.lower().split())
scored = []
for example in example_pool:
example_words = set(example["input"].lower().split())
overlap = len(query_words & example_words)
scored.append((overlap, example))
scored.sort(key=lambda x: x[0], reverse=True)
return [ex for _, ex in scored[:n]]
def dynamic_few_shot_prompt(
task_description: str,
example_pool: list[dict],
current_input: str
) -> str:
relevant_examples = select_relevant_examples(current_input, example_pool)
examples_text = "\n\n".join(
f"输入: {ex['input']}\n输出: {ex['output']}"
for ex in relevant_examples
)
return f"""{task_description}
{examples_text}
输入: {current_input}
输出:"""
4.7 思维链提示(Chain-of-Thought)
何时需要 CoT
思维链提示(CoT)通过让模型"展示推理过程"来提高复杂任务的准确性。在以下场景中显著有效:
- 数学和逻辑推理
- 多步骤问题分解
- 需要权衡多个因素的决策
- 代码调试(逐步追踪执行流程)
CoT 的几种实现方式
方式一:直接指令(最简单)
"请逐步思考,解释你的推理过程,然后给出答案。"
方式二:结构化推理框架
"使用以下步骤分析问题:
1. 问题分解:将问题拆分为子问题
2. 信息识别:找出已知条件和未知量
3. 方法选择:确定解决路径
4. 执行与验证:逐步执行并检验
5. 结论:给出最终答案"
方式三:XML 标签结构(最清晰)
def create_reasoning_prompt(problem: str) -> list[dict]:
"""创建带思维链的对话"""
return [
{
"role": "user",
"content": f"""请分析以下问题。在 <thinking> 标签中展示你的推理过程,
在 <answer> 标签中给出最终答案。
<problem>
{problem}
</problem>"""
}
]
# 使用示例
client = Anthropic()
messages = create_reasoning_prompt(
"一个班有 32 名学生,其中 3/8 是女生。"
"如果又转来了 4 名女生,现在女生占全班的百分比是多少?"
)
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=messages
)
# Claude 会在 <thinking> 中展示计算过程,在 <answer> 中给出答案
print(response.content[0].text)
CoT 与 Extended Thinking 的区别
CoT(Prompt 层面):
- 通过 prompt 指令让模型在响应中展示推理
- 推理内容在输出中可见
- 适用于所有模型
Extended Thinking(API 层面):
- 模型在生成最终响应前进行内部推理
- 推理 tokens 单独计费(输出价格)
- 仅 Opus 和 Sonnet 支持
- 通常效果更好,但成本更高
4.8 黄金结构完整模板
将前述所有要素组合成一个完整的 system prompt 模板:
def build_production_system_prompt(
role_name: str,
expertise: str,
audience: str,
core_behaviors: list[str],
output_format: str,
constraints: list[str],
examples: list[dict] = None
) -> str:
"""
生产级 system prompt 构建器
"""
behaviors_text = "\n".join(f"{i+1}. {b}" for i, b in enumerate(core_behaviors))
constraints_text = "\n".join(f"- {c}" for c in constraints)
examples_section = ""
if examples:
examples_lines = []
for ex in examples:
examples_lines.append(f"输入: {ex['input']}\n期望输出: {ex['output']}")
examples_section = f"\n## 示例\n\n" + "\n\n".join(examples_lines)
return f"""## 角色
你是 {role_name},{expertise}。你的用户是 {audience}。
## 核心行为
{behaviors_text}
## 输出格式
{output_format}
## 约束
{constraints_text}{examples_section}
"""
# 实际使用示例
system = build_production_system_prompt(
role_name="CodeReviewBot",
expertise="专注于 Python 和 TypeScript 的代码质量分析师",
audience="中级到高级的软件工程师",
core_behaviors=[
"识别 bugs、性能问题和安全漏洞",
"提供具体的、可执行的改进建议",
"解释每个问题的潜在影响",
"区分必须修复的问题和建议性改进"
],
output_format="""使用以下结构:
**严重问题** [需要立即修复]
**建议改进** [最佳实践,非强制]
**改进后代码** [如适用]""",
constraints=[
"只评审代码,不评论开发者的技术水平",
"如果代码没有问题,直接说'代码看起来没有问题,以下是一些可选的优化'",
"每次响应不超过 600 字"
]
)
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=system,
messages=[{
"role": "user",
"content": """请审查以下 Python 函数:
```python
def get_user(user_id):
conn = sqlite3.connect('users.db')
cursor = conn.cursor()
query = f"SELECT * FROM users WHERE id = {user_id}"
cursor.execute(query)
return cursor.fetchone()
```"""
}]
)
print(response.content[0].text)
4.9 常见 Prompt 反模式
反模式一:模糊的期望
❌ 不好: "生成一些营销文案"
✅ 好: "为 XX 产品(面向 25-35 岁都市白领)生成 3 个微信朋友圈文案,
每条 50-80 字,强调省时省力的核心价值,语气活泼不做作"
反模式二:矛盾的指令
❌ 不好: "回答要详细,但要简短,要专业,但要通俗易懂"
✅ 好: "回答面向非技术人员,使用日常比喻解释技术概念,
不超过 150 字,确保关键术语有解释"
反模式三:依赖 Claude 的默认行为
❌ 不好: "帮我写一封道歉邮件"(没有指定对象、场景、语气)
✅ 好: "帮我写一封道歉邮件,对象是我的客户(正式商务关系),
原因是项目延期 2 周,语气诚恳但不过度卑微,
需要包含补救措施,200-300 字"
反模式四:过长的"条款和条件"式 prompt
每条指令都需要 Claude 的注意力资源。超过 30 条规则的 system prompt 通常会导致规则互相干扰,总体遵循率反而下降。
最佳实践:识别最关键的 5-10 条规则,把其余的整合或删除。
小结
本章系统梳理了 Claude prompt 设计的黄金结构:
- 角色(Role):具体的专家描述激活相关的知识模式,比"有帮助的助手"有效得多
- 指令(Instructions):正向、具体的行为指令优于模糊描述和禁止列表;显式的优先级排序减少冲突
- 上下文(Context):提供足够的背景信息;重要信息放在开头和结尾;用 XML 标签组织长上下文
- Few-Shot 示例:演示比描述更有效,3-5 个覆盖典型情况的示例往往就足够
- 思维链(CoT):对复杂推理任务显著有效;结合 XML 标签获得更清晰的结构
下一章将转向 token 的经济学:计费机制、上下文窗口的限制,以及如何在超长文本任务中保持质量和控制成本。