FIELD NOTES / 知识笔记
我们有块 B2B 采购的业务,做 Agent 时亲手踩过的六个坑
今年 618 前一周,我们团队在 B2B 采购线接的 AI 服务底座出了件事。一份框架协议合同,Agent 生成报价时把阶梯促销价误当合同价带了出去,客户采购员比价时发现差了 8.7 万,直接截图甩进对接群。那天晚上我带着两个同事回滚数据到凌晨三点。
后来复盘,根因是模型在价格字段上把促销权重拉得偏高,而当时 Agent 被允许直接落字段。这种事在大模型应用里根本躲不掉,关键是你有没有把它钉死在生产链路外面。
先交代下业务背景。我们手上有块 B2B 采购的 AI 业务,给一头部电商平台的 B2B 业务线做统一 AI 服务底座,同时接 11 个行业场域 的智能问答、导购和清单选品。线上跑着 5.2 万 条 SSE 长连接、日均 210 万 次调用,架构是接入、意图、编排、适配四层,接入层做鉴权和灰度,目标是和商城核心系统 0 耦合,新场景接入从天级压到小时级。意图层我们还做了模型配置化切换,深度思考、联网搜索、轻量降级随时切。新模型和新场域我们都走灰度,先放 5% 流量看评测和告警,没问题再全量。
第一个跟头,Agent 的非确定性是生产系统最大的敌人。B2B 场景里合同、金额、库存都是硬约束,错一个字就是客诉甚至纠纷。我们一开始图省事让 Agent 直接落字段,badcase 率 23%,最离谱的就是上面那桩 8.7 万的差价。后来改成 结构化草稿加人工确认闸门:Agent 只出建议单,我们把动作按风险分成三档,金额、合同、库存、对外发送这类高敏感动作必须人点确认才放行,查价、查进度这类只读动作才放给自动执行;金额类我们还在后端加了二次兜底校验,把模型输出和主数据里的合同价再比一遍。还有次 Agent 把 A 客户的专属协议价推给了 B 客户,根因是 prompt 拼接时两个客户的上下文混在了一起。
我们后来给每次推理都加 tenant_id 强绑定,prompt 拼接按 tenant 隔离,确认环节前端也渲染成可编辑表单,确认按钮是硬拦截,不点不能往下走,谁确认谁留痕。三档怎么划不是拍脑袋,我们按历史 badcase 反推,金额类出错客诉最重所以一律人工确认,查价查进度出错最多误导所以放开自动。这么一改 badcase 直接压到 4%。高风险业务里,把 Agent 当协作者而非执行者,这条线我们踩过一次就有记性了。
RAG 这关,真不是接个向量库就完事。知识库有 200 万 切片,刚上线召回准确率只有 62%,业务方天天投诉答非所问。我拉了一周日志,发现 70% 的错误集中在长尾非标件,问题出在 embedding 模型对 五金件牢固度 这类专业词区分度差,向量空间里它们挤在一起。光换模型不够,我们动了三处:切分上按条款粒度切,把品类、适用客户、生效日期这类元信息前置到每段开头,检索时先过元数据过滤再向量召回;切片长度压到 512 token 左右,太长稀释相关度,太短丢上下文;检索上先做 query 意图归一,把口语化描述映射到标准字段,再用向量加 BM25 的混合检索(RRF 融合),BM25 专门补精确词匹配;再叠加一层 BGE 重排,把最相关的切片顶到上下文窗口前部。重排模型试了几个,几番对比留了 BGE,因它对中文长尾术语排序更稳。
向量召回我们落地在 Milvus,召回和重排拆成两个独立服务,重排那块单独留了弹性扩容,大促峰值不至于把整条检索链路拖垮。准确率拉到 89%。但 89% 只是召回准确率,上下文窗口有限,我们按相关度加时效性排序截断,把最新合同价顶到最前,避免旧价覆盖新价;知识库也不是静态的,合同价天天变,变动切片当天增量生效,不全量重建。BM25 权重没调好时把支架和手机支架全召回,后来用 RRF 做倒数排名融合,比直接加权稳。RAG 的瓶颈从来不在检索,在召回后的排序和上下文裁剪,这块偷不得懒。B2B 知识还涉密,不同客户的合同价、协议价不能串,我们给每个租户单独建索引和权限边界,检索结果强隔离。
成本和可靠性这关更隐蔽,多智能体在生产里的失败率一度冲到 60% 多。一条复杂采购审批链路,Agent 平均要调 14 次 工具,token 消耗是单模型的 4 倍 还不止。有次大促预热没设预算熔断,单日 token 烧了 100 多亿,账单出来我们对着这个数看了好一会儿,才意识到熔断不能省。更坑的是子 Agent 一旦陷入循环,会反复调同一个工具把 token 瞬间打爆。有回一个子 Agent 查库存分页参数传错,反复重试十几轮才被超时兜住,那一单烧了平时上百单的量。后来我们上了预算熔断加路由层:意图层先判断问题复杂度,高频 FAQ 走 7B 小模型,只有涉及多步编排才升 70B 以上,单 query 成本差了一个数量级;
再给每个子 Agent 加步数上限和超时,月度 token 从 1800 亿 压到 1200 亿,失败率也降到 5% 以内。编排方式我们也换过,最早串行把结果一级级往下传,链路一长中段就容易丢;后来改成共享黑板,每个子 Agent 只读自己关心的字段。路由和调度是我们自研的,没直接套 LangGraph 这类框架,因为要把预算熔断和 checkpoint 续跑嵌进调度里,现成框架的默认重试太重、还爱重跑整条链路,token 直接翻倍,我们改成只重试失败的那一个子任务,上下文从 checkpoint 续。
路由判错也有代价,有回把多步复杂问题误判成 FAQ 走了小模型答非所问,我们加了置信度阈值,低于就强制升档。多智能体不是银弹,是成本放大器,预算管不住就先别上。
长任务这块必须上状态机,不能指望一次对话跑完。B2B 采购从寻源到结算跨好几天,一份合同拆成 3 个交付批次、12 个零件。我们用嵌入数组加局部状态机,把每个子任务的状态单独管起来,每一步都落时间戳和状态字段。状态我们用嵌入数组存进父文档,读写一次拿全,几十个零件的粒度刚好,不用拆表 join。上线第二周真出过事,一家供应商在第三步断网,刷新后状态机从在途状态续上,数据没丢。平时更好用:跟单员在一个工作台就能看全,批次 A 的金属支架已过验待发、批次 B 的彩盒还在生产、批次 C 的塑料卡扣上次质检没过正在整改,不用再翻十几个微信群对账。
Agent 的长期记忆不该压在上下文窗口里,得靠持久化状态。我们也评估过工作流引擎,但各家客户流转规则略有不同,硬编码改起来慢,状态机加配置化反而灵活。每个 part 除了状态还存了操作人、时间和凭证,比如验货照的 file_id,验货不通过就按状态机定义的回流路径自动通知供应商整改,整改完再走一遍。点开任意批次都能拉出完整时间线:谁、什么时间、从什么状态到什么状态、带了什么凭证。这套机制还顺带让我们能灰度,先给一个场域放量跑稳再铺开。
还有件事我现在信了,评测和可观测性是能不能上生产的分水岭。上线前我们攒了 5000 条 真实业务 query 的评测集,覆盖各场域的高频问题,指标盯命中率、合规率和格式正确率三件,每条都标了标准答案和合规红线。
badcase 标准我们也写成了文档:凡涉及金额偏差、合规表述、格式错误一律算 badcase,口径模糊的由两人复核。新模型要过 95% 命中率才准放量,我们每周跑一轮评测做回归,新模型上来先过评测集再放量。全链路用 tracing 埋 trace_id,像查微服务一样查 Agent。
trace 里我们记了每一步的模型版本、耗时、工具调用和花费,哪步变慢、哪个工具报错看面板就知道。第一次靠 trace 定位一个 意图识别把退货误判成换货 的 case 花了 4 小时,后来有了评测集 5 分钟就能复现。有次小版本更新把退货和换货口径弄混,评测集当场红了,拦在放量前,没让用户踩到。没有评测飞轮的 Agent,上线基本等于裸奔。今年阿里云也在讲可观测性加评估飞轮,字节腾讯阿里在 Agent 平台也把评测当一等公民,我们是踩了不少坑才真正服气。评测集不是随便攒的,我们从真实对话日志按场域和错误类型分层抽样,badcase 的标准答案还人工校过防误杀。
打分上命中率用 LLM 当裁判比对标准答案,合规率走规则校验,格式走 schema 校验。线上给 badcase 率、P99 延迟、单 query 成本设了告警线,超了自动通知。
说回选型,今年真正让我们团队眼前一亮的是 MCP 协议。之前每接一个商城能力,查库存、拉合同、推工单,都要写一套适配代码,11 个场域就是 11 份重复的 glue,改一处要同步十几处。MCP 把工具接入从定制开发变成标准配置,工具变成标准 server,Agent 按需挂载,新场域接入从改代码变成配清单。每个 MCP server 我们都配了最小权限,Agent 只能调被授权的那几个工具,防止越权动核心数据。
我们借着 MCP 把 Agent 和商城核心系统彻底解耦,0 耦合 上线到现在没出过一次故障。之前没 MCP 时吃过亏,商城改一次接口我们要同步改 11 处适配,漏了一处线上报了一周错才查到。标准刚起来也有坑,有些 SDK 不稳,我们给每个 server 做了本地缓存和降级,挂了自动走兜底逻辑,不影响主链路。
2026 被叫 Agent 规模化落地元年,Gartner 预测年底四成企业应用会集成 Agent,这方向的机会才刚起步。