跳到主要内容

上下文工程

什么是上下文工程

上下文工程(Context Engineering)是通过精心设计输入、提示词和背景信息,来指导模型产生更好结果的技术。这是构建高质量代理的关键。

系统提示的设计

1. 角色定位

# ❌ 差的系统提示
system_prompt = "你是一个助手"

# ✅ 好的系统提示
system_prompt = """
你是一个有15年经验的专业金融顾问。
你的专长包括投资规划、退休计划和税务优化。
你总是基于数据和经验提供建议,而不是猜测。
"""

2. 行为指导

# 为代理确定清晰的行动指南
system_prompt = """
你是一个客服助手。执行以下规则:

1. 处理客户问题的优先级:
- 紧急问题 → 立即标记为高优
- 账户问题 → 立即转接人工
- 一般问题 → 尝试自助解答

2. 响应原则:
- 总是礼貌且专业
- 如果不确定,说"我不清楚"而不是猜测
- 提供具体的后续步骤

3. 禁止事项:
- 不要承诺无法实现的内容
- 不要泄露客户隐私信息
- 不要提供财务建议(除非授权)
"""

3. 输出格式指定

system_prompt = """
你是一个数据分析助手。

回答格式要求:
1. 总结:用1-2句话概括核心发现
2. 详细分析:
- 背景:问题的上下文
- 关键数据:相关的统计数据
- 解释:为什么这很重要
3. 建议:基于分析的3-5条行动建议
4. 额外资源:指向相关文档或工具的链接

始终使用markdown格式。
"""

提示词优化技术

1. 思维链(Chain-of-Thought)

# ✗ 直接问
"用户有多少钱要投资?"

# ✓ 使用思维链
"""
用户要做投资决策。考虑以下因素:
1. 用户的财务状况:收入、储蓄、债务
2. 投资目标:短期还是长期、是否需要流动性
3. 风险承受能力:保守、平衡还是激进
4. 投资时间:多长时间内需要回报

基于这些因素,逐步思考最合适的投资策略。
"""

2. 单样本/少样本学习

system_prompt = """
你是一个代码审查助手。

示例审查:
问题:
```python
users = db.query("SELECT * FROM users")

评论:

  • 安全问题:易受SQL注入攻击
  • 改进:使用参数化查询
  • 代码:users = db.query("SELECT * FROM users WHERE active=?", [True])

现在请用同样的方式审查提供的代码。 """


### 3. 角色扮演

