ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AI智能体上下文工程:从原理到实战,构建可靠记忆与知识系统

AI智能体上下文工程:从原理到实战,构建可靠记忆与知识系统 1. 从“提示词”到“上下文”智能体进化的分水岭如果你最近在折腾AI智能体不管是想用Dify、Coze搭个客服机器人还是想基于LangChain搞个自动化工作流大概率都经历过这样的场景你精心设计了一段“完美”的提示词Prompt告诉AI“请帮我分析这份销售数据找出潜在问题并给出建议。”AI的回复乍一看挺像样但当你把一份50页的PDF报告丢给它让它结合前面20页的背景和后面30页的详细数据一起分析时它可能就开始胡言乱语或者干脆只盯着最后几页内容完全忘了开头的核心目标。这不是AI笨也不是你的提示词写得不好。问题的核心在于我们过去太过于聚焦在“点”上的技巧——也就是提示词工程Prompt Engineering却忽略了智能体真正运作时所依赖的那个“场”——上下文Context。你可以把提示词想象成给AI下的一个精确指令比如“向左转90度”。这个指令本身很清晰但AI要执行它必须知道自己面朝哪里、身处何地、周围有什么障碍物。这些“知道”的信息就是上下文。上下文工程Context Engineering就是系统化地构建、管理和优化这个“信息场”的实践。它要解决的不是“怎么问”而是“让AI在回答时能看到什么、记住什么、以什么为参考”。当智能体需要处理多轮对话、长文档分析、复杂工具调用和长期记忆时上下文的质量直接决定了智能体是像一个健忘的实习生还是一个靠谱的专家助手。我见过太多项目前期在提示词上抠字眼后期却因为上下文混乱比如历史对话被截断、关键文档信息丢失、工具返回结果没被正确纳入考量而功亏一篑。今天我们就抛开那些浮于表面的热词深入聊聊为什么上下文工程是智能体从“玩具”走向“工具”不可或缺的基石以及在实际开发中我们到底该怎么搞定它。2. 拆解智能体的“记忆宫殿”上下文究竟包含什么很多人一提到上下文就只想到聊天历史。这太片面了也是很多智能体设计脆弱的根源。一个真正能用的智能体其上下文是一个多层、动态、结构化的信息集合体。我们可以把它拆解成几个核心部分理解每一部分的作用是进行有效工程化的前提。2.1 会话历史不只是聊天记录会话历史是最直观的上下文。它不仅仅是用户和AI你一言我一语的记录。一个设计良好的系统会对会话历史进行加工关键信息提取与摘要不是把每一句话都原封不动地塞进上下文窗口。对于长对话需要在每轮或每隔几轮后自动生成一个对话摘要例如“用户想策划一场户外团建已确认预算在5万元内时间偏好周末排除了爬山项目。”这个摘要会作为后续对话的“记忆锚点”即使原始对话被滚动出窗口核心信息仍在。意图与主题追踪通过分析对话流识别当前对话的主题如“售后咨询”和用户的潜在意图如“想要退货”而非“询问功能”。这能帮助智能体在上下文切换时比如用户突然问“那运费谁出”不至于迷失。角色与状态保持如果智能体在对话中扮演特定角色如“严厉的编程导师”这个角色设定以及相关的状态如“用户已连续三次忽略代码规范提醒”需要作为元数据保持在上下文中以确保行为一致性。注意直接存储原始对话是最简单但最低效的方式。随着对话进行token消耗会线性增长并且无关的细节会稀释关键信息。实操心得在实现时我会维护两个并行链条一个是完整的原始日志用于调试和审计另一个是经过提炼的、用于喂给模型的“工作上下文”后者只包含摘要、关键决策点和当前待办事项。2.2 外部知识给智能体装上“参考资料库”智能体不是全知全能的它的核心能力在于理解和推理而非记忆海量事实。因此将外部知识源接入上下文是扩展其能力边界的关键。这不仅仅是RAG检索增强生成。向量检索经典RAG用户提问时从知识库如产品手册、公司规章、项目文档中检索相关片段。这里的工程重点在于检索质量。简单的余弦相似度搜索很容易被一些语义相近但无关的文档干扰。我通常会采用混合检索策略先用向量检索召回一批候选文档再用基于关键词的BM25算法进行重排序过滤掉那些虽然语义相关但主题偏离的结果。结构化数据查询对于数据库、API接口返回的JSON、XML数据需要将其自然语言化后放入上下文。例如数据库查询返回{“status”: “delivered”, “date”: “2023-10-27”}放入上下文时应转化为“订单状态为‘已送达’送达日期为2023年10月27日。”这大幅降低了模型理解结构化数据的认知负荷。实时信息注入智能体需要知道“现在几点”、“用户的姓名是什么”、“当前正在处理什么工单”。这些实时信息需要在推理前以清晰、固定的格式插入到上下文的系统提示或用户消息中。例如在每次调用模型前预置一条消息“[系统信息] 当前用户张三VIP客户当前时间2024-05-27 14:30待处理工单IDTICKET-789。”2.3 工具调用与执行结果闭环反馈的核心智能体的强大之处在于能调用外部工具函数。但很多初级实现只把工具调用的“动作”发出去却忽略了将“结果”有效地整合回上下文。这会导致智能体“失忆”。结构化结果描述工具如调用天气API、执行数据库更新返回的结果应该被格式化成模型易于理解的描述。不仅仅是{“code”: 0, “data”: {...}}而应该是“已成功查询天气。北京今天晴气温22-30度西北风2级。空气质量良。”失败处理与上下文更新如果工具调用失败如网络超时、权限不足这个“失败”本身及其原因“因网络超时未能获取库存信息”必须作为重要上下文告知模型以便它决定重试、降级处理还是向用户求助。我曾调试过一个电商客服智能体它调用库存接口失败后上下文里没有记录导致它下一轮依然试图推荐那个缺货的商品逻辑完全断裂。多步骤执行的中间状态对于一个复杂任务如“订机票-选座位-订酒店”每个步骤的工具调用结果都应该作为后续步骤的上下文。这构成了智能体的“工作记忆”。2.4 系统指令与元提示不变的“宪法”这是上下文的基石层通常在整个会话周期内保持不变或只在模式切换时更改。它定义了智能体的“宪法”核心角色与职责“你是一个专业的Linux系统运维助手专注于解答服务器部署、故障排查和性能优化问题。你的回答应简洁、准确优先给出可执行的命令。”输出格式约束“请始终以Markdown格式输出代码部分使用代码块。”安全与边界规则“你不得生成或讨论涉及暴力、仇恨言论的内容。如果用户询问超出你知识范围的问题应如实告知。”推理流程指引思维链CoT“在回答复杂问题时请先逐步推理最后给出结论。你的推理过程应放在‘思考’部分。”这部分内容虽然固定但其设计质量直接影响智能体的行为基线。一个常见的错误是把所有规则都堆砌在一条冗长的系统提示里导致模型实际处理用户问题时这些“宪法”已经被挤到上下文窗口的边缘影响力减弱。我的经验是将最核心的1-2条规则放在系统提示开头其他细则可以通过在每次用户查询前动态插入一条简短的“行为提醒”来强化。3. 上下文工程的四大核心挑战与实战应对理解了上下文的构成接下来就要面对现实工程中的残酷挑战。这些挑战不解决智能体永远是个“实验室产品”。3.1 挑战一有限上下文窗口与信息过载的博弈所有大模型都有上下文长度限制如128K、200K tokens。这不是简单的“内存不够”更关键的是随着上下文增长模型对中间部分信息的注意力会衰减导致性能下降这种现象被称为“中间丢失”。策略1动态摘要与压缩这是最重要的手段。不是等窗口满了才处理而是建立主动的摘要机制。例如在对话类智能体中每5轮对话后触发一个摘要生成“将上述对话总结为用户的核心需求、已确认的信息和待解决的问题。”然后用这个摘要替换掉那5轮原始对话。对于文档处理可以按章节或段落生成摘要。策略2优先级筛选与滑动窗口并非所有信息都同等重要。设计一个评分机制根据信息的新鲜度最近提及、相关性与当前查询的语义相似度和重要性是否包含关键决策、数字、实体对上下文中的片段进行排序。只保留得分最高的部分形成一个“滑动窗口”。最新的用户查询和系统指令通常具有最高优先级。策略3分层存储与按需提取建立外部记忆体如数据库。将完整的会话历史、文档内容存储在外在需要时根据当前查询只检索最相关的片段注入上下文窗口。这实现了“无限上下文”的假象。实操技巧在实现分层存储时除了向量索引务必为每条记忆打上时间戳、会话ID、实体如产品名、人名等标签方便进行多维度检索和过滤。3.2 挑战二信息噪声与相关性衰减即使上下文窗口没满塞进去的低质量、无关信息也会成为“噪声”干扰模型判断。根因工具返回的冗长错误日志、检索到的不相关文档片段、用户对话中的闲聊内容都会污染上下文。解决方案上下文清洗与归一化工具结果过滤在将工具执行结果返回给模型前先做一层预处理。例如从API返回的JSON中只提取业务字段丢弃requestId、timestamp等调试信息。对于错误提取错误码和核心错误信息而不是堆栈跟踪。检索结果重排序与去重RAG检索返回的Top-K个文档经常有内容重叠。可以使用MMR最大边际相关性等算法在保证相关性的同时增加多样性避免上下文被同一事实的不同表述重复占据。对话内容轻量化识别并压缩用户消息中的客套话、重复表述。例如将“你好请问你能不能再帮我看看那个就是刚才说的那个问题我还有点不明白……” 压缩为 “用户对之前的问题仍有疑问。”3.3 挑战三长期依赖与状态一致性智能体在处理多轮、跨会话的复杂任务时必须维持长期的一致性。比如用户周一说了喜欢咖啡周五推荐饮品时就不能推荐茶。问题简单的滑动窗口或摘要会丢失这些长期偏好和细节。解决方案显式状态管理与属性提取设立一个独立的“用户档案”或“会话状态”存储。这不是给模型看的原始对话而是结构化数据。在对话过程中持续运行一个后台的“信息提取”智能体或调用模型的函数调用能力专门从对话中捕捉结构化信息并更新状态库。例如检测到“我喜欢拿铁不加糖”的表述就在用户档案的preferences字段更新{“favorite_drink”: “latte”, “sugar”: “no”}。在每次对话开始时或将对话主题切换到相关领域时将这些结构化的状态信息以自然语言描述的形式插入到上下文的前部。例如“[已知信息] 用户张三偏好无糖拿铁。”进阶技巧对于项目型智能体如编码助手可以维护一个“项目上下文”包括技术栈、已实现的模块、待解决的BUG列表等。这个上下文在项目周期内持续存在并更新。3.4 挑战四多模态与结构化上下文的融合未来的智能体必然要处理文本、图像、表格、代码等多种格式的信息。如何让模型在上下文中有效理解这些异构数据文本描述法对于图像使用视觉模型生成详细的文本描述对于表格提取表头和关键行列数据用文字说明其含义和趋势对于代码除了代码本身补充其功能说明和关键逻辑注释。核心原则是将所有非文本信息转化为模型能直接消化理解的自然语言叙述。结构化标记法在上下文中使用明确的标记来分隔不同类型的内容并说明其关系。例如[用户上传的图片描述开始] 图片内容一张折线图标题为“Q1销售额”。横轴是1月、2月、3月纵轴是销售额万元。1月约50万2月骤降至20万3月回升至45万。 [用户上传的图片描述结束] 用户问题请分析这张图中2月份销售额下降的可能原因。这种方式清晰地将视觉信息转化为了语言模型的“食粮”。混合使用对于代码可以同时提供代码块供模型参考具体语法和文字说明供模型理解意图。模型在上下文中看到代码块能更好地进行补全或调试。4. 从设计到实现一个智能体上下文系统的搭建蓝图理论说再多不如一个实战蓝图。下面我以一个“智能数据分析助手”为例勾勒其上下文系统的核心设计。这个助手能接受用户自然语言查询连接数据库进行分析并生成报告。4.1 系统架构与数据流设计整个系统的核心是“上下文管理器”它不直接生成回答而是负责为每次对大模型的调用准备一份“营养均衡”的上下文大餐。用户输入 | v [输入预处理模块] | - 清洗文本提取意图 | v [上下文管理器] | | |--- [会话历史存储] ---| 更新 |--- [知识库向量存储] ---| 同步 |--- [用户状态存储] ---| 更新 |--- [工具结果缓存] ---| 写入 | v [上下文组装引擎] | 1. 获取当前会话摘要 | 2. 根据意图检索相关知识 | 3. 加载用户偏好/状态 | 4. 注入系统指令和本次查询 | 5. 应用Token压缩/优先级筛选 | v 组装好的上下文 (Prompt) | v [大语言模型] | v 模型响应 (可能包含工具调用请求) | v [工具执行器] | v 工具执行结果 |------------------------------ 写回[工具结果缓存] | v [输出后处理与上下文更新] | - 格式化响应 | - 更新会话历史 | - 提取并更新用户状态 | v 最终回复给用户4.2 核心模块实现要点1. 会话历史存储与摘要模块存储使用Redis或PostgreSQL按session_id存储每轮对话的原始记录role,content,timestamp。摘要生成不要每轮都做摘要那样成本太高且琐碎。我常用的策略是“阈值触发”长度阈值当某个会话的原始历史总token数超过2000时触发摘要。轮次阈值每完成5轮对话触发摘要。主题切换检测通过嵌入向量计算用户消息之间的语义变化如果检测到明显的话题转折则在转折点前对旧话题进行摘要。摘要提示词设计摘要的质量至关重要。不能简单地说“总结上述对话”。要引导模型提取结构化信息请将以下对话总结为以下要点 1. 用户的核心目标或问题是什么 2. 目前已确认的关键信息有哪些如日期、数字、选择、偏好 3. 当前待解决或未决的事项是什么 4. 智能体已承诺或正在进行的操作是什么 请用简洁、客观的语言陈述避免直接引用原句。2. 知识检索与注入模块检索不是一次性的在组装上下文时检索应至少进行两轮第一轮粗筛。基于用户当前查询从向量库检索出Top-10相关片段。第二轮精炼。将第一轮的结果和用户查询一起让一个轻量级模型或同一模型但用更短的上下文进行相关性重排序和去重选出Top-3最核心、最不重复的片段。这能有效防止无关信息混入。检索结果格式化每个检索片段注入上下文时必须带上来源标识例如[参考知识-产品手册第3章]...内容...。这既能增加信息可信度也便于模型在生成回答时引用来源或在后续需要时进行溯源。3. 用户状态管理模块状态结构设计根据业务领域预先定义好状态Schema。对于数据分析助手可能包括{ “current_project”: “Q2销售分析” “preferred_chart_type”: “折线图” “recently_used_datasets”: [“sales_2024”, “user_logs”], “analysis_focus”: [“regional_comparison”, “monthly_growth”] }状态更新时机状态更新不应阻塞主响应流程。可以采用异步方式在每次获得模型响应或用户输入后启动一个后台任务来分析文本提取可能的状态变更并原子化地更新存储。4. 上下文组装与压缩引擎这是最核心的“厨师”负责把各种食材历史、知识、状态、指令炒成一盘菜。其算法伪代码如下def assemble_context(user_query, session_id): # 1. 加载基础指令 context_parts [get_system_instruction()] # 2. 加载会话记忆优先用摘要不够再补原始记录 conversation_memory load_conversation_memory(session_id, max_tokens800) context_parts.extend(conversation_memory) # 3. 加载用户状态结构化转自然语言 user_state load_user_state(session_id) if user_state: context_parts.append(f“[已知用户背景]{format_state_to_text(user_state)}”) # 4. 检索并注入相关知识 relevant_knowledge retrieve_knowledge(user_query, conversation_memory) context_parts.extend(relevant_knowledge) # 5. 注入本次查询 context_parts.append(f“用户查询{user_query}”) # 6. 令牌预算管理与压缩 final_context apply_token_budget_and_compression(context_parts, max_tokens32000) return final_context其中apply_token_budget_and_compression函数负责在总token超限时按照预设的优先级系统指令 最新查询 用户状态 最新对话记忆 旧对话记忆 参考知识对优先级低的部分进行摘要或截断。4.3 避坑指南我踩过的那些“上下文”的坑坑1摘要失真导致信息丢失。早期我们让模型做摘要结果它过度概括把用户明确指定的一个关键参数给“概括”没了。解决方案在摘要提示词中强调“必须保留所有具体的数字、日期、名称和选择项”。更好的办法是对于关键实体产品名、ID、日期在生成摘要的同时将它们单独提取出来作为结构化标签存储在需要时直接注入上下文。坑2工具结果污染上下文。一个调用外部API的工具返回了包含html...的整个错误页面直接被塞进上下文导致模型后续输出混乱。解决方案为每一个工具调用编写一个“结果解析器”函数这个函数的唯一职责就是把原始的、可能很脏的返回结果清洗成一句或几句干净、完整的自然语言描述。这是上下文工程里性价比最高的投入之一。坑3状态冲突。当多个并行流程如一个处理主任务一个后台提取状态同时读写用户状态时可能发生覆盖。解决方案对状态存储使用乐观锁或版本号控制确保更新是基于最新状态的。或者将状态设计为可追加的日志形式而非完全覆盖的键值对。坑4上下文窗口“冷启动”问题。一个新会话开始时上下文里只有干巴巴的系统指令模型缺乏“热身”导致前几轮回答比较生硬。解决方案设计一个“上下文预热”机制。即使在新会话中也根据用户的第一句话注入一些通用的、与领域相关的背景知识或示例对话few-shot learning让模型快速进入角色。5. 超越工程上下文思维与智能体设计的未来当我们把上下文工程做到位会发现它不仅仅是一套技术实现更是一种设计智能体的思维方式——上下文思维。这种思维要求我们在设计智能体的每一个交互、每一个工具、每一个流程时都不断地问完成这个动作需要哪些信息这个动作会产生哪些新信息这些信息该如何有效地传递给后续的步骤或其他智能体这引向了更前沿的两个方向1. 动态上下文编排未来的上下文管理器可能不再是静态的管道而是一个智能的“导演”。它能根据对话的进展、用户的情绪通过文本分析、任务的复杂度动态地调整上下文的组成策略。例如在轻松闲聊模式下减少知识库检索的权重增加会话历史的长度以保持连贯性在进入严肃的数据分析任务时则立刻切换到“精准模式”注入更多相关数据表和字段说明并压缩无关的聊天历史。2. 多智能体间的上下文共享与同步在复杂的多智能体协作系统中如一个智能体负责规划一个负责执行一个负责审核上下文需要在智能体之间安全、高效地流转。这涉及到上下文的过滤智能体B不需要知道智能体A的所有内部思考、摘要传递核心结论而非过程和版本管理。这有点像人类团队间的“工作交接”和“会议纪要”需要设计一套协议和共享内存区。说到底上下文工程的目标是让AI智能体从“单次反应的鹦鹉”进化成“拥有记忆、知识和规划能力的伙伴”。它把一次次的独立问答编织成了一段有头有尾、有因有果的连续协作。这个过程充满细节和挑战但每解决一个上下文相关的问题你的智能体就会变得更可靠、更聪明一点。这不再是炫技的提示词魔法而是扎扎实实让AI真正融入工作流的系统工程。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进