热爱技术,追求卓越
不断求索,精益求精

我把智能体接进业务系统,才发现最难的不是「接」,是「谁都别想自己造一套记忆」

中秋这几天没干别的,就在想一件事:怎么让智能体真正进到业务系统里干活。

不是那种「在旁边开个聊天窗口,用户有问题复制过去问一句」的玩法。我要的是:用户在商城客服里说一句「我那个订单到哪了」,接下来的事——查订单、看物流、需要时推一张订单卡片、答不上来时转人工——全部由智能体接住,而人工客服随时能接管过去。

方向定下来的时候我觉得没那么难。真开始往细里走,才发现难点根本不在「怎么调通一个接口」。

难在这件事的本质:一边是一个无状态的模型调用,一边是一个有状态、有记忆、有工具、会自己规划好几步的智能体,你要把它们缝在一起。

这篇写我在五个位置上的判断。每个位置我都写了「我最后怎么定的」,以及「那个看起来更顺的选择,为什么我放弃了」。你要是也在做同样的事,这五个坑大概率一个都躲不掉。

先看一个具体的场景,后面所有讨论都围着它转

用户在客服会话里打字:

「我上周买的那件外套,还没发货,能帮我看看吗?」

理想情况下,这条消息应该走完这一串:

① 业务系统收到消息,落库;

② 判断这个会话当前是「智能体接待」还是「人工接待」;

③ 是智能体接待 → 调智能体,把这段会话历史一并给它;

④ 智能体理解意图 → 调业务系统的订单接口 → 拿到订单 → 调物流接口 → 拿到状态;

⑤ 组织答复:一句话 + 一张订单卡片(用户可以直接点进去);

⑥ 业务系统把这个回复按消息类型落库、推给用户;

⑦ 整个过程如果触发「要转人工」,状态由业务系统改,智能体只负责说不说得出。

七步里,真正难的是 ③⑦ 和 ④。下面一个一个说。

接缝一:谁当底座?我选了业务系统

第一个要拍板的问题:这套东西,是业务系统当主平台、智能体当被它调用的能力,还是反过来,智能体当主平台、业务系统当它的一个数据源?

两个方向都成立,甚至从「技术含量」上看,反过来那个更性感——智能体那边有现成的循环、工具、记忆、多渠道,让它当中枢,业务系统只是它调用的一个数据源。

我最后选了业务系统当底座,智能体当被驱动的服务。三个理由:

第一,只有一个业务系统。 反过来那个方案的价值在于「中立中枢」——当你有七八个系统要整合,让智能体站中间统一调度是划算的。但我就一个业务系统,所谓「各个业务系统」其实是它内部的各个业务模块。为了一个不存在的场景付出中立成本,不划算。

第二,治理必须有唯一主权方。 身份、权限、多租户、审计、业务数据、事务,这些东西业务系统这边全是成熟的;智能体那边基本是空的。你要让它当底座,就得在那边重新造一遍治理——这不是工作量的问题,是「造出来也不如原来那套稳」的问题。

第三,客服通道本来就在业务系统里。 会话表、消息表、推送通道(长连接)都是现成的,还带未读计数、置顶、软删除这些细节。智能体那边虽然内置十几个渠道,但客服这条线在业务系统里更「亲」。

选完之后我给自己画了一条红线,这条红线是整篇文章里我最想强调的:

业务系统当底座 ≠ 把智能体降级成一个「会调工具的模型」。

这是我见过最容易滑进去的坑。因为业务系统里通常已经有一层模型接入能力,你把智能体的地址往那一填,好像就「接上了」。但那样接的是智能体的一个兼容接口,它只取你发过去的最后一条消息,每次当新会话处理。结果就是:智能体那边最值钱的东西——循环、工具编排、记忆、子任务——一个都没用上,你还以为自己接了个智能体,其实只是接了个模型。

正确的边界是:业务系统负责调用和治理,智能体保留完整的自主循环(理解 → 规划 → 调工具 → 多步执行)。它只是「由业务系统发起调用」,不是「被降级成无状态模型」。

职责我最后是按这张表切的:

能力 归谁
身份、权限、多租户、审计、业务数据与事务 业务系统
客服会话与推送通道 业务系统
调用编排入口(谁发起智能体回合) 业务系统
智能体循环、工具编排、长期记忆、多智能体 智能体
会话「记忆」的读取方式 业务系统给原文,智能体不自己存

最后一行的由来,是第二个接缝,也是我觉得整篇最反直觉的一条。

接缝二:会话历史到底该听谁的?

