AI开发基础(第8篇):Prompt与Context Engineering AI 开发基础第8篇Prompt Engineering 与 Context Engineering - 与模型沟通的艺术适合读者已读完第7篇Multi-Agent想深入理解如何有效控制模型输出预计阅读时间35分钟前言为什么前面7篇都绕不开提示词回顾一下前7篇里我们已经用到了大量提示词第3篇Agent Loopsystem prompt定义Agent行为第4篇Reasoning请一步步思考触发CoT第6篇Memory把用户画像注入prompt第7篇Multi-Agent每个Agent有不同的system prompt提示词是你和LLM之间唯一的沟通方式。写不好提示词模型再强也发挥不出来。但提示词工程这个词现在有个更大的进化Context Engineering上下文工程。一、Prompt Engineering让模型听懂你1.1 提示词的三个层次层次说明例子指令直接告诉模型做什么“翻译成英文”上下文提供背景信息帮助理解“这是一份法律合同请翻译”示例给出期望的输入输出格式“输入你好 → 输出Hello”好的提示词 清晰的指令 充足的上下文 典型的示例1.2 结构化提示词模板defbuild_prompt(task:str,context:str,examples:listNone,constraints:listNone):构建结构化提示词parts[]# 指令parts.append(f## 任务\n{task})# 上下文ifcontext:parts.append(f## 背景\n{context})# 示例ifexamples:parts.append(## 示例)fori,exinenumerate(examples,1):parts.append(f### 示例{i}\n输入{ex[input]}\n输出{ex[output]})# 约束ifconstraints:parts.append(## 约束)forcinconstraints:parts.append(f-{c})return\n\n.join(parts)# 使用promptbuild_prompt(task将中文技术文章摘要翻译成英文保持专业术语准确。,context目标读者是国际开发者文章关于AI Agent开发。,examples[{input:本文介绍了Agent Loop的核心概念,output:This article introduces the core concepts of Agent Loop},],constraints[专业术语保留英文如 Agent、RAG、MCP,不要意译忠实原文,输出格式为纯文本不加额外说明,],)1.3 高频提示词技巧技巧1角色设定你是一个有10年经验的Python高级工程师。你写的代码 - 遵循PEP 8规范 - 有类型注解 - 有docstring - 处理边界情况为什么有效LLM训练数据中有大量高级工程师写的代码和初级工程师写的代码。角色设定帮你锁定高级那一部分。技巧2输出格式控制请按以下JSON格式输出 { analysis: 分析结论, confidence: 0.0-1.0的置信度, suggestions: [建议1, 建议2] }踩坑有时候LLM不严格按格式输出。加一句只输出JSON不要其他内容可以改善。更可靠的方案是用Structured Output第1篇提过的Function Calling方式。技巧3Few-Shot示例## 分类任务 示例1 输入今天天气真好心情不错 输出{sentiment: positive, category: 日常} 示例2 这个Bug我已经改了3遍了还是不对 输出{sentiment: negative, category: 工作} 现在请分类 输入新的AI模型发布了比上一代快3倍 输出经验3个示例通常就够了。太少1个模型可能过拟合那个模式太多10个浪费Token。技巧4负向提示不要 - 不要用Markdown标题 - 不要添加这里是翻译结果之类的说明 - 不要省略原文中的数字和日期 必须 - 必须保持原文的段落结构 - 必须保留所有超链接经验负向提示比正向提示更有效。模型知道不该做什么后犯错率明显降低。二、Context Engineering管理模型的全部输入2.1 Prompt Engineering → Context Engineering传统Prompt Engineering关注的是你写的那段文字。但模型的输入远不止你写的提示词模型的完整输入Context System Prompt ← 你定义的Agent角色和行为 对话历史 ← 之前的多轮对话 工具定义 ← Function Calling的工具schema RAG检索结果 ← 向量数据库检索的知识 用户画像 ← 之前存储的用户偏好 代码上下文 ← 如果在做代码相关任务 任务状态 ← Multi-Agent的共享状态 ContextContext Engineering 管理这所有输入的工程。不只是写好提示词而是确保整个上下文都是高质量、相关的。2.2 上下文窗口的预算管理假设模型有128K Token的上下文窗口你怎么分配组成部分建议分配说明System Prompt~2K角色定义行为规则够用就行工具定义~5-15K取决于工具数量和schema大小用户画像~1K偏好摘要RAG检索结果~5-10K最相关的3-5段对话历史剩余空间越多越好但需要裁剪用户输入~1K当前问题输出预留~4K给模型留足回答空间代码实现classContextManager:上下文管理器def__init__(self,max_context_tokens:int120000):self.max_tokensmax_context_tokens self.reserved{system:2000,tools:0,# 动态计算profile:1000,rag:8000,input:1000,output:4000,}defcalculate_budgets(self,tool_schemas:list,rag_results:list,history:list,profile:dict)-dict:计算各部分的Token预算importtiktoken enctiktoken.encoding_for_model(gpt-4o-mini)# 动态计算工具定义的大小tool_tokenssum(len(enc.encode(json.dumps(t)))fortintool_schemas)self.reserved[tools]tool_tokens# 已固定占用fixedsum(self.reserved.values())-self.reserved[tools]available_for_historyself.max_tokens-fixed-tool_tokens-self.reserved[rag]return{system:self.reserved[system],tools:tool_tokens,profile:self.reserved[profile],rag:self.reserved[rag],history:max(0,available_for_history),input:self.reserved[input],output:self.reserved[output],}defbuild_context(self,system_prompt:str,tool_schemas:list,rag_results:list,history:list,profile:dict,user_input:str)-list:构建完整的上下文budgetsself.calculate_budgets(tool_schemas,rag_results,history,profile)messages[]# System Promptmessages.append({role:system,content:system_prompt})# 用户画像注入到system promptifprofile:messages[-1][content]f\n\n用户信息{json.dumps(profile,ensure_asciiFalse)}# 对话历史按预算裁剪trimmed_historyself._trim_to_budget(history,budgets[history])messages.extend(trimmed_history)# RAG结果ifrag_results:rag_text参考信息\n\n.join(rag_results)messages.append({role:user,content:rag_text})messages.append({role:assistant,content:好的我已阅读参考信息。})# 用户输入messages.append({role:user,content:user_input})returnmessagesdef_trim_to_budget(self,messages:list,max_tokens:int)-list:裁剪消息到预算范围内importtiktoken enctiktoken.encoding_for_model(gpt-4o-mini)kept[]total0formsginreversed(messages):tokenslen(enc.encode(msg[content]))iftotaltokensmax_tokens:breakkept.insert(0,msg)totaltokensreturnkept2.3 动态上下文高级用法根据用户输入动态决定需要什么上下文。asyncdefdynamic_context(user_input:str,user_id:str)-list:动态构建上下文# 第1步用一个小模型快速分析判断需要哪些上下文analysisawaitsmall_model_call(f分析用户输入判断需要哪些上下文多选 - history: 对话历史 - profile: 用户画像 - rag: 知识库检索 - tools: 工具调用 用户输入{user_input}只输出需要的上下文名称逗号分隔。)needed[x.strip()forxinanalysis.content.split(,)]messages[{role:system,content:你是一个智能助手。}]ifprofileinneeded:profileget_user_profile(user_id)ifprofile:messages[-1][content]f\n用户画像{json.dumps(profile)}ifhistoryinneeded:messages.extend(get_recent_history(user_id,n10))ifraginneeded:resultsawaitknowledge_search(user_input,top_k3)ifresults:messages.append({role:user,content:f参考资料\n\n.join(results)})messages.append({role:assistant,content:已阅读参考资料。})messages.append({role:user,content:user_input})returnmessages好处不是每次都塞满所有上下文。简单问题少塞复杂问题多塞Token利用率更高。三、提示词工程 vs 上下文工程的区别Prompt EngineeringContext Engineering关注点你写的提示词文本模型的全部输入范围system prompt 用户消息prompt history tools RAG profile …目标让模型理解你的意图让模型在最优上下文中工作技术角色设定、Few-Shot、CoTToken预算管理、动态裁剪、RAG检索、记忆注入类比写好一篇演讲稿准备好演讲的全部环境灯光、音响、观众背景Context Engineering是Prompt Engineering的升级版。它告诉你不只是写好提示词而是管理好模型能看到的所有信息。四、真实项目经验4.1 CSDN文章生成的上下文管理asyncdefarticle_context(topic:str)-list:文章生成的上下文构建messages[{role:system,content:你是一个技术文章写作专家。 写作规范 - 代码必须完整可运行 - 数据必须有来源 - 有真实踩坑经验 - 面向中级开发者 - 3000-5000字}]# 检索相关文章作为风格参考relatedawaitsearch_my_articles(topic,top_k2)ifrelated:ref_text你的历史文章风格参考\nforarticleinrelated:ref_textf-{article[title]}\nmessages.append({role:user,content:ref_text})messages.append({role:assistant,content:好的我会参考这些文章的风格。})# 搜索竞品文章了解别人怎么写的competitorsawaitsearch_web(topic,top_k3)ifcompetitors:comp_text竞品文章概要\nforcincompetitors:comp_textf-{c[title]}:{c[summary]}\nmessages.append({role:user,content:comp_text})messages.append({role:assistant,content:好的我会参考但保持原创。})messages.append({role:user,content:f请写一篇关于{topic}})returnmessages4.2 提示词版本管理生产环境必须做的prompts/ ├── v1/ │ ├── agent_system.txt │ ├── coder_system.txt │ └── reviewer_system.txt ├── v2/ │ ├── agent_system.txt │ ├── coder_system.txt │ └── reviewer_system.txt └── CHANGELOG.md # 记录每次改了什么、为什么改importhashlibdefprompt_hash(prompt:str)-str:计算提示词hash用于追踪版本returnhashlib.md5(prompt.encode()).hexdigest()[:8]# 每次LLM调用记录使用的提示词版本log_entry{prompt_hash:prompt_hash(system_prompt),prompt_version:v2,input:user_input,output:response.content,tokens:response.usage.total_tokens,timestamp:2026-05-22T08:00:00Z,}踩坑改了提示词后效果变差但忘了改了什么。版本管理hash追踪可以避免这个问题。五、本章总结你学到了什么Prompt Engineering四技巧角色设定、输出格式控制、Few-Shot示例、负向提示Context Engineering不只是写好提示词而是管理模型的所有输入Token预算管理按优先级分配上下文窗口空间动态上下文根据输入判断需要哪些上下文不浪费Token提示词版本管理生产环境必须追踪提示词变更关键公式Context System Prompt History Tools RAG Profile Input Context Engineering Token预算分配 动态裁剪 相关性检索下一篇预告第9篇Harness Engineering 与知识地图 - 管控整个Agent系统参考资料OpenAI Prompt Guidehttps://platform.openai.com/docs/guides/prompt-engineeringAnthropic Prompt Guidehttps://docs.anthropic.com/en/docs/build-with-claude/prompt-engineeringPrompt Patterns论文https://arxiv.org/abs/2102.07484Context Engineering综述https://www.anthropic.com/research/building-effective-agents上一篇第7篇 Subagent 与 Multi-Agent下一篇第9篇 Harness Engineering 与知识地图