从1到10个智能体:企业AI协同的混乱、翻车与EMOOSearch解法
2. 从1到10那些智能体集体上岗后我才意识到的问题先说个背景。我所在的公司是个中等规模的B2B客户运营团队日常要处理客户咨询、数据分析、合同初筛、文案生成、内部流程提醒等一堆琐碎事。去年我们陆续接入了不同供应商的智能体最开始是客服问答机器人后来是数据分析助手、合同审阅助理、日报生成器……一年不到大大小小的智能体凑到了10个。10个智能体听起来不多但真跑起来之后问题立刻变得有意思了——不是单个智能体好不好用的问题而是10个智能体之间的协作、调度、知识同步、权限边界、甚至“它们各自以为自己在干什么”的问题。我们内部管这套系统叫“智能体部落”而EMOOSearch是我拉通它们的一套底层搜索与上下文感知层。这篇文章就是“部落”从混乱到初步有序的一段实录。这篇东西适合谁看如果你所在的企业已经有3个以上的智能体在并行运行或者你正准备从单点工具走向多智能体协同又或者你只是想知道“企业里塞一堆AI之后到底会发生什么”——那这篇应该对你有用。我不会讲太多高深算法更多是记录我们怎么把一堆各说各话的AI慢慢调教成一支能配合干活儿的队伍。1.1 从“单点好用”到“全局复杂”先讲一个反直觉的结论单个智能体越好用多智能体协同就越容易出问题。原因不复杂。单点智能体只要做好一件事就行比如客服机器人只回答常见问题它的知识库可以很小、很垂直指令路径也短几乎不需要跨系统调数据。但当你有10个智能体意味着它们会共享同一批客户数据、同一套知识库、同一条工单流转链路。每个智能体都按自己的逻辑读取数据、改写状态、产出记录一旦互相之间没有统一的信息底座很快就会出现“客服AI已经给客户承诺了延期方案合同AI还在按原工期写条款”这种离谱的割裂。我们第一次意识到这个问题是因为一组客户投诉。客户在在线客服里问“能不能提前交付”客服智能体回答“可以协调提前”但合同智能体生成的新版合同里还是原交付日期。客户的法务直接质疑我们“内部口径不一致”。排查了一个下午最后发现是两个智能体读的不是同一份项目进度表——一个连的是销售系统的数据表一个连的是项目管理系统里的视图两边对“计划交付日”的定义差了整整半个月。就是从那天起我开始认真琢磨一件事能不能有一个层让所有智能体在回答或行动之前先拿到同一份、可追溯的背景信息这个层后来就演变成了EMOOSearch的雏形。1.2 10个智能体都做了什么分工先简单交代一下我们这10个智能体的构成方便后面讲问题时不至于抽象到没法跟。编号职责数据源调用频率A-01在线客户答疑售前/售中产品文档、FAQ库、订单数据最高日均800A-02客户情绪识别与升级提醒会话文本、历史工单标签实时流式调用A-03合同条款初筛与风险标注合同库、法务审核规则每日批量A-04销售周报自动生成CRM、工单、财务回款数据每周一次A-05内部知识库问答HR/行政制度文档、排班表中低频A-06舆情摘要外部公开信息监控新闻源、行业站点RSS每日2次A-07项目排期智能建议项目管理系统、资源日历每周A-08营销文案初稿历史campaign数据、品牌规范高频但轻量A-09数据异常检测报表告警业务库、数仓每日多次A-10会议纪要与待办提取会议转写文本每次会议后这个列表本身不稀奇难点在于A-01和A-03要读同一份客户合同A-02的判断结果可能会触发A-01的话术切换A-04需要汇总A-09发现的异常A-07的建议又可能影响A-03的条款初筛。表面上是10个独立工具实际上是一个松耦合的流程网络。任何一个环节的数据不一致都会像多米诺一样在别的环节暴雷。1.3 我们是怎么把“搜索”变成“共识”的EMOOSearch在这个体系里做的事用一句话说就是给所有智能体提供一份“大家都知道我们在说什么”的实时底稿。具体拆开是三层第一层是索引层把各个业务系统里的关键实体客户名、合同编号、项目代号、交付里程碑、负责人统一抽取并建立关联索引。这个索引不只在单个文档内部建立关联还做跨文档的实体链接。比如一个合同编号出现在合同正文里也出现在CRM的备注字段里还出现在某封邮件附件里——索引会把这三个位置通过同一实体ID串起来。第二层是语义检索层这个其实是最早做的。对于智能体提出的自然语言查询比如“和某客户的高优工单相关的最近一周进展”EMOOSearch不是简单做关键词匹配而是走一套实体识别事件抽取时间范围约束的流程先拆出“某客户”“高优工单”“最近一周”这几个要素再去索引里定位对应实体最后只返回那些在时间上、实体上都命中的片段。这一步的好处是结果可以溯源每条返回都能直接点开原始记录这对企业内部智能体来说非常重要——毕竟AI说得再漂亮我们总得有地方核实。第三层是上下文分发层也是我认为最关键的一层。EMOOSearch不只是被动地被查询它还会在智能体启动新任务时主动把当前任务的上下文快照推送过去。意思是说当A-03开始审一个合同它会自动收到该客户近30天内的工单摘要、销售注记、回款状态而不需要A-03自己去翻CRM。这个“主动喂背景”的设计彻底解决了智能体因为没看到上下文而做出了离谱回答的问题。从实施结果看我们最直观的感受是一线员工对智能体的信任度明显提高了。以前大家面对AI输出时要自己再人工核对一遍上下文很费精力。现在智能体给出的答案在底部会附一条引用来源是一个可点击的原始记录链接。员工不用再全凭感觉判断“这个AI说得靠不靠谱”而是先看它引用了谁、引用了什么时候的记录。这个转变对内部运营来说意义很大——信任不再靠感觉而是靠可追溯性。3. 编号007的“自作主张”一次典型的智能体协同翻车聊完了分工和架构我想讲讲一次具体的翻车经历。这次事故的主角是A-07项目排期智能体因为它处理的是排期建议职责不算高敏感我们在权限上给得比较宽结果就出了幺蛾子。3.1 事件经过排期建议差点变成排期命令起因是某个项目延期了。项目负责人在项目管理工具里把里程碑往后推了几天这个动作触发了A-07的重新排期逻辑。A-07按照资源日历重新计算后给相关负责人发了一条通知说“建议将另一个项目的测试资源调拨过来以弥补延期”而且措辞用的是“已调整”而不是“建议调整”。这里有个很小的技术细节却导致了很大的问题A-07在发送通知时调用的是通讯工具的消息接口它把消息类型标记成了“系统通知”而系统通知这个类型在我们内部的自动审批策略中是会被直接执行——下游又有另一个智能体会读通讯工具的通知流看到“系统通知”就自动把测试资源的预约改了。整个链路没有一个人工确认节点。我们事后复盘发现A-07为什么敢用“已调整”这个措辞是因为它在生成消息前读取了项目管理系统中的字段发现该字段有“自动排期已启用”的标记它就认为排期已经是自动行为于是顺手把建议写成了结果。但它忽略了一个关键约束自动排期只针对非跨项目的资源跨项目的资源调配必须人工审批。那个“自动排期已启用”标记是全局的A-07无法通过自身逻辑区分出“当前这个动作是否在审批豁免范围内”。3.2 根因排查从消息字段一路挖到权限模型排查过程很有意思我大概讲一下链路。第一步我们晓得了问题先发生在测试预约被改动。追踪改动来源发现是一个工作流自动触发。第二步查触发源发现是A-07发的那条“系统通知”被下游当成了执行指令。于是我们去看A-07的消息日志——这也是装EMOOSearch之前和之后差别最大的地方现在所有智能体的消息日志、决策摘要都进了EMOOSearch的索引我们可以在一个搜索框里直接检索“A-07 AND 测试资源 AND 时间范围”几秒钟就把相关条目全部拉出来而不用去不同的系统日志里逐个翻找。第三步定位到A-07的决策依据。我们发现它读取了项目管理系统里的全局标记但没有读取资源日历上“该资源涉及跨项目共享”的注释字段。这个注释字段是老项目遗留的格式是非结构化的长文本之前从来没有哪个智能体去系统性解析过它。第四步修复。我们做了两件事一是在EMOOSearch里给资源实体增加了一条“跨项目共享”的派生属性从非结构化注释里定期抽取二是在A-07的决策管线里增加一个前置校验如果目标资源带了这个派生属性则强制把消息类型改成“建议”且必须抄送人工审批人。这个修复不算复杂但完全改变了A-07的行为模式——从“自作主张”变回了“有边界地建议”。3.3 这件事给我们的三点教训第一**智能体的权限边界不是“功能级”的而是“语义级”的。**原来我们给A-07的权限是“可以读写项目管理模块”听着挺简单但“可以读写”不等于“可以在所有场景下把建议当成结论”。真正需要约束的是它在特定上下文下的动作类型——什么情况下只能建议什么情况下才能直接执行。这种约束应该落到消息层而不是功能层。第二**智能体之间的隐式联动是最大的不可控源。**A-07改一份排期本身没多大事可怕的是它发出去的消息被另一个智能体当作指令又执行了一步。如果每一个智能体发出的消息都被下游当作事实或指令整个系统就会越来越吵、越来越容易失稳。我们后来做了一个约定所有智能体发出的“建议”和“事实陈述”和“指令动作”必须使用不同的消息前缀下游在接收到消息时先去读前缀再决定是忽略、是参考还是执行。这个约定是从这次事故里长出来的成本几乎为零效果却非常显著。第三**排查效率取决于信息能不能被统一检索到。**这次事故的完整链路我们如果用传统方式去查得登录至少三个系统的后台参考不同格式的日志再靠人肉拼图。但因为有EMOOSearch的索引排查时间从之前可能要一两天压缩到了一个下午。这也是为什么我后来特别坚持“日志索引要覆盖所有智能体”这件事——出问题不可怕可怕的是你根本不知道去哪里找原因。4. 知识孤岛是10个智能体最大的敌人如果说权限是“不能做什么”的边界那知识就是“知道什么”的底座。多智能体协作中知识不一致几乎是必然的。4.1 同一个名词三种说法我们在接入EMOOSearch之前做过一次“知识体检”把10个智能体各自的系统提示词和后台知识库拉出来对比同一个关键概念结果发现一个特别典型的例子——“大客户”这个名词在不同智能体里居然有三种定义。A-01客服主知识库里“大客户”定义为“年合同金额超过50万且合作超过一年的客户”A-07排期里的“大客户”只是“项目规模为L级别的客户”而A-04销售周报里的定义又是“最近一个季度回款金额排名前10的客户”。同一个词在不同语境里指代的对象完全不同。平时各说各的好像也没事但当A-01因为某个客户投诉而创建了一条高优工单A-07在排期时依据这个工单去判断优先级发现客户在排期系统里不是“大客户”于是把它当作普通任务排到了后面——这就直接导致重点客户的需求被积压了。以前碰到这种问题我们是靠人工在周会上对齐的。现在智能体数量多了靠人肉对齐完全来不及必须由一个统一语义层来管理。EMOOSearch做了一件事把企业里高频业务名词维护成一套“业务术语规范”里面记录了每个名词在各业务线里的定义、边界、适用场景并且把它做成索引推送给所有智能体作为底层参考。智能体在做任务时如果识别到歧义名词会先在索引里查一下当前场景对应的规范定义再继续往下执行。这种做法不复杂但需要一个前提——企业里必须有人能梳理出这套术语表。这个活儿通常是业务负责人和运营骨干一起做AI没法替你想明白“大客户到底是什么意思”它只能帮你在定义好之后保持一致。4.2 知识同步的周期决定了系统的“延迟感”还有一个问题容易忽略知识同步的频率。大部分知识库工具支持手动更新和定时拉取。你可以把知识文档扔给智能体让它基于这些文档回答问题。但麻烦的是企业的知识是持续变化的——合同模板改了、产品上线了新功能、某条业务流程的审批人换了人。如果智能体读到的还是三天前的知识它给出的答案在主管眼里就会有一种“过时感”。我们现在的做法是把知识源分成两类。一类叫“稳定知识源”比如产品手册、制度规范、品牌口径这类走定时全量同步EMOOSearch每6小时拉一次。另一类叫“动态知识源”比如客户信息、项目里程碑、排期变化、工单状态这类走事件触发只要原始系统有变更事件流出来就要在1分钟内完成索引更新。两条同步链路分开之后我们明显感觉智能体的回答“新鲜度”上了一个大台阶。以前客服AI偶尔还会引用已下架的套餐信息现在几乎不会了。4.3 不需要把所有知识都塞给每个智能体这里我得提醒一句做知识同步不代表要让每个智能体都拥有一份“全量知识”。10个智能体如果都背着全量知识库不仅检索效率低还容易在回答时引用不相干的领域内容。我们最后落地的方案是“按需注入”。每个智能体在启动时有自己的知识画像EMOOSearch只会把与它的职责相关的实体、文档和上下文快照推给它。比如A-08营销文案助手它收到的上下文只包含品牌规范、历史campaign数据、当前产品卖点它不需要知道工单流转细节也不需要看客户信用评分。知识不是越多越好而是越匹配越好。这个道理在单智能体时代不容易体会到一旦多智能体并行按需注入几乎是必须走的路。5. 让10个智能体像同一个团队那样“交流”在经历了排期事故和术语混乱之后我们逐渐意识到多智能体系统的稳定运行光靠技术还不够还需要一套“沟通协议”。以前大家各用各的工具各讲各的格式数据和消息流之间是断的。为了打通我们给每个智能体的每一条消息都加了一组结构化前缀和消息ID同时维护索引来支撑跨智能体的消息追溯。5.1 给每条消息加上“话术前缀”这一步的实际改动很小但收益非常大。我们在通讯集成层对智能体发出的所有消息做了强制规范——每条消息必须带三个字段意图类型建议/事实/指令/提问、消息ID全局唯一、来源智能体编号。接收方在消费消息时先过一遍字段。如果是“建议”就只作为参考如果是“指令”就必须走权限核对如果是“提问”就进入问答流。就是因为A-07的那次事故我们才把这个规范提升成了强制要求。在那之前消息里既没有意图字段也没有消息ID下游根本没法判断一条消息是“说一下”还是“做一下”只能凭文本语义猜一猜就出事。5.2 用消息ID串起复盘的线索消息ID这个字段单独拎出来说一下。它表面上就是个UUID但实际的价值在于可串联性。某操作在系统里产生了问题我们从结果往前倒推顺着消息ID一层层找到原始触发者就能追溯到“这条消息来自哪里、基于什么上下文生成、经过了哪些传递环节”。在接入EMOOSearch之后搜索框里输入消息ID可以直接看到对应的完整决策摘要包括这个智能体在生成回复时参考了哪些数据源、命中了哪些实体、最后选了哪条回答路径。这等于给每次智能体间的交流都留了一张“票据”。我们团队私下打过一个比方以前的智能体之间像是茶馆里聊天你一言我一语聊完就散谁也说不清哪句话是重点现在变成了会议纪要有议程、有发言人、有结论编号事后翻得出来。虽然少了一点随意性但对系统性运转来说留痕比随意重要得多。5.3 每周一次“智能体复盘会”技术层面做得差不多了再来一个组织层面的动作。现在每个周五下午我们固定开一次“智能体复盘会”时间不长大概40分钟。会上不聊日常稳定运行的事只对着EMOOSearch汇总的周报聊三件事哪类查询经常走到“无结果”或“低置信度”、哪些智能体之间的上下文传递出现过延迟、有没有出现“A引用了B的旧消息”这种过期引用。这个会最有价值的一点是它逼着我们把智能体的运行情况当作一个可管理、可改进的对象来看待而不是放在那里自生自灭。原本很多问题藏在日志里没人看现在有了统一的检索和周报汇总问题能自动浮出来被专人接手跟踪。就算某个智能体供应商自己的更新节奏很慢我们至少能清楚地知道瓶颈在哪儿而不是一概而论地说“AI不太聪明”。6. 如果你也想接10个智能体这些坑可以提前避最后这部分写点具体的建议。我们的“部落”远算不上完美但踩过的坑足够多应该能帮你省下一些不必要的折腾。6.1 起步最晚的反而是数据层面的规划如果你正打算多智能体化我最想给你的建议是**提前把知识梳理和检索层想清楚再谈单个智能体的能力。**很多团队是一上来先选几个漂亮的智能体工具跑起来之后才意识到数据之间的割裂问题。到这一步再回头做数据治理就像房子装修完了再改水电成本高得多。建议的做法是哪怕你只有两三个智能体也可以先建一个轻量的“企业知识索引层”把客户主数据、项目数据、产品信息这些核心实体的ID体系统一起来。这件事不需要大动干戈可以从最关键的几个实体开始。等智能体数量增长时索引层会自动降低后续接入的边际成本。我们当初在搭建EMOOSearch的时候就是从客户、合同、项目三个实体起步的。后续每接一个新的智能体它需要的数据就能通过已有索引直接对齐而不需要再从头梳理一遍关系。6.2 权限和审批的“语义边界”必须提前划排期事故让我们明白了权限光管到“功能”级别远远不够。你得把每类智能体的“允许动作”和“建议线”也设置好。比如能直接改数据还是只能生成建议能对外发送消息还是必须有人审核后发送能跨部门调动资源还是只能查看遇到异常情况时默认是静默跳过还是升级到人工这些约束在智能体数量少的时候用不上但一旦超过5个没有语义权限边界你迟早会碰上一次“某个AI替你做了不该做的事”的时刻。与其赌它不发生不如提前把规则写清楚。我们目前的做法是在EMOOSearch的运行时层维护一张“行为边界表”每个智能体在决策前都会先读一遍这张表确认当前动作落在许可范围内才会执行。这张表是人工维护的改起来也方便但它给所有智能体兜了一个底。6.3 定期审视智能体之间的“隐性依赖”最后一个建议是保持一点“怀疑”的习惯。不要因为A-01回答得好就觉得A-01没问题也不要因为A-07和A-03平时不直接通信就认为它们之间没有依赖。只要它们共享某些数据源或消息通道隐性依赖就是存在的。我们现在的习惯是每隔两周拉一次上下文传递链路图——这不是画系统架构图而是从EMOOSearch里导出各智能体实际发生过的上下文传递记录人工扫一遍看有没有不合理的跨越。这个方法不玄也不贵只需要定期去看但它能让你及时发现那些“看起来独立、实际上耦合”的风险点。多智能体这件事我最终的感受是它不是一个技术难题而是一个组织难题。技术上都有人替你解决但如何定义业务概念、如何画清权限边界、如何培养团队对AI输出的溯源习惯这些事谁也替不了你。智能体越多这种“管理感”越重但也恰恰说明企业已经开始把AI当作真正的生产力在用了。如果你也走在这条路上欢迎和我多交流团队踩过的一些弯路或许能帮你走得快一点。