这个问题我一开始没意识到是个问题,直到我把它写进设计文档才发现自己踩了两个假设。

假设一:智能体自己会记住聊天。 它确实有会话存档,按「智能体 + 会话」缓存。但这个「会话」是它自己的会话概念,不是业务系统里那个客服会话。两边一旦各自记账,就一定会有对不上的那天。

假设二:人工接管之后,智能体自然知道人工说了什么。 不会。智能体只处理「别人发给它的内容」,它没有能力主动去读业务系统里的消息表。如果在人工接管的这半小时里它什么都没收到,等交回给 AI 时,它对这半小时是失忆的。

那么正确姿势是什么?我最后定的是:

客服会话原文只存一份,存在业务系统里。智能体不做历史真相源,它每一轮接收「带说话人标注的会话历史」,无状态地处理这一次请求。

为什么这么定,理由很实在:

业务系统的消息表天然能区分三方。 它本来就有「发送方是谁、什么类型」的字段,能区分会员、管理员(人工客服)。我只需要再补一个标记,把「AI 发出的」和「人发出的」也区分开。数据齐了。

智能体这边本来就有「外部历史注入」的口子。 它的对话入口是支持你从外部传一段历史进来的。这不算什么需要改造的功能——它的设计里本来就考虑过「会话存在外面」这种情况。

同步方式我建议选「每轮全量带过去」而不是「实时增量推送」。 两种都能用,但当业务系统已经是唯一真相源的时候,每轮把最近若干轮带过去是最省心的——不会出现某一轮推送丢了、两边悄悄不一致的事。增量推送的复杂度,是留给「智能体需要随时知道业务系统里发生了什么」这种场景的,而我这里并不需要。

然后是一个很关键的设计:人工接管期间怎么办。

我选的是「只记不回」:人工接管时,用户的每一条消息、人工客服的每一条回复,业务系统都继续同步给智能体,但不触发它回复。

这样做的直接好处是:等交回给 AI 时,它不需要补历史,因为它一直在看。间接好处更值钱——人工是怎么回答的,是一份高质量的监督样本。 我完全可以约定一个机制,把那些被人工处理得很好的问答沉淀下来,让 AI 逐步学会这些情况自己就能接,而不是每次都往上报。

我当时在文档里写了一句给自己的批注,这里也抄出来:转人工是一件「失败」,但人工的每次回复都是一次「教学」。 一个只会转人工、却学不会的客服系统,等于是一个永远长不大的实习生。

接缝三:知识库该由谁检索?这决定了 AI 会不会一本正经地瞎答

业务系统里有自己的知识库:文档切片、向量检索、重排,一整套。智能体那边也有自己的知识库:一堆 markdown 文件,配上索引和检索工具。

两套知识库,就必须决定「业务相关的智能体读哪个」。我在文档里看到过一句很诱人的话,大意是:智能体会在回答前主动检索。

这句话的问题在于,它是个软约束。它写的是「必须在回答前检索」,但执行的是模型。模型觉得「这个问题我会」,就不检索了;模型检索了一次没找到,可能也就这么答了。

客服场景里,这等于把「召回有没有做」赌在模型的判断上。而漏召回的后果不是「答得差一点」,是一本正经地答错——比如把退货政策记反了,或者把不该承诺的时效承诺出去。

所以我最后定的是一个混合方案:

层 做法 为什么
主:业务系统侧预先检索 业务系统在发起智能体调用之前,先把最相关的若干片段检索出来,作为上下文一起传过去 客服场景召回必须可靠,不能赌模型记得调工具;而且业务系统的检索能力现成,带租户和权限
辅:智能体侧检索工具 给智能体一个工具,注入的片段不够时它可以主动换关键词再挖 保留智能体的自主性,补召回。实现成本很低——照着它本来就有的检索工具写一个,把内部检索换成调业务系统的检索接口

为什么不选「纯靠智能体主动调工具」:用户直接提问、你必须答对的场景,把「查不查」交给模型判断,风险太高。

为什么不选「纯每轮预检索」:无关的轮次也塞片段,浪费上下文和延迟;而且智能体想深挖的时候没有手段。

为什么把预检索放在业务系统侧而不是智能体侧:业务系统是调用发起方,检索能力也有,而且检索必须带上租户和用户上下文(防越权)——放在业务系统侧,这些天然就是齐的,也不用在智能体的每轮流程里加钩子。改动更少,隔离更好。

