首页 / 资讯中心 / 文章详情

Agent真正难管的不是token,而是这四大隐性失控源

Agent真正难管的不是token,而是这四大隐性失控源 ★ FEATURED ARTICLE
1. 这句话到底在说啥当大家还在盯着token数时真正的瓶颈早就不在那里了“Agent真正难管的不是token”——这句话最近在技术圈里传得挺快尤其在做智能体Agent开发、RAG系统搭建、多步任务编排的同行之间常被当作一句带点自嘲又透着清醒的口头禅。它不是在否定token的重要性而是像一个老司机看到新手猛踩油门还死盯转速表时轻轻拍了下方向盘说“别光看这个你轮胎快磨平了刹车片也快没了转向系统响应延迟200ms这时候再加推力车不是跑得快是飞出去。”我接触过不下二十个实际落地的Agent项目从某高校实验室的科研助手Demo到某公司内部的跨系统工单自动处理系统再到面向终端用户的多模态客服Agent。它们有个惊人的一致性90%以上的调试时间花在解决“行为不可控”“路径不可预测”“结果不可复现”上而不是在优化prompt长度或压缩embedding向量维度。Token确实会卡——比如模型返回超长思考链导致超限、流式输出中断、上下文窗口塞满冗余日志——但这些基本都属于“有明确报错、有固定解法”的显性问题而真正让人半夜改代码改到凌晨三点的是那些没有错误日志、没有超限提示、甚至模型返回结果“语法完全正确”但业务逻辑彻底崩坏的隐性失控。举个真实例子某次为某制造企业做的设备故障诊断Agent核心流程是“接收维修工语音转文字 → 提取故障关键词 → 检索知识库 → 调用维修SOP接口 → 生成分步指导”。我们把token控制得极好输入严格截断、检索结果只取top3、SOP调用返回精简字段。可上线后发现维修工按步骤操作后设备反而报出新错误。排查三天最后定位到Agent在检索环节“自信地”把“轴承异响”误判为“轴承过热”于是调用了冷却系统清洗流程而实际该换润滑脂。整个过程token用量只有模型上限的42%没有任何报错所有中间步骤返回都是200状态码日志里全是绿色✓——但它就是做错了事。所以“难管”的本质是Agent作为一个具备目标导向、工具调用、反思修正能力的动态决策体其行为稳定性、逻辑一致性、环境适应性远比静态文本长度更难建模、更难观测、更难干预。Token是纸面指标是API账单上的数字而“管得住”是让Agent在复杂现实约束下持续做出可预期、可追溯、可兜底的动作。这背后牵扯的是推理链路设计、工具边界定义、状态感知粒度、失败回退机制、人类介入通道等一系列系统级工程问题。接下来我们就一层层拆开来看为什么这些地方才是真正卡脖子的关卡。2. 为什么token只是表象四大隐性失控源深度拆解很多人一听到“Agent难管”第一反应是去压prompt、裁context、换小模型——这就像汽车动力不足时先去拆掉空调压缩机、卸掉音响功放指望靠减重提速。短期可能有点用但根本问题没碰。真正让Agent“不听使唤”的是以下四个深层结构性问题它们共同构成了比token更顽固的瓶颈。2.1 推理链路的“黑箱漂移”Chain-of-Thought不是万能保险丝CoT思维链被奉为Agent的“大脑”但现实很骨感它既不是逻辑电路也不是确定性程序。模型在生成“Let me think step by step…”时并不真在执行预设算法而是在概率空间里采样一条高置信路径。这条路径的稳定性严重依赖三个脆弱支点输入扰动敏感性同一段用户提问加个“请务必谨慎”或删个标点CoT路径可能完全分叉。我们做过测试对“如何重启服务器”这个问题原始输入触发的CoT是“1.确认服务状态→2.执行systemctl restart→3.验证端口”而仅在句末加个问号“如何重启服务器”CoT就变成“1.分析重启风险→2.检查磁盘空间→3.备份配置→4.执行重启”多出两步无关动作且第三步“备份配置”在当前权限下根本无法执行导致后续工具调用直接失败。工具调用反馈的语义失真Agent拿到工具返回的JSON数据后要把它“翻译”成自然语言再喂给LLM继续推理。这个翻译过程极易失真。比如某库存查询API返回{status:success,data:{item_id:A102,stock:0,last_update:2024-05-20T08:12:33Z}}Agent可能概括为“商品A102有货”因为模型更习惯将非零数字与“有”关联而忽略stock:0这个关键事实。这种失真不是token多寡的问题而是LLM对结构化数据的语义解析能力天然存在盲区。反思Reflection环节的自我欺骗很多Agent框架内置“反思”步骤让模型自己评估上一步是否合理。但实测发现当模型生成了错误结论后它的反思往往不是纠错而是“合理化”——用更华丽的语言为错误找借口。例如把“调用错误API”反思成“为获取更全面信息主动扩展查询维度”。这种自我辩护机制让Agent在错误道路上越走越坚定且不留痕迹。提示不要迷信CoT的“可解释性”。它提供的是一条叙事路径而非执行轨迹。真正可靠的推理链路必须强制插入可观测锚点——比如要求每步推理必须引用具体输入字段、工具返回的原始key、或外部知识库的精确段落ID让“思考”有迹可循而非任由模型自由发挥。2.2 工具调用的“幻觉接口”当Agent坚信某个API存在而它根本不存在这是最让后端工程师抓狂的场景Agent在规划阶段信心满满地写出“调用/api/v2/inventory/check_stock获取实时库存”然后执行器报错404。问题来了——这个API从未在工具描述文档里出现过。它是怎么“想出来”的根源在于工具描述Tool Description的表述模糊性与LLM的过度泛化倾向之间的致命碰撞。我们给Agent的工具列表里有/api/v1/inventory/get和/api/v1/warehouse/status两个接口。模型在训练中见过大量RESTful API命名模式于是基于“inventory”和“check”这两个词自行脑补出了一个更“精准”的路径。这不是bug是LLM语言建模能力的副产品——它太擅长补全了以至于补全到了现实世界之外。更麻烦的是“部分幻觉”Agent调用了一个真实存在的API但传了错误参数。比如知识库检索工具明确要求query字段为字符串而Agent传入了一个数组[error_code, E102]后端服务因类型校验失败返回500。日志里只看到“工具调用失败”但失败原因藏在HTTP body里而Agent的错误处理逻辑只检查HTTP status忽略body内容于是它把500当成“服务暂时不可用”转头去调用另一个完全不相关的备用工具彻底偏离主线。注意工具注册不是“把API文档扔给Agent就完事”。必须做三件事1工具描述用最小完备集禁用任何暗示性词汇如“类似接口”“推荐使用”2所有工具调用前强制进行参数Schema校验可用JSON Schema校验失败直接终止不交给LLM“猜”3工具返回的错误信息必须结构化提取关键字段如error_code,suggestion并原样注入下一步上下文避免LLM二次解读失真。2.3 状态管理的“幽灵变量”Agent记不住自己两分钟前干了什么传统程序的状态存在内存变量里Agent的状态呢散落在prompt的各个角落初始指令、历史对话、工具返回摘要、反思笔记……这些碎片化状态没有统一视图没有版本控制更没有原子性保证。典型症状是“状态污染”Agent在处理用户A的订单修改请求时中途被用户B的紧急咨询打断。等它切回来继续处理A的订单可能把B咨询中提到的“优先发货”策略错误应用到A的订单上导致A的订单被插队。这不是并发问题是状态隔离失效——因为两个会话共享了同一个“当前优先级”上下文槽位而Agent没有能力识别并隔离这个槽位。另一个常见问题是“状态衰减”Agent在长流程中会逐渐遗忘早期关键约束。比如一个旅行规划Agent第一步用户明确说“预算不超过5000元”到第五步选择酒店时它却推荐了6800元的套房。翻看中间步骤发现第三步工具返回的酒店列表里价格字段被摘要为“高端舒适型”原始数字被过滤掉了而LLM在后续推理中只记得“舒适型”忘了“预算”这个硬约束。我们曾尝试用外部数据库存状态但很快发现新问题每次工具调用前后都要读写DB延迟叠加一个简单查询变成300ms更糟的是如果DB写入成功但Agent进程崩溃状态就永久丢失下次唤醒时它“失忆”了却以为自己记得一切。实操心得轻量级Agent用带TTLTime-To-Live的内存状态缓存键名必须包含会话ID步骤序号如session_abc123_step4_budget避免跨会话污染中大型Agent必须引入状态机State Machine引擎每个状态转移需满足明确条件如“收到支付成功回调”且转移前强制校验前置状态有效性。别让LLM“凭感觉”管理状态那是给混沌留门。2.4 失败恢复的“假死循环”当Agent卡在错误里反复横跳最折磨人的不是Agent出错而是它出错后拒绝承认、拒绝求助、拒绝切换策略执着地在同一条死路上反复尝试。我们称之为“假死循环”。一个经典案例某金融Agent需要从PDF合同中提取“违约金比例”。它调用OCR工具得到文本但PDF扫描质量差关键数字被识别成乱码1,5%。Agent第一次解析失败进入反思“文本识别可能不准应增强OCR精度”。于是它调用“增强版OCR”工具其实是同一套引擎只是参数微调再次得到同样乱码。第二次失败反思“或许需结合上下文推断”于是它调用知识库查“常见违约金范围”得到“5%-15%”便自信地填入“10%”。整个过程耗时27秒token用量正常日志干净但结果完全错误。为什么它不直接说“我无法识别请提供清晰图片”因为它被初始prompt训导为“必须给出答案”而“无法识别”被视为失败违反了核心指令。它的恢复机制不是向上求助而是向下钻牛角尖——在现有工具集内无限试错。更隐蔽的是“优雅降级失效”框架预设了“主工具失败→备选工具→人工接管”三级恢复。但Agent在主工具失败后可能因CoT偏差直接跳到“人工接管”而跳过本该更高效的备选工具或者它调用备选工具时又犯了参数幻觉错误导致备选也失败最终才慢半拍地触发人工。关键洞察失败恢复不是靠增加更多工具或更长prompt而是靠定义清晰的失败信号。必须为每个工具调用设定可量化的成功阈值如OCR返回文本的置信度0.85或关键字段提取完整率100%低于阈值即视为失败立即触发预设恢复路径不给LLM“自我发挥”的机会。把“判断是否失败”的权力从LLM手里收回来。3. 真正该管什么一套可落地的Agent治理四象限框架既然token不是核心矛盾那我们该把精力投向哪里经过多个项目迭代我总结出一个“Agent治理四象限”框架它不追求理论完美只关注现场能否快速定位、快速修复、快速预防。每个象限对应一个可测量、可干预、可审计的治理抓手。3.1 可观测性象限让Agent的“思考”和“动作”变成可追踪的流水线没有可观测性一切治理都是盲人摸象。但Agent的可观测性不能照搬传统APM应用性能监控那一套——它不是测QPS或P99延迟而是测“决策质量”和“行为意图”。我们落地的核心方案是三层埋点日志L1 原始事件层记录每一次LLM调用的完整输入prompt、输出response、耗时、token数、模型版本。这是基础但价值有限因为response是文本难以直接分析。L2 语义解析层在L1基础上用轻量级规则引擎非LLM做实时解析。例如检测CoT中是否包含明确的工具调用指令匹配call.*?tool_name正则提取response中的结构化字段如{action: search_knowledge, query: ...}校验工具调用参数是否符合预设Schema用JSON Schema validator。 这一层产出结构化事件流如{event_type: tool_call_planned, tool: inventory_check, params_valid: true}。L3 业务意图层将L2事件流映射到业务目标上。例如定义“订单处理成功”的意图链为[user_query_order] → [extract_order_id] → [check_inventory] → [confirm_payment] → [generate_shipping_label]。每完成一个环节打一个意图标记。当某次会话缺失confirm_payment标记但出现了generate_shipping_label系统立刻告警——意图链断裂说明Agent绕过了风控环节。这套方案的好处是不依赖LLM自身解释用确定性规则锚定不确定性行为。运维人员看仪表盘不再是一堆文本日志而是清晰的意图完成率、工具调用成功率、CoT路径分布热力图。上周我们靠这个发现83%的失败会话都卡在check_inventory到confirm_payment之间进一步排查定位到是库存服务偶发503而Agent的重试逻辑没覆盖这个状态码——问题瞬间聚焦。实操细节L2解析引擎我们用Python jsonpath-ng 自定义正则部署为独立服务延迟5ms。L3意图定义用YAML配置支持热更新业务方改个配置就能新增监控维度不用动代码。3.2 可控性象限用“硬闸门”代替“软劝导”把失控扼杀在摇篮可控性就是确保Agent在任何时候都只能在预设的安全区内行动。这需要放弃“靠prompt约束”的幻想转向工程化的“硬性围栏”。我们实施了三个层级的硬闸门输入闸门Input Gate所有用户输入在进入Agent前必须通过规则引擎清洗。例如过滤含sudo、rm -rf、format等高危词的指令哪怕用户只是开玩笑对数字类查询如“查余额”强制添加单位校验balance 0 and balance 10000000防注入对多轮对话检测是否出现“忽略之前指令”“重置上下文”等规避性话术触发人工审核。动作闸门Action GateAgent规划出的每一个动作在执行前必须通过闸门校验。校验项包括工具白名单只允许调用已注册且状态为active的工具参数沙盒所有参数值必须在预设范围内如timeout必须在1000-30000ms频率熔断同一工具在60秒内调用超过5次自动拒绝防止死循环。输出闸门Output GateAgent生成的最终回复在返回用户前做最后一道过滤敏感信息脱敏自动识别并替换身份证号、手机号、银行卡号用正则上下文判断避免误伤“13812345678”这种纯数字文本事实核查对涉及数字、日期、专有名词的陈述调用知识库做快速比对如“违约金10%” vs 合同原文“5%”不一致则插入澄清说明语气校准检测是否出现“绝对化”表述“肯定”“必然”“100%”强制替换为“通常”“一般”“根据当前信息”。这三层闸门全部用同步方式嵌入请求链路总延迟增加15ms。效果立竿见影上线后高危指令执行归零工具调用失败率下降62%用户投诉中“回答不准确”类下降78%。关键是它不依赖LLM的理解能力是纯粹的工程防御。3.3 可恢复性象限设计“有尊严的失败”让Agent知道何时该喊停好的Agent不是永不犯错而是犯错后能体面退场并把接力棒稳稳交到该交的人手上。这需要一套清晰的“失败尊严协议”。我们的协议包含三个核心原则失败必须可分类不可模糊Agent的每一次失败必须打上明确标签。我们定义了五类失败INPUT_INVALID用户输入无法解析TOOL_UNAVAILABLE工具服务不可达TOOL_FAILED工具调用失败含明确错误码LOGIC_INCONSISTENTCoT与工具返回矛盾如库存为0却建议发货CONFIDENCE_LOWLLM自评置信度0.7。 每一类对应不同的恢复策略和上报路径。恢复策略必须可执行不可协商针对每一类失败预设动作INPUT_INVALID→ 返回结构化错误模板“我没理解您的意思请用‘我想查XX订单状态’这样的格式告诉我”TOOL_UNAVAILABLE→ 启动本地缓存降级如用昨日库存数据并发送告警LOGIC_INCONSISTENT→ 立即冻结当前会话生成“矛盾报告”含原始输入、CoT片段、工具返回、冲突点推送至人工审核队列CONFIDENCE_LOW→ 主动询问用户“关于XX问题我的把握不大您希望我A) 再试一次 B) 查其他资料 C) 转人工”。交接必须有凭证不可丢弃当触发人工介入Agent必须生成一份“交接包”包含完整会话历史带时间戳所有工具调用详情含原始请求/响应Agent的最终推理摘要用L2解析层提取的结构化摘要非自由文本当前状态快照如order_status: pending_payment。 这份交接包是人工快速接手的唯一依据避免重复询问用户。这套协议让失败从“灾难”变成了“例行维护”。客服团队反馈接手Agent转交的case平均处理时间从12分钟降到3.2分钟因为信息全、线索清、无歧义。3.4 可演进性象限让Agent的能力增长像软件升级一样可控Agent不是一次训练就一劳永逸的模型它的能力需要随业务变化持续进化。但盲目“喂数据”“调prompt”只会让系统越来越臃肿、越来越不可控。我们采用“版本化能力包”机制。每个Agent能力被封装为一个独立的、可版本化的模块例如knowledge_retrieval_v2.1负责知识库搜索v2.1修复了对表格内容的解析缺陷payment_validation_v1.3负责支付校验v1.3新增了对跨境支付手续费的计算error_recovery_v3.0负责失败恢复v3.0引入了基于用户历史偏好的恢复策略。这些模块的升级遵循严格的CI/CD流程测试先行每个新版本必须通过三类测试单元测试验证模块核心逻辑如payment_validation对amount100, fee_rate0.02是否返回total102集成测试在模拟环境中与上下游模块联调验证端到端流程A/B测试新版本与旧版本并行运行10%流量对比关键指标如意图完成率、用户满意度NPS。灰度发布通过率99.5%且A/B指标不劣于基线才进入灰度。灰度期持续24小时期间实时监控异常率。一键回滚任何时刻运维可点击按钮将指定模块回退到上一稳定版本无需重启服务。这套机制让我们在两周内安全上线了7个能力模块更新零生产事故。更重要的是它让“Agent变聪明了”这件事变得可衡量、可审计、可追溯——不再是玄学。4. 实操指南从零开始构建你的第一个“可管”Agent理论讲完现在来点实在的。下面是一个极简但完整的实操指南教你用主流开源工具LangChain LlamaIndex FastAPI从零搭建一个具备基础可观测性、可控性、可恢复性的Agent。全程不碰token优化专注“管得住”。4.1 环境准备与核心依赖安装我们选择Python 3.10环境依赖精简到最低必要pip install langchain0.1.16 llama-index0.10.27 fastapi0.110.0 uvicorn0.29.0 pydantic2.7.1 jsonpath-ng1.6.1关键点说明langchain0.1.16锁定此版本因其AgentExecutor的handle_parsing_errors参数稳定便于我们接管错误llama-index0.10.27此版本的VectorStoreIndex对中文分词支持较好且retriever接口清晰pydantic2.7.1用于定义强类型Schema是实现“动作闸门”参数校验的基础jsonpath-ng轻量级用于L2日志解析比用正则更可靠。注意不要用最新版LangChain其Runnable抽象层虽新但错误处理钩子不稳定容易绕过我们的闸门。老版本API虽略啰嗦但可控性高。4.2 定义你的第一个“硬闸门”输入清洗与意图识别创建gateways/input_gate.pyfrom pydantic import BaseModel, field_validator import re class UserQuery(BaseModel): text: str session_id: str field_validator(text) def validate_text(cls, v): # 闸门1过滤高危指令 dangerous_patterns [r\bsudo\b, r\brm\s-rf\b, r\bformat\b] for pattern in dangerous_patterns: if re.search(pattern, v, re.IGNORECASE): raise ValueError(f检测到高危指令: {pattern}) # 闸门2数字类查询单位校验示例 if 余额 in v or balance in v.lower(): # 简单规则不允许出现负数或超大数 numbers re.findall(r-?\d\.?\d*, v) for num in numbers: try: val float(num) if val 0 or val 10000000: raise ValueError(余额查询数值超出合理范围) except ValueError: pass # 非数字字符串跳过 # 闸门3规避性话术检测 evade_phrases [忽略之前, 重置上下文, 从头开始] for phrase in evade_phrases: if phrase in v: raise ValueError(f检测到规避性话术: {phrase}) return v # 使用示例 try: query UserQuery(text请帮我查一下账户余额谢谢, session_idsess_abc123) print(输入合法进入Agent流程) except ValueError as e: print(f输入被拦截: {e})这个UserQuery模型就是你的第一个输入闸门。它用Pydantic的field_validator在数据进入Agent前就完成三重过滤。任何不合规输入都会抛出ValueError你可以捕获它返回友好的错误提示而不会让脏数据污染Agent的思考。4.3 构建“可观测”Agent执行器三层日志埋点实战创建agents/observable_agent.pyimport logging from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from typing import Dict, Any, Optional import json from jsonpath_ng import parse from jsonpath_ng.ext import parse as ext_parse # 初始化日志 logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) class ObservableAgentExecutor(AgentExecutor): 重写AgentExecutor注入三层日志 def _run(self, inputs: Dict[str, Any], **kwargs: Any) - Dict[str, Any]: # L1: 记录原始调用 logger.info(f[L1] Agent start | session_id: {inputs.get(session_id, unknown)} | input_len: {len(str(inputs))}) # L2: 解析CoT意图简化版 try: # 尝试从prompt中提取工具调用意图 prompt self.agent.prompt.format_prompt(**inputs).to_string() # 粗略匹配寻找call 工具名 tool_calls [] for tool in self.tools: if fcall {tool.name} in prompt.lower() or f{tool.name}( in prompt: tool_calls.append(tool.name) if tool_calls: logger.info(f[L2] CoT intent detected | tools: {tool_calls}) except Exception as e: logger.warning(f[L2] CoT parsing failed: {e}) # 执行原逻辑 result super()._run(inputs, **kwargs) # L3: 业务意图标记示例订单查询 if 订单 in inputs.get(input, ) and status in str(result).lower(): logger.info(f[L3] Business intent achieved | order_status_query | session_id: {inputs.get(session_id)}) return result # 创建Agent省略prompt和tools定义聚焦日志逻辑 # agent create_tool_calling_agent(llm, tools, prompt) # executor ObservableAgentExecutor(agentagent, toolstools, verboseTrue)这段代码的关键在于ObservableAgentExecutor类。它继承了LangChain的AgentExecutor并在_run方法中插入了L1/L2/L3日志。L1是基础L2用简单规则解析CoT意图L3则根据业务关键词打标记。运行时你会在日志中看到清晰的三层事件方便后续用ELK或Grafana做可视化。4.4 实现“有尊严的失败”结构化错误处理与人工交接创建handlers/error_handler.pyfrom enum import Enum from pydantic import BaseModel from typing import List, Optional class FailureType(Enum): INPUT_INVALID INPUT_INVALID TOOL_UNAVAILABLE TOOL_UNAVAILABLE TOOL_FAILED TOOL_FAILED LOGIC_INCONSISTENT LOGIC_INCONSISTENT CONFIDENCE_LOW CONFIDENCE_LOW class FailureReport(BaseModel): type: FailureType message: str session_id: str timestamp: str # 关键交接凭证 context_snapshot: dict # 包含输入、历史、工具返回等 suggested_action: str # 如 转人工审核 或 重试工具X def handle_agent_failure(e: Exception, inputs: dict, tools_result: Optional[dict] None) - FailureReport: 集中处理Agent失败生成结构化报告 import datetime # 分类失败 if isinstance(e, ValueError) and 输入被拦截 in str(e): failure_type FailureType.INPUT_INVALID suggested 请用户提供更清晰的指令 elif Connection refused in str(e) or timeout in str(e).lower(): failure_type FailureType.TOOL_UNAVAILABLE suggested 启用本地缓存降级 elif 500 in str(e) or internal server error in str(e).lower(): failure_type FailureType.TOOL_FAILED suggested 检查工具服务状态 else: # 默认归为逻辑不一致 failure_type FailureType.LOGIC_INCONSISTENT suggested 生成矛盾报告转人工审核 # 构建交接包 context { user_input: inputs.get(input, ), history: inputs.get(chat_history, []), tool_result: tools_result or {} } return FailureReport( typefailure_type, messagestr(e), session_idinputs.get(session_id, unknown), timestampdatetime.datetime.now().isoformat(), context_snapshotcontext, suggested_actionsuggested ) # 使用示例 try: # ... agent.run(...) pass except Exception as e: report handle_agent_failure(e, inputs{input: 查订单, session_id: sess_xyz}) print(f生成交接报告: {report.json()}) # 此处可将report发往消息队列触发人工审核流程这个handle_agent_failure函数就是你的“失败尊严协议”执行器。它把各种Exception映射到预定义的FailureType并生成包含完整上下文的FailureReport。这份报告就是Agent向人类求助时递上的那张清晰、完整、无可辩驳的“求助卡”。5. 那些没人告诉你的坑来自真实战场的避坑清单纸上谈兵终觉浅绝知此事要躬行。上面所有方案都源于我们踩过的坑。这里列出5个最痛、最常被忽略的实战陷阱附上血泪解决方案。5.1 坑一LLM的“自信幻觉”会污染所有日志你以为加了日志就能看清Agent在想什么错。LLM在生成CoT时会把“猜测”包装成“事实”。比如它可能写“根据知识库第3.2节违约金为10%”而实际上知识库根本没有第3.2节或者该节写的是5%。这个虚假引用会随着日志一起被记录让你误以为问题出在知识库而实际是LLM在编造。避坑方案在L2日志解析层强制要求所有“知识库引用”必须匹配真实存在的段落ID。我们用llama-index的Node对象自带的node_id在检索时就将其注入prompt。Agent若引用不存在的IDL2解析器直接标记为REFERENCE_INVALID并告警。永远不要相信LLM对自身引用的诚实性要用确定性ID来锚定。5.2 坑二工具调用的“成功”不等于“有效”工具返回HTTP 200不代表业务成功。比如库存查询API返回{code: 200, msg: success, data: null}这是成功的HTTP响应但data为空业务上就是失败。很多Agent框架只检查status code导致它把null当有效数据继续处理最终输出“库存充足”。避坑方案为每个工具定义success_condition。例如库存工具的成功条件是response[data] is not None and response[data][stock] 0。这个条件在工具调用后、结果注入LLM前由闸门引擎强制校验。不满足直接视为TOOL_FAILED不给LLM任何“发挥”机会。HTTP状态码是网络层的事业务层的成功必须由业务规则定义。5.3 坑三多Agent协同时的“状态雪崩”当你有多个Agent如客服Agent、订单Agent、物流Agent协同工作时一个Agent的状态错误会像多米诺骨牌一样引发连锁崩溃。比如客服Agent把用户地址记错订单Agent就发错货物流Agent再按错地址派车——错误被层层放大。避坑方案实施“状态公证人”State Notary模式。所有Agent的状态变更不直接写入共享存储而是先向一个中央StateNotary服务发起“状态变更申请”附带变更理由和证据如用户确认的截图。StateNotary根据预设规则如“地址变更需用户二次确认”审批审批通过后才写入全局状态。让状态变更成为受控的、可审计的事务而非各Agent的自由发挥。5.4 坑四Prompt越写越长Agent越管越难为了“约束”Agent很多人不断往prompt里加规则“不要编造”“必须引用原文”“遇到不确定就问”……结果prompt长达2000tokenAgent一半算力在解析自己的说明书另一半才干活且规则越多冲突越多Agent越困惑。避坑方案Prompt只做三件事1定义角色你是谁2定义终极目标你要达成
阅读完成 · 觉得有帮助?
咨询建站