```python
# 通过让模型扮演特定角色来改进输出
system_prompt = """
你是一个严格的老师,正在教授高中物理。
学生刚才问了一个关于重力的问题。

你的回答应该:
1. 确认学生已经理解的正确部分
2. 温和地指出任何误解
3. 提供清晰的解释
4. 给出可以验证理解的问题

用教育但不居高临下的语气。
"""

上下文窗口管理

1. 重要信息优先

def prioritize_context(task: str, all_context: list):
"""将最相关的信息放在最前面"""

# 优先级:系统 > 任务相关 > 背景信息
priority_context = []

# 1. 系统提示
system = [c for c in all_context if c.get("type") == "system"]
priority_context.extend(system)

# 2. 高优先级
high_priority = [c for c in all_context if c.get("priority") == "high"]
priority_context.extend(high_priority)

# 3. 中等和低优先级
others = [c for c in all_context if c not in priority_context]
priority_context.extend(others)

return priority_context

2. 动态上下文选择

def select_relevant_context(query: str, context_pool: list, limit: int = 5):
"""根据查询选择最相关的上下文"""
from sklearn.metrics.pairwise import cosine_similarity
from sentence_transformers import SentenceTransformer

# 获取嵌入模型
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')

# 计算相似度
query_embedding = model.encode([query])
context_embeddings = model.encode([c.get("text", "") for c in context_pool])

similarities = cosine_similarity(query_embedding, context_embeddings)[0]

# 选择最相似的
top_indices = similarities.argsort()[-limit:][::-1]

return [context_pool[i] for i in top_indices]

特定领域的上下文工程

1. 代码生成任务

system_prompt = f"""
你是一个 Python 代码生成助手。

代码风格指南:
- 遵循 PEP 8 规范
- 为所有函数添加类型提示
- 包含文档字符串
- 处理所有可能的异常

框架版本:
- Python: 3.11+
- Django: 4.2
- FastAPI: 0.104

生成的代码应该:
1. 可以直接运行
2. 包含必要的导入
3. 包含使用示例或单元测试
"""

2. 数据分析任务

system_prompt = """
你是一个数据分析专家。

分析流程:
1. 数据探索:描述数据的大小、类型和分布
2. 数据清洗:识别并处理缺失值、异常值
3. 统计分析:计算关键统计量
4. 可视化:建议合适的图表类型
5. 结论:总结关键发现

总是考虑数据的业务含义,而不仅仅是技术细节。
"""

3. 创意写作任务

system_prompt = """
你是一个专业的故事编剧。

写作指导:
- 创建有三维性格的角色
- 建立清晰的故事弧线:起点 → 冲突 → 解决
- 使用对话推进情节
- 包含感官描写(视觉、声音、味道等)
- 保持一致的语气和风格

目标受众:成人读者,20-45岁

故事应该在3000-5000字之间。
"""

避免常见错误

1. 过度指导(Over-specification)

# ❌ 过度指导
system_prompt = """
问题1:用户叫什么?
问题2:用户的年龄是?
问题3:用户住在哪里?
...
按照这个顺序一个一个问。
"""

# ✅ 更好的方式
system_prompt = """
通过自然对话收集用户的基本信息(名字、年龄、位置)。
根据进展动态调整问题。
"""

2. 矛盾的指导

# ❌ 矛盾的指导
system_prompt = """
总是准确,但也要保持创意和趣味。
快速回答,但确保深思熟虑。
"""

# ✅ 清晰一致
system_prompt = """
在保持准确性的前提下,添加幽默和创意。
目标是快速回答(<30秒),同时提供有见地的观点。
"""

3. 模糊的指导

# ❌ 模糊
system_prompt = "你是一个有帮助的助手"

# ✅ 具体
system_prompt = """
你是一个客户支持助手,专门处理账户相关问题。
平均响应时间目标是2分钟。
你有权发放最多$100的补偿。
"""

动态上下文调整

class AdaptiveContextManager:
"""根据对话动态调整上下文"""

def __init__(self):
self.conversation_history = []
self.detected_topics = []
self.user_preferences = {}

def analyze_conversation(self):
"""分析对话以检测主题"""
# 从对话历史中提取主题
topics = extract_topics(self.conversation_history)
self.detected_topics = topics

def get_adaptive_prompt(self):
"""根据检测到的主题生成自适应提示"""
base_prompt = "你是一个有帮助的助手。"

if "技术" in self.detected_topics:
base_prompt += "\n专注于提供技术解决方案。"

if "情感支持" in self.detected_topics:
base_prompt += "\n使用同情和理解的语气。"

if "紧急" in self.detected_topics:
base_prompt += "\n优先处理此事项,立即采取行动。"

return base_prompt

def update_from_feedback(self, feedback: str):
"""根据用户反馈调整"""
# 解析反馈并更新策略
pass

# 使用
context_manager = AdaptiveContextManager()
adaptive_prompt = context_manager.get_adaptive_prompt()

测试和迭代

def evaluate_prompt(prompt: str, test_cases: list):
"""评估提示的有效性"""
results = []

for test_case in test_cases:
response = agent.invoke({
"messages": [{
"role": "user",
"content": test_case["input"]
}]
})

# 评估响应
score = evaluate_response(
response,
test_case["expected_output"]
)

results.append({
"input": test_case["input"],
"output": response,
"score": score
})

# 计算平均分
avg_score = sum(r["score"] for r in results) / len(results)

return {
"average_score": avg_score,
"details": results
}

# 使用A/B测试比较二个提示
prompt_a = "你是一个有帮助的助手"
prompt_b = "你是一个专业的技术支持专家,有20年经验"

results_a = evaluate_prompt(prompt_a, test_cases)
results_b = evaluate_prompt(prompt_b, test_cases)

print(f"Prompt A 得分: {results_a['average_score']}")
print(f"Prompt B 得分: {results_b['average_score']}")

最佳实践清单

  • ✅ 明确定义代理的角色和专业领域
  • ✅ 提供具体的行为指导和禁止事项
  • ✅ 在示例中说明所需的输出格式
  • ✅ 使用思维链支持复杂推理
  • ✅ 定期使用真实测试用例评估效果
  • ✅ 根据用户反馈不断改进
  • ✅ 避免矛盾和模糊的指导
  • ✅ 考虑目标用户的背景和需求

常见问题

Q: 如何知道系统提示是否有效? A: 通过测试用例评估。使用可观测性与调试中的工具进行量化评估。

Q: 应该有多详细的系统提示? A: 平衡详细性和灵活性。通常200-500词是合适的范围。

Q: 提示词对成本有影响吗? A: 是的,更长的提示词和更多的样本都会增加token使用,因此增加成本。