顺便定了一条不做的事:不做双向同步。 业务无关的智能体(通用助手、写东西的)用自己本地的知识库;业务相关的智能体只读业务系统的知识库,不写回。两套知识库混用的下场,是同一条政策有两个版本,然后你永远不知道 AI 用的是哪一版。

接缝四:业务数据怎么给智能体用?三种接法我选了这个

智能体要能查订单、查物流、查会员。业务系统这边是一堆 REST 接口。中间这层怎么接,有三种做法:

做法 是什么 结构化/可靠性 业务模块多了之后
协议化工具 业界有一套标准协议,让大模型直接调用外部工具,带明确参数定义 高。模型直接按定义调用,不靠猜 好。接口能自动暴露成工具
技能 写一份说明文档告诉模型「什么时候用、怎么用」,配一个脚本,模型读文档后去跑脚本 中。中间隔了一层「读文档 + 执行命令」,容易走偏 差。每加一个能力就要手写一份
自定义工具 直接写代码扩展智能体 高。但要动它的源码 中。每个能力都要写代码

我最后定的是:数据查询走协议化工具,流程型能力(比如「处理一次退款」这种多步业务)走技能。

理由:查订单查物流这种事,数据是结构化的,让模型按明确的参数定义去调用,比让它读一份说明文档再去跑脚本,可靠得多、也省 token。 而我这边业务模块只会越来越多,让 REST 接口自动暴露成工具,比逐个手写技能的可扩展性好太多。

但这里有个前提成本要说清楚:业务系统目前只是一堆 REST 接口,它不会自动变成协议化工具。 你得在中间加一层——要么在业务系统里按需自建一个工具服务端,要么放一个转换桥把接口自动转成工具。这一层是躲不掉的工作量,我把它排在「链路先跑通」之后、作为第二阶段。

还有一个细节值得单独提,因为它差点让我做错判断:工具能不能按智能体隔离?

我一开始以为不能——共享配置下的工具,所有智能体都能看到。后来仔细看才发现在它的工作目录设计里,某个智能体如果自己有配置文件,就改用自己那份,而不是叠加在共享配置上。

所以可以隔离,但代价是「覆盖而不是叠加」:一旦这个智能体用了自己的配置,它就看不到共享配置里的其他工具了,你得把需要的全写进它自己那份。

这直接决定了我的做法:给专属客服智能体配一份自己的工具配置(含业务系统工具),其他智能体继续用共享配置(不含业务系统工具)。 这样业务能力的暴露范围是收着来的,而不是全平台放开。

接缝五:AI 和人工怎么交接?状态必须由业务系统改

这是我最花心思的一块,因为它直接决定用户体验:用户不会在乎你后台是怎么分层的,他只在乎「我到底在跟谁说话,它是不是在敷衍我」。

我先定了一条原则,这条原则是整块设计的灵魂:

状态判定和状态流转,由业务系统确定性地执行。智能体只负责输出「建议转人工」这个信号,绝不直接改状态。

为什么这么较真?因为如果让智能体直接决定「转不转人工」,你就把控制权交给了一个概率系统。它可能因为一次语气不好就转,也可能在明显该转的时候硬撑。而转人工是业务动作——它要落库、要广播给用户和客服两端、要进待接入列表——这种事情必须有一个可审计、可复现的执行者。

状态我设了三个:AI 接待 / 人工接待 / 排队中。第三个是必要的,因为「转人工时没有客服在线」是个真实且高频的情况,不能让它静默地卡在那里。

转人工的触发我按可靠性排了序:

优先级 触发条件 谁来判定
1 用户显式要求:转人工、找真人、要投诉 业务系统的规则(关键词 + 意图)
2 规则命中:敏感词、退款纠纷、法律、辱骂、高危 业务系统的配置化规则,不经模型
3 AI 自评答不上:连续几次知识库没命中 智能体输出一个结构化信号,业务系统决定转不转
4 人工主动点「接管」 业务系统

注意第 3 行的分工:智能体返回的不是「我要转人工」这个动作,而是一个结构化的信号(大致是「我没把握,原因是知识库没命中,把握度大概多少」)。业务系统收到这个信号之后,再按自己的策略决定转不转——比如可以要求「连续命中几次」才真的转,避免 AI 答两句就想叫人。

这一行的设计价值在于:智能体提供判断,业务系统保留决策。 两者的职责是清晰的,将来出问题也查得到是谁的判断。

反过来,人工转回 AI 的触发有三种:人工自己点、人工超时没说话(我设的是三十分钟,可配)、客服下班或离线。第三种要在「转给另一个在线客服」和「转回 AI」之间做选择——有在线客服就转派,没有才回归。

