ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Elastic Agent Builder实践:让AI Agent自主管理上下文

2026/9/11 5:31:50 拓冰建站 浏览量
Elastic Agent Builder实践:让AI Agent自主管理上下文 上个月有个做内部知识库的客户跑来问我现在团队天天在用各种Agent写代码、做分析但他们最头疼的反而不是模型效果差而是上下文老是不够用。对话稍微长一点Agent就开始“失忆”要么答非所问要么干脆报错。我当时的回答是别总想着把上下文塞给模型你得教会 Agent 自己管理上下文。这个思路后来就落到了 Elastic Agent Builder 这套实践上。Elastic Agent Builder 是 Elastic 平台里用来构建和托管 AI Agent 的能力底层衔接了 Elasticsearch 的数据存储与检索、ES|QL 查询以及外部大模型接口。它的核心价值在于让 AI 代理不只依赖模型自带的上下文窗口而是通过一套机制主动决定“什么该记住、什么该查、什么该丢”。这篇博文就完整拆解我们是怎么做到的包括设计思路、核心配置、System Prompt 的写法、踩过的坑以及实测数据适合正在用 RAG 做应用、或者被上下文长度困扰的开发者参考。1. 整体设计为什么“上下文管理”不能靠模型自己硬扛先聊一个很实际的问题上下文到底是什么对 AI 应用来说上下文就是你在一次对话或一次任务里喂给大模型的全部信息包括用户问题、历史对话、检索到的文档片段、工具返回结果等。大模型能同时处理的信息量是有限的用行话讲叫“上下文窗口”比如几千到几十万 token 不等。一旦超出要么直接报错要么模型强行截断结果就是核心信息丢失。1.1 “无限制上下文”为什么是个伪命题网上很多人追捧“无限制上下文”或者“超长上下文”但实际上这是一个工程取舍问题而不是简单的容量问题。即使模型的上下文窗口能撑到 100 万 token或者通过某些手段做“上下文压缩”也不意味着你该把所有东西都塞进去原因有三点。第一成本和延迟会线性上涨。大模型是按照输入 token 数计费的假设一次查询只用了 5 万 token 的上下文看起来不多但如果一个 Agent 一天被调用 1000 次一个月下来成本就是不可忽视的。第二信息干扰会变严重。当上下文里混入大量无关文本时模型反而容易被噪声带偏专业说法叫“注意力分散”表现出来就是幻觉变多、回答质量下降。第三服务端硬限制仍然存在。即便是 Claude、GPT 这些头部模型API 层面也有明确的 max_tokens 上限比如 Claude 单次请求超过 200K tokens 就会强制失败。所以在实际项目里追求“无限制”没有意义你真正要解决的是有限的上下文窗口如何装下最关键的信息。1.2 传统做法有哪些隐藏成本目前大多数 RAG 应用的上下文管理方式是外部代码写死逻辑先把用户问题拿去向量检索取回 top K 条结果拼到 prompt 里再丢给模型。这个方案能跑但有几个很别扭的地方。一是路由不灵活。不管用户的意图是什么检索逻辑永远是“查相似度最高的那几条”不会区分“这事我可以用工具直接算出来”还是“这事我需要去翻历史工单”。二是历史记忆基本靠堆。很多产品直接把整段对话记录 append 到 prompt 里没有摘要、没有裁剪聊到第十轮时前面的信息早就被截断了。三是为了解决这些问题你可能要额外写一套调度逻辑比如判断何时该摘要、何时该清空、何时该触发检索。这些逻辑写多了代码就变成一座维护成本很高的屎山。那时候我就在想为什么不把“决定怎么管理上下文”这件事直接交给 Agent 本身毕竟 Agent 是有推理能力的它比写死的规则更知道当前这一步需要什么信息、不需要什么信息。1.3 Elastic Agent Builder 的思路转变Elastic Agent Builder 在架构上理顺了这条逻辑。它不把 Agent 定义成一个“输入 prompt 就返回结果”的黑盒而是拆成了“规划 - 工具调用 - 检索 - 再规划”的循环。Agent 内部有一个编排器Orchestrator可以感知当前任务状态决定下一步是调用一个外部工具、发起 ES|QL 数据聚合、还是结束对话并给出答案。触发检索、触发查询这些动作是由 Agent 自己判断的不是外部代码强行塞给它的。这样带来的好处非常明显上下文里不再需要预置一堆“可能有用”的文档Agent 只会在真正需要时把相关信息拉进来用完之后还能主动清理对话历史只留摘要。这才是“AI 代理自己管理上下文”的真实含义也是整个项目里体验最明显的变化。我用一个生活化的类比来解释传统的 RAG 方案像是你去饭店吃饭不管你点什么菜后厨都先把所有食材堆到桌子上让你自己挑。Agent Builder 的方案则是你点菜后厨按需配菜用不到的食材永远待在冰箱里。显然后者更省空间、更准确。2. 核心机制拆解Agent 到底怎么“管理”上下文这个部分我会拆开讲 Elastic Agent Builder 内部的核心机制不涉及太多源码重点说清楚设计原理。理解了这些你写配置和 System Prompt 时才能真正得心应手而不是套模板。2.1 工具调用上下文的最小加载单元Agent Builder 里的一个核心概念是“工具”或“技能”。一个技能可以被理解成一个独立的动作比如“运行一次 ES|QL 查询”或者“搜索知识库内的相似文档”。关键的设计在于技能不是一次性全部加载到上下文里的。在每一轮规划时Agent 只会选择需要的 1 到 2 个技能并且只把这次技能调用需要的最小参数带过来。举个例子如果用户问“上个月订单失败率最高的三个地区是哪些”Agent 的规划结果是调用“ES|QL 数据查询”这个技能那么上下文里加载的只是这次查询的条件和返回结果历史对话里那些关于登录、权限、测试数据闲聊的内容都会先被摘出来放到一边。这种方式让上下文的使用效率提升了非常多实测同等任务下 token 消耗能减少一半以上原因就是模型每一轮“看到”的内容都更精准了。2.2 检索时机由模型意图决定Agent Builder 的另一个机制是“检索时机控制”。它不是每轮都做向量检索而是把检索当成一个可选的工具。模型会根据用户问题的意图自主决定是否调用检索。比如用户问的是实时统计数据Agent 可能会直接选择 ES|QL 聚合而不是向量检索。但如果用户问的是“我们之前有没有处理过类似的网络超时问题”Agent 就会调用语义检索在历史工单里找相似记录。这种“按需检索”的模式有一个很实在的收益把你每次请求的上下文平均体积降下来了。过去做一个固定的 RAG 流程一次请求至少带 3 到 5 条文档片段每条可能 500 到 1000 token总共就是 3000 到 5000 token。现在 Agent 只有在语义需求明确时才会检索很多统计类问题甚至完全不检索直接执行 ES|QL 就返回了上下文体积可以控制在 1000 token 以内。2.3 对话历史压缩智能摘要代替无限堆叠对话历史的管理是上下文工程里最容易翻车的一块。简单粗暴地把之前的对话全量附上越到后面上下文越长模型越容易迷失重点。Agent Builder 内置一个策略当对话轮次超过设定阈值时触发一次“历史摘要动作”。系统会先让模型把前面的关键信息压缩成一段摘要比如用户需求、已经确认的时间范围、已经排除掉的方案这部分摘要替换掉原始对话继续参与后续推理。这里有个容易被忽略的细节实现时要处理好“阶段性摘要的累积误差”。也就是说第一轮压缩成摘要 A第二轮把摘要 A 和新对话再压缩成摘要 B如果压缩逻辑设计得不好信息会被层层丢失。我们在实际方案里做了个改进——摘要生成时要求模型保留“结构化标签”比如“用户限制条件”“已确认事实”“待办事项”并且在新一轮压缩前做一次关键字段比对确保这些信息没有被遗漏。你如果自己去配 Agent也可以参考这个思路关键是不要偷懒只让模型写一段自然语言总结要给一个固定的摘要模板。2.4 策略编排写“规则”让 Agent 执行上面这些机制听起来很美好但要是没有好的策略编排Agent 很容易“自由发挥”得过了头比如该检索的时候不去检索、不需要工具时硬去调用。所以我们在 System Prompt 里塞入了一套显式规则告诉 Agent 在什么情况下必须走什么路径。规则本身并不复杂重要的是颗粒度要合适。不能太粗太粗 Agent 抓不住边界也不能太细太细会变成“手写规则系统”失去了 Agent 自主推理的意义。我们最后落地的规则大致如下用户询问历史工单、历史经验、知识库内容必须触发语义检索技能用户询问统计指标、趋势、聚合结果必须触发 ES|QL 数据查询技能如果问题能通过数据查询直接回答则不需要额外检索文档当对话轮次超过 6 轮触发历史摘要并在摘要中保留“用户限制条件”和“未解决问题”如果检索结果为空必须明确告知“知识库内未找到相关内容”而不是自由发挥编答案。你可以在部署时按需调整这些规则但核心思想是一致的Agent 是执行者但策略的边界该由人来定。上下文管理这件事本质上就是“在什么时机加载什么信息”而策略编排决定了这个“时机”是否可靠。3. 实操过程从零配好一个会管上下文的 Agent下面进入完整实操环节。我会按步骤说明整个配置流程包括环境、数据准备、连接器配置、Agent Builder 创建、System Prompt 写法、技能定义和测试验证。这套流程以 Elastic Cloud 为基础如果你用的是本地部署步骤几乎一致只是连接器地址有些差异。3.1 环境准备Elastic Cloud 与基础组件我这边用的是 Elastic Cloud 最新的版本版本号不是核心因为 Agent Builder 能力基本已经进入稳定的通用可用阶段。你需要确保环境中已经启用了以下基础组件Elasticsearch 索引用于存储知识库文档和对话记录Inference API用于调用外部大模型接口比如 OpenAI 兼容接口或者 Claude 接口Connector API用于连接外部数据源比如企业内部 Wiki、工单系统或模型服务Kibana 里的 Search AI Lake 或 AI Assistant 模块因为 Agent Builder 的图形化配置界面就在这里。如果你的环境里还没有 Elasticsearch建议先创建一个最小规模的部署两节点起步数据量不大时完全够用。3.2 准备知识库和索引映射先准备一份知识库数据。比如我们这里使用了一个“历史工单数据集”包含工单标题、问题描述、解决方案、发生时间、影响系统等字段。把这些数据导入 Elasticsearch 后要创建一个给 Agent 用的搜索管道核心是定义一个向量字段映射用于后续的语义检索。你需要确保索引的 mapping 里有类似于下面的字段结构{ mappings: { properties: { title: { type: text }, description: { type: text }, solution: { type: text }, created_at: { type: date }, embedding: { type: dense_vector, dims: 1024, index: true, similarity: cosine } } } }如果你的 embedding 模型输出维度不同比如 OpenAI 的 text-embedding-3-small 是 1536 维把 dims 改成对应值就行。测试阶段数据量少可以用较小维度的模型跑通流程再切换正式模型。3.3 新建 Agent 并配置模型连接器进入 Kibana 的 AI Assistant 或 Search AI Lake 页面选择 Agent Builder。创建新 Agent 后会要求你绑定一个模型连接器。这里我们选择 OpenAI 兼容连接器因为内部已有的模型网关支持该协议。连接器配置有几个关键点URL 填模型服务的 API 地址API Key 填你的密钥Model ID 填你希望 Agent 底层使用的模型名称比如 gpt-4o-mini 或你自己的微调模型Prompt 里的温度和 max_tokens 可以先保持默认后面调优再处理。如果你要用 Claude 系列模型Elastic 官方也有对应的连接器模板但需要特别注意Claude 对 system prompt 的格式要求比较严格里面不要有多余的 markdown 表格字符否则容易解析异常。这个坑我下面会细讲。3.4 设计并写入 System Prompt这一步最关键Agent 的“上下文管理性格”有一大半是 System Prompt 决定的。我和团队在调试过程中前前后后改了几十个版本最后沉淀出一套相对通用的写法。这里给出我们的模板你可以直接抄但建议结合自己场景微调。你是企业内部知识助手负责基于工单知识库和数据分析回答问题。 你拥有两个核心工具 1. knowledge_base_search当用户询问历史工单、解决方案、经验总结等内容时你必须优先调用此工具进行语义检索。如果检索结果为空直接告诉用户知识库中没有相关内容不得编造。 2. esql_data_query当用户询问统计指标、趋势、聚合结果等数据类问题时你必须调用此工具使用 ES|QL 查询相关索引基于真实数据回答问题。 上下文管理规则 - 当对话轮次超过 6 轮时你需要对前面的对话进行摘要压缩。摘要必须保留以下结构用户核心需求、已确认的限制条件、未解决的问题、最近一次查询的数据范围。 - 当你准备进行工具调用时先把与当前任务无关的历史对话暂时隔离不要携带进工具调用请求中。 - 当工具返回的结果足以回答问题不要再额外检索知识库。 - 若一个查询可以用 ES|QL 完成就不要用知识库搜索替代。 - 每次回答尽量控制信息冗余不输出与问题无关的背景知识。这套 Prompt 的关键不是辞藻华丽而是把“什么时候调用什么工具”“什么时候压缩历史”“什么时候停止检索”这些上下文管理策略全部显式地写给了模型。你可以把这段 Prompt 理解成一份给实习生看的操作手册规则越清晰执行越稳定。3.5 定义技能让 Agent 真正能“动手查”除了 System Prompt你还需要在 Agent Builder 里定义技能Skills。技能本质上是给 Agent 提供了可执行的工具封装。我们这里定义了两个技能。第一个技能是知识库检索。Provider 类型选择 ElasticsearchIndex 填工单索引名称Query 类型选 semantic。在这个技能配置里有一个“结果数量限制”size参数建议先设为 5后续根据效果调整。还有一个容易被忽略但重要的设置最大检索窗口它控制每一轮检索最多消耗多少 token。默认值可能偏大我们实际调到了 2000 token够用且不浪费。第二个技能是 ES|QL 查询。这个技能里要预设一批常用查询模板因为 Agent 直接用自然语言生成 ES|QL 是有学习成本的稍微复杂一点就容易出错。预设模板的好处是Agent 只需要做“参数填充”和“查询选择”而不是从零生成语法。我们在模板里预置了按时间范围聚合、按字段分组统计、计算平均值或百分比等常见模式。你别小看这一步它能极大减少 Agent 因为查询写错而反复重试的问题。3.6 上下文压缩期的触发条件配置接下来是动手配置“上下文管理”的关键开关。在 Agent 配置页面你会看到一个跟对话轮次、记忆策略相关的区域。这里可以设置“历史摘要触发条件”和“历史保留策略”。我们的配置如下触发轮次阈值6 轮摘要间隔每 3 轮压缩一次保留策略保留最近 2 轮完整原文其余全部替换为摘要摘要长度上限500 token。这个配置的含义是对话进行到第 6 轮时模型会把前 4 轮的内容压缩成摘要保留最近 2 轮完整对话。当新对话达到第 9 轮时再做一次摘要把前 7 轮含第一次摘要再次压缩并仍然保留最近 2 轮。这样一来长对话的上下文体积会被控制在一个相对稳定的范围不会无限膨胀。这里有一个值得多说的设计细节为什么只保留最近 2 轮原文因为很多问题的语义是跟最近几轮强相关的如果全部压缩模型可能理解不了“那按刚才的逻辑再算一遍”。但如果保留太多轮原文压缩机制就形同虚设了。2 轮是一个经过测试后的折中值你可以在自己场景里调整但思路是类似的。3.7 完整测试从简单统计到复杂多轮对话配置完成后建议做一套覆盖不同场景的测试集不要只测几个简单问题就上线。我这边一般会准备这样的测试用例场景一数据查询。问“今年第三季度各业务线的工单量排名”验证 ES|QL 技能是否能被正确触发上下文是否干净场景二知识检索。问“我们之前有没有处理过 SSL 连接超时的工单”验证语义检索是否能召回相关历史记录场景三多轮对话。连续问 8 到 10 个问题观察第 6 轮之后是否自动触发摘要且摘要后能否继续准确回答场景四混合场景。先问统计数据再接着问历史工单验证 Agent 是否正确切换技能且没有把过多无关信息带入第二次检索。我强烈建议你每组测试都把请求日志打开逐条看 Agent 决策记录和 token 消耗。不要只看最终回答对不对要关注“为了回答这个问题Agent 实际向模型发了多少 token”。这一步是我们优化上下文管理时最重要的数据来源。4. 常见问题、踩坑与场景扩展最后这部分我把实际部署过程中遇到的典型问题整理成一份速查表并分享几个解决“上下文管理”痛点的诀窍。同时聊聊这套方案可以用在哪些场景帮助判断它到底适不适合你的项目。4.1 上下文管理常见问题速查表问题现象可能原因解决思路Agent 长对话后突然丢失关键信息摘要压缩策略过于激进丢失了核心条件在 System Prompt 中强制摘要保留“用户限制条件”和“未解决问题”字段Agent 每轮都触发检索回答很慢检索被当成默认动作没有按需触发调整 Prompt非语义需求不检索统计数据直接走 ES|QL工具调用返回片段太长浪费 token技能配置中最大检索窗口偏大将 semantic search 的 size 从 5 降到 3限制最大检索窗口模型生成的 ES|QL 查询总是语法报错没有预设查询模板模型从零生成 SQL/ES|QL新增查询模板技能限定 Agent 只能模板匹配和参数填充Claude 模型偶尔返回顽固格式错误prompt 中包含复杂 markdown 表格字符简化 System Prompt 格式去掉表格改用短句混合意图场景下判断不准确只依赖模型常识判断缺少外部约束增加“意图预分类”步骤先让模型输出 intent 标签再选技能长对话 token 消耗仍然只增不减上下文压缩没有按轮次触发检查 Agent 配置确认摘要触发阈值已生效查询日志中应有 summary 记录表格里列出的这些场景都是我们在真实环境中跑出来的问题不是凭空想象的。其中“摘要丢失关键限制条件”那条最典型早期版本我们的摘要策略只是让模型“总结前面的对话”结果模型把所有关于时间范围、业务线范围的信息都丢了导致后面回答牛头不对马嘴。后来改成结构化摘要模板问题才缓解。4.2 独门技巧在摘要中保留“禁止遗忘”清单说到这里额外分享一个小技巧。如果你希望 Agent 在压缩后仍然不能遗忘某些用户侧的关键条件可以在 System Prompt 的最后追加一段“禁止遗忘清单”例如在整个对话过程中你必须始终记住以下关键用户条件 - 用户指定的时间范围比如近 7 天、本月、第三季度等 - 用户指定的数据筛选条件如特定业务线、特定系统 - 用户明确表达的不需要项如“不要包含测试数据”。 即使发生历史摘要压缩你也要在摘要保留字段中记录这些内容。如果后续回答与这些条件冲突以用户最新明确条件的表述为准。这是一个低成本但见效极快的技巧。我们测试后发现加上这段提示之后Agent 在压缩历史后的回答准确率明显上升原因是模型在压缩时会把“禁止遗忘清单”当成高优先级任务来对待而不是凭感觉提取信息。4.3 适合扩展的场景与落地建议这套“Agent 自主管理上下文”的思路并不局限于 Elastic 这一个平台。虽然我手里写的是 Agent Builder 的实操但底层理念可以平移到任何具备工具调用能力的 Agent 框架上比如 LangChain、Semantic Kernel 等。你只要把“工具按需加载”“对话历史智能摘要”“意图决定检索时机”这三个机制实现出来就能在不少场景中看到效果。比较典型的适用场景包括企业知识库问答历史文档、工单、Wiki 混合问答需要区分查资料和查数据数据分析助手业务人员用自然语言查指标、看趋势不能让 Agent 每次把无关查询条件都塞进上下文智能客服升级多轮对话中要保留客户诉求同时筛选历史解决方案文档审阅与合规检查需要读取多种来源的文本但每个来源只抽取相关片段而不是整套加载。如果你准备把这些场景落地我建议先不要一上来就追求复杂的 Agent 编排能力。先用 Agent Builder 跑通一个最小闭环比如只配置一个知识库检索技能然后再增加 ES|QL 查询技能最后再加入历史摘要压缩。每一步都记录日志、观察上下文变化会比一次性配全所有功能稳得多。从我个人实际操作体会来说Elastic Agent Builder 最有价值的地方并不在于它提供了多炫酷的 Agent UI而在于它把“上下文管理”这个原本要靠手工代码维护的工作变成了有规则、有策略、可观测的系统能力。你不再需要为了一个截断问题反复改提示词拼接逻辑只需要把策略写清楚剩下的推理和判断交给 Agent 自己完成。这个转变带来的效率提升比单纯换一个更大的模型明显得多而且成本还更可控。