ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Agent-Reach:AI Agent从原型到生产环境的工程化落地实践

Agent-Reach:AI Agent从原型到生产环境的工程化落地实践 1. 项目概述Agent-Reach 到底是什么这两年 AI Agent 的概念热得发烫几乎每个技术团队都在捣鼓自己的智能代理。但说实话我见过太多 Agent 项目死在了 PPT 上演示时惊为天人一上生产环境就原形毕露——工具调用三天两头失败、上下文一长就失忆、用户问个稍微绕弯的问题就开始一本正经地胡说八道。这也是我启动 Agent-Reach 这个项目的根本原因。Agent-Reach 的核心只有一句话让智能代理真正触达业务场景而不是停留在原型验证阶段。这里的关键词是“Reach”。它不是“Run”能跑也不是“Demo”能演而是“够得着”——你的 Agent 能不能够到真实的用户需求、够到真实的业务系统、够到生产环境里那些乱七八糟的边界条件。我做这个项目就是想搞清楚一个 Agent 从 Jupyter Notebook 里的玩具变成生产系统里的劳动力中间到底要跨过哪些坎。这篇博文不是学术论文也不是产品宣传稿而是我这几个月在 Agent-Reach 项目里踩坑、填坑、调参、重构的全记录。适合谁看如果你是做 Agent 应用的开发者、AI 产品经理或者正准备把一个智能代理推向生产环境的架构师这篇内容应该能帮你省掉不少弯路。我会把架构选型、核心实现、事故排查、指标体系整个链路拆开揉碎地讲一遍重点说那些文档里不会写的坑。2. 核心需求拆解为什么 Agent 需要一套工程化方案2.1 从“能对话”到“能干活的”差距先聊一个真实场景。我团队之前给一家电商客服公司做过一个退货处理 Agent第一版原型做得特别顺模型理解用户意图、调用退货接口、生成处理结果整个链路在测试集上跑得飞起。但一上线问题接踵而至用户说“我这个东西有点问题想退”Agent 需要知道“这个东西”指的是哪个订单里的哪个商品用户中途打断说“算了不退了我换个大的”Agent 的对话状态管理直接乱了退货接口偶尔超时Agent 不会重试直接跟用户说“您的请求失败请稍后再试”——然后用户就炸了这些问题在 Demo 阶段几乎都不会暴露因为演示脚本是精心设计过的每一个用户输入都在预期路径上。真实世界根本不管你预不预期。Agent-Reach 要解决的本质上就是这三层问题意图理解与上下文追踪的可靠性、外部工具调用的容错性、以及异常场景下的自恢复能力。这三件事单靠调 Prompt 是解决不了的必须从工程架构层面入手。2.2 为什么大多数 Agent 项目都卡在“最后一公里”我观察到一个规律Agent 项目通常死在这几个地方——第一是架构脆弱。很多初期的 Agent 就是一个 Recursive loop把用户输入拼到 Prompt 里让模型决定调用什么工具然后把工具结果拼回去再让模型决定下一步。听起来很合理对吧但问题是模型一旦出现输出格式偏差比如 JSON 里多了一个逗号整个循环就断了。第二是上下文失控。对话超过十轮之后Prompt 越来越长Token 消耗几何级增长模型开始忘掉最开始的信息。这不是模型不行是上下文管理没有做分级策略。第三是工具接入靠硬编码。每接一个新工具就要改一次 Agent 的核心代码改着改着代码就成了一团乱麻。工具越来越多Agent 的决策延迟越来越重最后只好推倒重来。Agent-Reach 解决的就是这“最后一公里”的工程化问题。它把 Agent 从“一段调模型的脚本”升级为“一套可扩展、可观测、可治理的系统”。2.3 我的设计目标不依赖单一模型不追求完美做 Agent-Reach 的时候我给自己定了三个原则。原则一模型无关。底层用 GPT 还是用开源模型、以后换更好的模型都不应该影响上层架构。Agent 的主干逻辑是路由和决策模型只是决策的引擎之一。原则二稳定性优先于智能性。一个偶尔聪明但经常出错的 Agent比不上一个偶尔平庸但从不掉链子的 Agent。所以我把大头精力花在了错误恢复和边界处理上而不是一味追求让模型“更聪明”。原则三可观测性是默认需求。Agent 的决策链路比传统程序复杂得多每一轮调用模型、每一次工具执行都可能是 Bug 的温床所以日志和链路追踪绝不能是事后补的必须在设计时就埋进去。这三个原则贯穿了整个 Agent-Reach 的开发过程后面的所有设计决策都能追溯到它们。3. 整体架构设计Agent-Reach 的分层体系3.1 五层架构接入层、规划层、执行层、记忆层、治理层Agent-Reach 的整体架构我把它拆成五个层。每一层干一件事层与层之间通过标准接口通信互不渗透。接入层Access Layer负责所有外部入口的统一接入。不管是网页端的实时对话、API 接口的批量请求还是内部消息系统里的异步消息全部走这一层转成统一的 AgentRequest 结构。这一层的设计初衷很简单——上行消息如果不统一后面所有层都要写兼容代码。规划层Planning Layer这是 Agent 的大脑。它接收标准化后的请求结合历史记忆和当前状态决定下一步要做什么。规划层有一个核心的“决策循环”详见第 4 章每轮循环先分析意图再拆解任务最后判断该调用工具还是直接回复。执行层Execution Layer也就是工具层。所有 Agent 能做的动作查库存、发邮件、计算价格、调用第三方 API都注册在工具总线上。执行层负责把规划层的指令翻译成具体的工具调用并把执行结果格式化后返回规划层。记忆层Memory Layer解决“失忆”问题。短期记忆存在 Redis 里带 TTL中期记忆存在向量数据库里长期记忆存在关系型数据库里。每一轮对话都要在记忆层完成信息的读写但对模型暴露的永远是一个裁剪后的上下文窗口。治理层Governance Layer这是安全护栏。内容包括这个用户有没有权限调用这个工具这个动作是不是超出了合规边界当前对话的 Token 预算还剩多少这一层不参与 Agent 的“思考”但每一步决策都要经过它的检查。五层架构的示意表格如下层级核心职责关键技术选型主要输入输出接入层多端统一接入、协议转换FastAPI 消息队列原始请求 → AgentRequest规划层意图理解、任务拆解、路由决策LangGraph LLM 策略模板AgentRequest → Plan执行层工具注册、调用、结果格式化Python 装饰器工具总线Plan → ToolResult记忆层分层存储、上下文打包Redis Milvus PostgreSQLQuery → MemoryPackage治理层权限、配额、合规、安全规则引擎 审计日志所有请求 → 通过/拒绝有了层级划分Agent-Reach 的开发和排障就清爽多了。哪一层出了问题直接在对应的日志面板里找不用像以前那样把成千上万行日志从头翻到尾。3.2 为什么用 LangGraph 做规划层框架规划层是 Agent 的大脑很多团队在这层选型时候会纠结是自己写状态机还是用 LangChain 这类现成框架还是上 LangGraph或者其他编排框架。我的选择是 LangGraph理由是它把“循环”这件事做得特别扎实。传统的 Agent 实现不管是 OpenAI Function Calling 的循环还是 ReAct 模式的循环本质上都是在一个 while 循环里反复调模型这个循环的逻辑全靠自己维护。而 LangGraph 把这个循环抽象成了图结构节点是“行动”边是“决策”你可以显式地定义什么时候该调工具什么时候该回退什么时候该结束。这种显式控制对生产环境非常救命。举个例子在最早的版本里我用的是单纯 ReAct 模式Reason and ActAgent 的一轮行为是“思考 → 行动 → 观察 → 再思考”。问题在于一旦模型的输出里出现了不该出现的动作选择这个循环就失控了。比如模型决定去调用一个自己没权限的工具又没有护栏机制结果就是无限执行。而 LangGraph 让你能在图的任意节点加条件判断我可以直接在图结构里写清楚如果工具调用失败超过三次就进入人工兜底节点不再让模型继续猜。LangGraph 的另一个优势是它和 LangChain 生态打通但又不被 LangChain 绑架。LangChain 早期版本的抽象层级太多Debug 起来非常痛苦。LangGraph 的粒度更细状态管理是可编程的你能精准控制每一步的上下文更新。本地方跑的时候每一步的状态变化都可以打印出来逐行检查这在调 Agent 的环节就是救命稻草。当然如果你团队的 Agent 逻辑没那么复杂只有两三个工具调用自己写一个状态机也完全够用。我选择 LangGraph 是因为 Agent-Reach 的业务场景需要处理几十个工具的动态路由手写状态机的话光边和状态的维护就够呛而且后续加逻辑还要重构。3.3 工具总线的设计思路执行层的工具总线是 Agent-Reach 的特色设计。传统 Agent 接工具是“在 Prompt 里描述 在代码里硬编码调用”这种方式加了三个工具之后就很难维护了——每加一个工具不仅要在 Prompt 里加描述让模型知道有这个工具还要在代码里写调用逻辑当模型说要调用该工具时这两处代码还容易不同步。工具总线的做法是用装饰器注册 反射调用。注册工具的时候一次性完成三件事声明工具的描述供模型理解、定义入参 Schema 供模型生成参数、指定执行函数供运行时调用。这三件事绑定在一起不会出现描述和实现不一致的问题。下面是我在工具总线上实现的一个注册示例实际是简化版但结构一致# Agent-Reach 工具总线注册示例 from agent_reach.toolbus import register_tool, ToolResult register_tool( namecheck_inventory, description查询指定SKU的实时库存数量, params_schema{ sku: {type: string, description: 商品SKU编号}, warehouse: {type: string, description: 仓库代码} } ) def check_inventory(sku: str, warehouse: str) - ToolResult: # 调用库存系统的HTTP接口 try: resp inventory_service.query(skusku, warehousewarehouse) return ToolResult.success(dataresp) except Exception as e: return ToolResult.failed(errorstr(e))这段代码有三个重点。第一name和description决定了模型能不能正确理解这个工具是干嘛用的描述写得太简短模型就会乱选工具。第二params_schema用的是 JSON Schema 格式这样模型生成参数时有个明确的约束减少幻觉参数的几率。第三函数的返回值统一包装成ToolResult成功和失败的形态完全一致规划层不用为了不同工具写一堆特殊的错误解析逻辑。工具总线带来的一个直接好处是新增工具的成本从“改代码改 Prompt改测试”变成了“注册一个函数”。我后来接支付查询、订单状态、物流追踪这些工具时每个工具的开发工时从半天压缩到了半小时。4. 核心实现详解Agent 决策循环与上下文管理4.1 决策循环让 Agent 有“计划”、有“反思”Agent-Reach 的规划层核心是一个带状态机的决策循环。循环分四个阶段接收Receive、思考Think、行动Act、观察Observe简称 RTAO 循环。接收阶段从接入层拿到标准化的请求把用户输入、会话 ID、历史消息摘要组装成一个上下文包思考阶段调用大模型让它结合上下文生成行动计划包括目标拆解、需要的工具、参数猜测行动阶段如果行动计划里包含工具调用就交给执行层如果只是需要回答用户就直接生成回复观察阶段获取工具调用的结果判断是否与预期一致。如果一致继续下一步如果不一致修正策略后重新走思考阶段这个环看起来没多少稀奇的但关键在于我增加了一个“反思”子模块。当行动阶段的结果与思考阶段的预期不一致时Agent 需要做一次明确的“重新评估”而不是盲目重试。这里用了一个简单的自省提示让模型对比“我期望发生的事”和“实际发生的事”生成偏差说明和修正策略。这个小小的机制极大减少了 Agent 在一个错误动作上反复横跳的概率。用代码示意一下这个循环的核心逻辑# Agent-Reach 简化的决策循环 class RtioLoop: def __init__(self, planner, executor, memory, guardrails): self.planner planner self.executor executor self.memory memory self.guardrails guardrails async def run(self, request: AgentRequest) - AgentResponse: ctx await self.memory.load_context(request.session_id) for step in range(MAX_STEP): # 防止死循环 # 思考阶段 plan await self.planner.plan(ctx, request) # 治理层检查 decision, reason self.guardrails.check(plan) if decision reject: return AgentResponse.fallback(reason) # 行动阶段 if plan.action call_tool: result await self.executor.execute(plan.tool_name, plan.arguments) # 观察阶段:判断结果是否符合预期 if not result.success: revised await self.planner.revise(ctx, plan, result) plan revised continue ctx self.memory.update(ctx, plan, result) elif plan.action reply: return AgentResponse.reply(plan.message) return AgentResponse.fallback(agent_loop_exceeded)这个实现的关键点在于MAX_STEP。千万不要觉得 Agent 多“思考”几步就能更聪明实际上每多一步踩坑的概率就大一分。我的经验值是单次任务最多 8 步超过就进入人工兜底或者给出明确失败提醒。宁可承认自己搞不定也不能让用户在对话里等到天荒地老。4.2 上下文管理与 Token 预算控制上下文管理是 Agent 工程化最容易忽略、又最容易翻车的环节。很多 Agent 项目初始阶段不设 Token 预算对话轮次一多Prompt 里塞进去的内容越来越长历史消息、工具描述、中间结果、参考文档……全都堆在一起。不仅模型响应的延迟急剧上升成本也跟着暴涨。Agent-Reach 的上下文管理采用了三级策略即时上下文、会话摘要、长期记忆。即时上下文存储最近 5 轮对话的完整内容。超过 5 轮的部分不是直接丢弃而是交给一个摘要模型压缩成一两句话的摘要。这样模型每次看到的除了最近 5 轮完整对话就是一个会话级别的长期摘要。如果用户问的是很久以前的话题摘要无法回答再从向量数据库里做相似度检索把相关记忆片段拼进上下文。这里有一个 Token 预算的控制机制。我把每一轮模型调用的 Token 上限分为三块系统固定内容工具描述、角色设定、安全规则约 15% 的预算固定不变即时上下文约 40% 的预算只装最近 5 轮检索回答长期记忆/文档约 45% 的预算用相似度检索结果填充这个比例的设定是拍出来的吗还真不是是通过好几次压测调出来的。一开始我给即时上下文分了 60%结果发现模型经常忽略检索到的相关信息——因为用户说的都是最近的事但业务问题往往需要更早的背景。之后调整到 40%实测效果是最均衡的。值得提醒的是Token 预算超过预算时不要直接截断文本而是要做“优先级剔除”。我的策略是先去掉检索回来的低分内容再去掉较早的会话摘要最后再去掉工具执行时的冗长日志。如果最大程度减完还不够宁可直接让 Agent 说“我记不清了”也不要硬塞导致模型注意力分散。4.3 记忆层实现Redis、Milvus 和 PostgreSQL 的分工记忆层听上去是一种技术名词实际上拆解下来很简单不同时效的数据放在不同的存储里。第一层是短期记忆存在 Redis 里。每条会话的最近 5 轮完整内容作为一个 Hash 存储key 是 session_idTTL 设为 2 小时。这样服务重启之后用户在 2 小时内的对话上下文不会丢。TTL 设太短用户正常聊个天就断了设太长 Redis 内存压力大2 小时是我在真实业务里测出来的平衡值。第二层是中期记忆存在向量数据库里。每轮对话结束之后主干信息用户意图、Agent 的行为、结果状态会被编码成语义向量存进去用于后续的检索召回。我用的是 Milvus因为它的性能足够好而且支持动态 schema——如果后续要加新的记忆类型不用改表结构。第三层是长期记忆存在 PostgreSQL 里。存的是用户的持久化偏好比如用户之前在退货时说要“优先退到原支付渠道”、Agent 学到的领域规则等。记忆层还有一个“记忆写入”的优化不是每一轮对话都写入记忆而是只在关键节点写。比如用户完成了一个动作退货成功、订单修改成功或者用户表达了一个明确偏好这时候才触发记忆写入。否则的话用户随口一句“今天天气不错”也要编个向量存进去纯属浪费存储资源。5. 实操复盘Agent-Reach 从零到准入生产的环境与部署5.1 运行环境与依赖选型Agent-Reach 作为一个相对重型的 Python 项目对环境有一定要求。我本地的开发环境是 Ubuntu 22.04 Python 3.11 Docker Compose。如果只是跑基础版8GB 内存的机器也勉强可以但建议至少 16GB因为 Milvus 和 Redis 都常驻内存加上模型推理进程的话8GB 会很吃力。依赖管理的推荐做法是用 Poetry 或者 uv不要用 requirements.txt 裸奔。Agent 项目里 Python 包之间的依赖冲突本来就多LangGraph 和 LangChain 生态尤其喜欢互相拉扯版本用语义化版本约束可以省掉不少“为什么之前能跑现在不能跑”的麻烦。以下是核心依赖的参考版本写文章时验证过的一组稳定组合python 3.11 langgraph 0.2.20 langchain-openai 0.2.5 redis 5.0.0 pymilvus 2.4.0 psycopg2-binary 2.9.0 pydantic 2.6.0 fastapi 0.110.0这里有个坑要提醒LangGraph 的版本更新比较勤快API 变动也大。我中途从 0.1.x 升到 0.2.x遇到几个 API 签名变化花了一天时间迁移。建议锁定版本号生产环境的依赖就固定在那一个 commit不要追新。5.2 部署拓扑与服务划分生产环境的 Agent-Reach 不是单机跑一个 Python 进程而是拆成 5 个独立的服务gatewayFastAPI 服务负责接入层的所有请求和响应转换plannerLangGraph 规划层独立部署与 gateway 通过 gRPC 通信executor工具执行服务跑在容器里按需扩缩容memory记忆服务封装 Redis、Milvus、PostgreSQL 的读写接口governance治理服务提供规则引擎和审计查询拆成微服务看起来更复杂了但带来的收益是某个服务雪崩时其他服务不受影响。比如 executor 因第三方 API 慢被拖垮后gateway 和 planner 还能继续响应基本的对话能力只是工具调用会失败。这在单体架构里很难做到。服务的编排我直接用了 Docker Compose测试环境和 Kubernetes生产环境。Kubernetes 上部署主要依赖 HPA水平自动扩缩来应对突发流量因为 LLM 调用的延迟方差非常大普通静态扩容不好预测。5.3 构建工具注册与测试基线实操记录我拿一个典型业务场景来演示 Agent-Reach 的构建过程。假设我们要做一个“订单服务助手”核心能力四个查订单状态、发起退款、修改收货地址、计算运费。第一步是定义这四个工具并注册到工具总线。以“查订单状态”为例register_tool( namequery_order_status, description根据订单号查询最新物流状态和签收信息结果返回结构化状态码、所在地、预计送达日期。, params_schema{ order_id: {type: string, description: 订单号例如 SO20240617001} } ) def query_order_status(order_id: str) - ToolResult: data order_service.query_status(order_id) return ToolResult.success(datadata)第二步是配置规划层的策略模板。我用的是 LangGraph 的简单三节点图route_intent判断用户意图 →execute_tool执行工具 →compose_response生成回复。route_intent节点会将用户输入映射到四个工具之一并给出参数。映射不到的直接走compose_response用模型通用能力回答。第三步是编写测试基线。这是整个过程中最磨人但也最重要的环节。我建了三层测试集第一层是“标准路径测试”20 条典型用户输入比如“帮我查一下订单 SO20240617001 到哪了”第二层是“变异测试”在标准输入上做轻微扰动比如“查一下状态呗订单号是这个SO20240617001”或者用户用不标准的中文表达第三层是“对抗测试”故意给 Agent 设陷阱比如“我的订单号是 SO20240617001 和 SO20240617002 对比一下哪个先到”——这种没有设计对比工具的诉求Agent 应该会明确回答“我无法对比订单时效”我建议任何 Agent 项目在正式上线前都必须至少跑完这三层测试。不要只看标准路径的通过率变异测试和对抗测试才真正反映 Agent 在真实用户面前的抗压能力。6. 常见问题与排查实录Agent 事故现场还原6.1 现场一Agent 死循环疯狂调用工具第一次遇到这个问题是在测试“订单跟踪”功能的时候。用户问“我的东西到哪了”Agent 先调用了query_order_status拿到了订单状态正常返回。但它在生成回复之前又去调了一次——没有任何理由就是模型自己决定再查一遍。然后第三次第四次直到我们代码里的 MAX_STEP 把它拦住。这个问题的根因是 LangGraph 图中compose_response节点的判定太宽松了。模型在观察阶段结束后下一步被引导回了“再次行动”节点而不是“结束并回复”。排查方式是在观测面板里逐节点看模型的状态转移发现它反复绕圈。修复方案有两步。第一步在compose_response节点显式判断如果前一个节点已经是execute_tool且执行成功且用户问题已经得到解答就终止循环。第二步在治理层加了一个“同工具连续调用不超过 2 次”的规则超过就强制切到兜底路径。6.2 现场二模型虚构工具参数有一次Agent 需要调用“修改收货地址”工具用户说的是“把地址改成北京市朝阳区某某路 88 号”。模型生成的参数是对的new_address北京市朝阳区某某路 88 号。但第二次测试的时候用户说的是“地址改成之前默认那个”模型竟虚构了一个address_id12345的关键参数。它并不知道用户默认地址是什么只是在瞎猜。这类幻觉问题有个通用规律模型特别擅长在信息不足时脑补。所以我在工具总线的params_schema上做了更严格的要求每个参数都声明是否必须且禁止在描述里出现任何“猜测默认值”的引导。另外在执行层加了参数校验凡是参数值与上下文里已经存在的信息对不上直接返回参数缺失错误让 Agent 去向用户澄清而不是用错误参数去撞业务系统。6.3 现场三上下文被工具日志塞爆有一次生产告警提示 Token 消耗异常排查发现某工具获取物流详情的第三方接口返回的 JSON 特别大6000 多字符。Agent 把完整返回值原封不动丢进上下文然后下一轮又把这 6000 字符传给模型。连续三轮之后单条消息的 Token 数翻了三倍。修复办法是给工具执行层加“返回结果裁剪”机制配置每个工具可暴露的最大字段长度。超过长度的部分不传给规划层而是存储到执行日志里需要时再去查。同时加了一个字段级别的敏感信息过滤——像手机号、身份证号这类数据在进入上下文之前就做了掩码处理。这不仅是为省 Token更重要的是隐私合规。6.4 现场四数据库写入失败导致的状态错乱这起事故最有代表性。Agent 在执行“发起退款”时底层的退款接口返回了“成功”但因为网络抖动Agent 没收到成功响应以为失败了。于是它重新发起退款——结果用户在后台看到两笔退款单。这个问题本质上是“分布式系统的确认不确定性”Agent 的决策循环必须引入幂等机制。修复方案是在工具注册时强制声明该工具是否幂等。对于“发起退款”这种非幂等动作Agent 在执行完但没收到确认响应时不走“重试”路径而是走“人工确认”路径——明确告诉用户“退款指令已提交请稍后查询确认”同时生成一条待确认的工单给人工客服。Agent 工程里最让我战战兢兢的从来不是模型不够聪明而是它在不该有行动力的时候太有行动力了。幂等约束和操作确认是把这种行动力关进笼子的重要手段。7. 衡量指标与巡检体系Agent 上线前必须会的四件事7.1 四项核心指标达成率、成本、延迟、护栏命中率Agent 项目上线后团队经常面对一个灵魂拷问这 Agent 到底有没有用要回答这个问题不能靠感觉得看数据。我维护了四项核心指标任务达成率Success RateAgent 在一条会话中完整解决用户诉求的比例。计算方式是通过事后标注人工抽检或者关键节点检测比如用户结束会话时是否触发了“问题解决”节点。达成率低于 85% 的 Agent 是不具备上线资格的。单会话成本Cost/Conversation每条会话消耗的 Token 费用总和。主要看两个值平均值和 P95。平均值告诉你长期经营的可持续性P95 告诉你预算的极端波动——如果某些场景的成本异常高说明上下文管理或工具调用有优化空间。端到端延迟Latency从用户发出消息到收到 Agent 回复的总时长。内部又拆成规划层耗时、工具调用耗时、生成耗时三段。哪个环节成了瓶颈一目了然。护栏命中率Guardrail Hit Rate治理层拦截下来的异常动作占所有请求的比例。命中率不是越低越好而是要看拦截的“质量”——拦下了真正的风险动作而不是误杀正常流程。误杀率高说明护栏规则设计得太激进要调整。7.2 巡检面板与告警策略Agent-Reach 的观测层我用的工具是 Grafana Prometheus 加自定义的链路追踪日志。每个服务启动时都会注册自身的 Metrics核心的展示面板有四个服务健康度服务存活、请求数、错误率、P95 延迟模型调用统计每轮调用的 Token 消耗、成本估算、不同模型供应商的占比工具统计每种工具的调用次数、成功率、失败原因分布质量反馈用户消极反馈量点“没用”按钮的、人工接管量、超时回退量告警策略上重点关注三类异常信号单服务错误率连续 5 分钟超过 5%、单会话 Token 消耗超过预设阈值、护栏拦截数量突然飙升说明出现了新类型的恶意输入或模型行为异常。7.3 回归评测集的维护这可能是所有 Agent 工程中最不被重视又最关键的一环。模型升级、Prompt 微调、工具数量增加都需要回跑评测集验证没有引入回归问题。我的做法是维护一个持续增长的评测集每次线上出现问题、修复后都把出问题的 case 添加到评测集里。现在这个评测集大概有 200 多条包含标准路径、边界输入、故障注入比如故意让某个工具报错等类别。每次迭代要跑全量回测通过率不低历史基线就不允许上线。这个过程的繁琐程度堪比维护一套单元测试但它对 Agent 系统的稳定性贡献是隐形的、巨大的。8. 写在最后Reach 的关键从来不是模型本身几个月做下来最大的感悟是Agent 项目能不能走向生产环境关键不在大模型选得多好、推理能力多强而在系统工程的严谨性。模型只是提供了一个不完美的“大脑”工程体系负责把不完美兜住——该裁的上下文裁剪掉该拦的危险动作拦住该人工确认的绝不擅自执行。Agent-Reach 后续我打算扩展方向也基本清楚了增强多 Agent 协作时的任务分配机制、做更有深度的记忆沉淀规则、以及把护栏层做成可视化配置让业务人员也可以调整规则阈值。这些方向绕不开的还是那一件事——让 Agent 稳定地触达那些原本只能靠人肉完成的任务。这才是“Reach”分量的所在。
返回列表