还有一条最小但我觉得很重要的细节:状态一变,必须落库并广播给两端。 用户端要看到「已接入人工客服」「已恢复智能助手」这样的系统提示,客服端要实时看到新会话进入待接入列表。状态切换不能是静默的——用户不知道对面换了个人,体验就崩了。

顺带解决的:智能体怎么「推」出富消息,而不是一段干巴巴的文字

上面那个场景里,第 ⑤ 步是「一句话 + 一张订单卡片」。这件事其实专门值得写一段,因为它是「智能体」和「聊天机器人」的分水岭之一。

好消息是,业务系统的客服消息类型里本来就内置了商品消息和订单消息,消息内容字段是自由字符串。也就是说,卡片不需要扩展任何枚举——把 JSON 塞进内容字段就行。

坏消息是,正因为「只存不校验」,卡片字段完全是一份前后端口头契约。服务端不会拦你,前端按什么渲染全靠约。这种「静默错渲染」是最难查的一类 bug:不报错,只是显示得很奇怪。

所以我的做法是:卡片结构先定一份书面版本——订单卡大致带订单号、状态、商品明细、金额、创建时间、跳转地址,金额统一用「分」(跟商城保持一致,前端自己格式化)。

智能体这边怎么产出卡片?它要能输出纯文本之外的结构化块,而不是把 JSON 当文字吐给用户。它的工具执行结果里有专门给「人类读者」准备的可读字段,流式事件里也有结构化的块——我在这上面约了一个「卡片事件」,标注类型 + 载荷。落到业务系统侧再做一层映射:文字 → 文本消息类型,商品卡 → 商品消息类型,订单卡 → 订单消息类型,然后走上原有的发送路径落库、推送。

最后一条安全注意:卡片的载荷是智能体生成的,业务系统落库前必须做字段白名单过滤,别让它往里塞前端没预期过的字段。卡片数据本身来自前面的业务工具(查商品、查订单),AI 只决定「推哪一张」。

分阶段,别一口气全上

这五个接缝想清楚之后,我把它拆成了四个阶段,按「什么时候能看到东西」排:

阶段 内容 量级
打通链路 客服消息 → 智能体 → 回复能跑通,会话映射 + 人工接管状态机的最小版 周级
接入知识 智能体侧加一个检索工具,只读业务系统的知识库 天级
业务取数 业务接口接成工具,先只读、先只接两三个模块(会员/订单/物流) 周级
治理与收口 多租户隔离、审计、权限白名单、业务端点收敛成一个「业务网关」 周~月级

第二阶段我特意标了「先最小」:不要一上来就把所有业务接口全量暴露成工具。工具的暴露范围越大,出问题的面就越大。先从两三个只读模块开始,验证完再扩。

三件我写在最前面的底线

第一,历史真相源只能有一个。 这条上面说过了,但它值得再强调一次——因为「两边都存一份、看着挺保险」是人的本能反应,而它恰恰是后面所有不一致的根源。定死一边,另一边无状态接收。

第二,智能体反调业务接口时,必须带上租户和用户上下文。 这不是「优化」,是合规底线。业务系统的数据权限是按租户和归属人切的,智能体用一个内部服务账号去调,如果不带着上下文,就等于开了一个能跨租户读数据的洞。

第三,别小看智能体自带工具的攻击面。 一个完整的智能体是有能力执行命令、读写文件的,而它的权限模式是参数级的,不是沙箱级的——它自己的文档里就写着「要硬边界请上容器」。接进业务系统意味着它会接触到真实数据,所以:只读模式起步、容器隔离、独立 token,一个都不能省。

说在最后

回头看,这件事真正难的地方,全都不在「怎么把两个系统连起来」。

而在于:一个有状态的智能体,和一个治理成熟的业务系统放在一起,中间所有「看起来两边都行」的地方,你都必须明确指定一个主权方。

会话听谁的、知识库谁检索、状态谁改、数据谁能看——每一个含糊过去的地方,将来都会变成一个查不清、复现不了的线上问题。

把它当一次普通的接口对接,你会收获一个「会聊天的客服」。

把它当一次职责边界的重划,你才可能收获一个真的能替你干活的同事。

赞(0)
未经允许不得转载:LoveCTO-技术天天练,程序员的 AI 实战笔记 » 我把智能体接进业务系统,才发现最难的不是「接」,是「谁都别想自己造一套记忆」

热爱技术 追求卓越 精益求精

登录

找回密码

注册