
1. 当多个Agent开始互相“甩锅”问题出在哪如果你最近在折腾多智能体系统大概率遇到过这种场景三个Agent协作完成一个任务结果A把任务推给BB觉得这不是自己的职责又推回给AC在旁边反复输出“我建议先明确分工”——整个系统陷入一种诡异的“开会循环”token烧了一大把任务原地踏步。更离谱的是当你去查日志发现每个Agent的推理链条看起来都“很有道理”但合在一起就是一团乱麻。这个现象在圈子里有个很形象的说法叫机器部落主义。每个Agent基于自己的角色设定和上下文形成了一套“局部最优”的判断逻辑当多个局部最优碰撞时不是产生全局最优而是产生内耗。你给它们设定了不同的persona、不同的工具权限、不同的知识库本意是让它们各司其职结果它们各自为政甚至互相“甩锅”。我最近在做一个多智能体协作平台的项目核心要解决的就是这个问题。具体来说是通过一套身份脱敏加系统隔离网关的架构把Agent之间的“身份包袱”卸掉让它们只关注任务本身而不是“我是谁、我该不该管这件事”。关键词里的Harness、Agent框架、系统隔离网关都是这套方案里的核心概念。这篇文章我会把整个设计思路、踩过的坑、以及实际跑下来的效果完整地拆开讲一遍。适合谁看如果你正在做Agent开发、多智能体协同、或者单纯被Agent之间的“内耗”搞得头大这篇内容应该能给你一些可以直接抄作业的思路。如果你刚接触Agent还没踩过协作的坑那更好提前把坑标出来省得后面返工。2. 机器部落主义是怎么形成的从角色设定到信息茧房2.1 角色Prompt的“副作用”越详细越容易画地为牢做Agent开发的人一开始都会花大量精力打磨System Prompt。你要给Agent一个清晰的身份“你是一个资深财务分析师”“你是一个代码审查专家”“你是一个客服代表”。这个思路本身没问题但问题出在过度细化上。我试过给一个Agent写这样的Prompt“你是一个专注于后端API性能优化的专家你只负责分析接口响应时间、数据库查询效率、缓存命中率不负责前端渲染、不负责业务逻辑正确性、不负责安全审计。”看起来很清晰对吧结果在实际协作中当另一个Agent把“这个接口返回的数据结构有问题”抛过来时这个“性能专家”直接回了一句“这不属于我的职责范围”然后把任务原路退回。整个协作链条在这里断掉了。这就是角色Prompt的副作用你越是把边界画得清楚Agent就越倾向于在自己的边界内“安全地”工作遇到边界模糊的地带它的第一反应不是“我来试试”而是“这不是我的事”。多个这样的Agent放在一起就形成了部落主义——每个Agent守着自己的“一亩三分地”跨部落的协作变得极其困难。2.2 上下文隔离带来的“信息茧房”另一个加剧部落主义的因素是上下文隔离。在多智能体架构里每个Agent通常有自己的上下文窗口看到的是经过筛选的信息。A Agent看不到B Agent的完整推理过程只能看到B输出的结果。这就导致A对B的决策依据缺乏理解容易产生“它为什么这么做”的困惑进而引发重复确认、反复询问。我实测过一个三Agent协作的场景Agent A负责需求拆解Agent B负责技术方案设计Agent C负责代码实现。A把需求拆成五个子任务发给BB基于自己的理解设计了方案但方案里有一个假设“用户数据已经过脱敏处理”没有明确写出来。C拿到方案后发现数据格式对不上于是回头问BB说“我假设数据是脱敏的”C说“但A给我的原始数据没有脱敏标记”。然后A被拉进来解释A说“我拆解需求时默认数据是原始的”。三个人来回扯了七八轮最后发现只是一个假设没有对齐。这种问题的根源在于每个Agent都在自己的上下文里“自洽”但跨Agent的假设对齐没有机制保障。信息茧房让每个Agent都觉得自己是对的问题出在别人身上。2.3 内耗的量化Token浪费与延迟放大部落主义和信息茧房带来的内耗是可以量化的。我做过一组对比测试同一个任务一个中等复杂度的数据处理流程用两种方式跑指标无隔离网关有隔离网关总Token消耗约12万约4.8万任务完成时间8分32秒3分15秒Agent间消息轮次23轮9轮任务成功率67%94%无隔离网关的情况下大量Token花在了Agent之间的“确认-澄清-再确认”循环上。有几次甚至出现了死循环A问B要数据B说数据在C那里C说数据已经给A了A说没收到然后循环。最后是人工介入才断开的。延迟放大也很明显。每个Agent的推理都需要时间23轮消息意味着至少23次模型调用每次调用哪怕只花2秒累计就是46秒的纯等待时间。再加上上下文越来越长每次调用的延迟还会增加。8分32秒里真正用于“干活”的时间可能不到2分钟。3. 身份脱敏的核心思路让Agent忘记“我是谁”3.1 从“角色驱动”转向“任务驱动”身份脱敏的核心逻辑很简单不让Agent知道自己在整个系统中的“身份标签”。传统做法是给每个Agent一个固定的角色“你是财务专家”然后期望它在这个角色下做出正确决策。身份脱敏的做法是Agent在接收任务时只看到任务描述和必要的上下文看不到“你是第几号Agent”“你的角色是什么”“你的权限边界在哪里”。举个例子。传统方式下Agent B收到的消息可能是“你是技术方案设计Agent请基于以下需求设计技术方案。”身份脱敏后Agent B收到的消息是“请基于以下需求设计技术方案输出格式要求如下。”没有角色标签没有“你是XX专家”的暗示只有任务本身。这个改变看起来很小但效果很显著。Agent不再纠结“这该不该我管”因为它根本不知道“自己”是谁它只知道“当前有一个任务需要处理”。任务驱动取代了角色驱动Agent的注意力从“身份维护”转移到了“任务完成”上。3.2 脱敏的粒度哪些信息该隐藏哪些必须保留身份脱敏不是把所有信息都抹掉那样Agent就没法工作了。关键是脱敏的粒度。我总结了一个原则隐藏身份标签保留能力描述。具体来说以下信息应该被隐藏Agent的编号或名称“Agent-001”“财务专家”Agent在系统中的层级关系“你是A的下级”“你向B汇报”Agent的历史交互记录“你之前和C有过冲突”Agent的权限边界描述“你只能访问X数据库”以下信息必须保留当前任务的具体描述完成任务所需的数据和工具输出格式和验收标准必要的业务规则和约束这个粒度划分的依据是身份标签会触发Agent的“自我保护”机制而能力描述不会。当Agent知道“我是财务专家”时它会倾向于维护这个身份的一致性遇到财务相关的问题会更积极遇到非财务问题会更保守。但当它只知道“当前任务需要分析财务数据”时它的行为完全由任务本身驱动没有身份包袱。3.3 脱敏后的Agent行为变化实测对比我做过一组A/B测试同一个任务同一组Agent唯一变量是是否启用身份脱敏。结果很有意思启用身份脱敏前Agent A需求拆解在拆解时会刻意把“技术方案设计”部分标注为“由B负责”把“代码实现”标注为“由C负责”。这种标注本身就在强化部落边界。Agent B技术方案在设计时会反复确认“这个方案是否符合A的预期”而不是“这个方案是否合理”。Agent C代码实现在遇到方案模糊时会先问B“你当时是怎么想的”而不是直接基于代码逻辑做判断。启用身份脱敏后Agent A拆解需求时只输出子任务列表和依赖关系不标注“谁负责”。Agent B设计技术方案时直接基于需求和技术约束做决策不再猜测“A想要什么”。Agent C遇到方案模糊时直接基于代码逻辑和测试结果做判断必要时才向上游请求澄清。最明显的变化是消息轮次从23轮降到了9轮。Agent之间的交互从“确认-澄清-再确认”变成了“任务-结果-下一步”。每个Agent都更关注“怎么把当前任务做好”而不是“怎么不越界”。4. 系统隔离网关的工程实现Harness到底在做什么4.1 Harness的定位不是Agent框架是Agent之间的“交通管制”很多人第一次听到Harness这个词会以为它是另一个Agent框架。其实不是。Harness在我的架构里扮演的是系统隔离网关的角色。它不负责Agent的推理逻辑不负责工具调用不负责记忆管理。它只做一件事管理Agent之间的消息传递确保身份脱敏和上下文隔离。你可以把Harness想象成一个邮局。Agent A把消息投递到邮局邮局把消息里的身份标签抹掉然后根据路由规则投递给Agent B。Agent B收到消息时不知道这消息来自A还是C只知道“这是一个任务请求”。Harness还负责上下文裁剪确保Agent B只看到与当前任务相关的上下文而不是整个系统的全局状态。这个定位很关键。很多Agent框架试图把编排、推理、工具、记忆全部包进来结果变得极其臃肿。Harness的哲学是只做隔离和路由其他事情交给Agent自己或者外部的编排层。这样Harness可以保持轻量也更容易适配不同的Agent实现。4.2 消息脱敏的具体流程从发送到接收的完整链路Harness的消息脱敏流程我拆成了五个步骤第一步消息拦截。Agent A调用Harness的send接口传入原始消息。原始消息里可能包含Agent A的ID、角色标签、历史上下文引用等信息。第二步身份剥离。Harness解析消息结构把身份相关的字段sender_id、sender_role、sender_history等全部剥离只保留payload任务描述、数据、格式要求。第三步上下文裁剪。Harness根据接收方Agent B的当前任务从全局上下文中裁剪出必要的部分。比如B正在处理“数据清洗”任务那么Harness只会把与数据清洗相关的上下文传给B不会把A的完整推理过程传过去。第四步路由决策。Harness根据任务类型和Agent的能力注册表决定把消息路由给哪个Agent。这个路由是动态的不依赖于固定的角色映射。比如“数据清洗”任务可能路由给Agent B也可能路由给Agent D取决于当前哪个Agent有空闲容量。第五步消息注入。Harness把脱敏后的消息注入Agent B的输入上下文B看到的是一条“干净”的任务请求没有身份信息没有历史包袱。这个流程的关键在于第三步和第四步。上下文裁剪决定了Agent能看到多少信息路由决策决定了任务分配给谁。两者结合实现了任务驱动的协作模式。4.3 隔离网关的部署形态进程内、进程间、还是独立服务Harness的部署形态有三种选择我实际都试过进程内模式Harness作为Agent进程内的一个模块直接函数调用。优点是延迟极低没有网络开销。缺点是隔离性差如果Agent进程崩溃Harness也跟着挂。适合单机部署、Agent数量少的场景。进程间模式Harness作为独立的进程Agent通过IPC或本地Socket通信。优点是隔离性好Harness可以独立重启。缺点是延迟比进程内高大概多0.5-1毫秒。适合单机多Agent的场景。独立服务模式Harness作为独立的网络服务Agent通过HTTP或gRPC通信。优点是扩展性好可以跨机器部署。缺点是延迟最高网络开销大概2-5毫秒。适合分布式部署、Agent数量多的场景。我最终选择了进程间模式。原因是延迟可以接受0.5-1毫秒相对于模型推理的几百毫秒可以忽略隔离性足够Harness崩溃不影响Agent反之亦然部署复杂度适中不需要额外的网络配置。如果你的Agent数量超过20个或者需要跨机器部署可以考虑独立服务模式。5. 踩坑实录身份脱敏不是万能药5.1 脱敏过度导致的任务迷失一开始我走了一个极端把所有身份信息都抹掉连“你是一个AI助手”这样的基础设定都不给。结果Agent变得极其“迷茫”。它不知道自己的能力边界在哪里遇到需要专业判断的任务时会反复询问“我应该用什么标准来判断”。比如一个数据清洗任务Agent收到的是“请清洗以下数据”。它不知道自己是“数据工程Agent”还是“业务分析Agent”于是它既做了格式清洗又做了业务规则校验还尝试做了一些统计分析。输出了一大堆东西但大部分都不是当前任务需要的。这个坑让我意识到身份脱敏不等于身份消除。Agent需要知道“我能做什么”只是不需要知道“我是谁”。所以后来的方案里我保留了能力描述“你可以使用以下工具”“你可以访问以下数据源”但去掉了身份标签“你是XX专家”“你属于XX团队”。5.2 上下文裁剪的“误伤”把关键信息裁掉了上下文裁剪的粒度很难把握。裁得太少Agent看到太多无关信息注意力被分散裁得太多关键信息被误伤Agent做出错误判断。我遇到过一个典型案例Agent B在做一个API设计任务Harness裁剪上下文时把“该API需要兼容旧版本客户端”这条信息裁掉了因为Harness判断这条信息属于“历史背景”与“API设计”这个任务类型不直接相关。结果B设计了一个不兼容旧版本的API导致下游的Agent C在实现时发现无法对接。这个问题的根源在于Harness的裁剪规则是基于任务类型的静态规则但实际协作中很多信息是跨任务类型的。后来我改成了动态裁剪Harness会分析当前任务的所有依赖关系把直接依赖和间接依赖的信息都保留只裁掉真正无关的部分。这个改动让裁剪准确率从72%提升到了91%。5.3 Agent“假装”不知道身份但行为模式暴露了身份脱敏后Agent在显式层面确实不知道自己的身份了。但它的行为模式仍然可能暴露身份。比如一个被设定为“谨慎型”的Agent即使脱敏后它在做决策时仍然会倾向于保守选项。一个被设定为“激进型”的Agent仍然会倾向于冒险。这个问题在短期内无解因为Agent的行为模式是由底层模型和训练数据决定的不是靠Prompt就能完全改变的。我的应对策略是行为模式多样化在路由任务时不只看Agent的能力匹配度还看Agent的当前行为倾向。如果当前任务需要谨慎决策就路由给行为偏保守的Agent如果需要快速迭代就路由给行为偏激进的Agent。这个策略的效果是Agent之间的“性格冲突”减少了。以前两个性格迥异的Agent协作时经常在决策风格上产生分歧。现在Harness在路由层面就做了匹配协作顺畅了很多。6. 实测数据隔离网关到底省了多少成本6.1 Token消耗对比从12万降到4.8万前面提到过同一个任务无隔离网关时Token消耗约12万有隔离网关时约4.8万。这个差距主要来自三个方面消息轮次减少从23轮降到9轮每轮消息都包含输入和输出Token轮次减少直接带来Token节省。粗略估算每轮消息平均消耗5000 Token输入输出14轮的差距就是7万Token。上下文长度缩短无隔离网关时每个Agent的上下文里包含了大量历史交互记录导致每次调用的输入Token膨胀。有隔离网关后Harness裁剪了上下文每个Agent只看到与当前任务相关的部分输入Token平均减少了40%。重复推理减少无隔离网关时Agent经常需要重复推理“这个任务该不该我管”“我之前有没有处理过类似任务”。有隔离网关后这些元推理被消除了Agent的推理全部集中在任务本身。6.2 任务成功率提升从67%到94%任务成功率的提升主要来自死循环的消除和假设对齐的改善。无隔离网关时23轮消息里有相当一部分是“确认-澄清”循环。有几次甚至出现了死循环需要人工介入。这些情况直接导致任务失败。有隔离网关后Harness在路由层面就确保了任务分配的明确性Agent不需要反复确认“这是不是我的任务”。假设对齐的问题也通过上下文裁剪得到了改善因为Harness会确保所有Agent看到一致的假设前提。6.3 延迟变化单次调用增加整体时间缩短隔离网关本身会引入额外的延迟。进程间通信大概增加0.5-1毫秒上下文裁剪大概增加1-2毫秒路由决策大概增加0.5-1毫秒。总计每次消息传递增加2-4毫秒。但整体任务完成时间从8分32秒降到了3分15秒。原因是消息轮次从23轮降到了9轮每轮消息的模型推理时间几百毫秒到几秒远大于隔离网关的延迟。所以虽然单次调用变慢了但整体时间大幅缩短。这个数据说明一个道理在多智能体系统里减少协作轮次比优化单次调用延迟更重要。隔离网关的几毫秒开销换来的是轮次的大幅减少整体收益是正的。7. 这套方案适合什么场景不适合什么场景7.1 适合的场景任务明确、Agent数量多、协作频繁这套方案最适合的场景是任务明确、Agent数量多、协作频繁的多智能体系统。比如数据处理流水线多个Agent分别负责数据采集、清洗、转换、加载任务边界清晰但协作频繁。代码生成与审查多个Agent分别负责需求分析、代码生成、代码审查、测试生成需要频繁交互。客服工单处理多个Agent分别负责意图识别、知识检索、回复生成、质量检查任务流转频繁。在这些场景里身份脱敏和隔离网关能显著减少内耗提升协作效率。7.2 不适合的场景需要深度角色扮演、创意协作、强身份依赖这套方案不适合的场景也很明确深度角色扮演比如模拟谈判、角色扮演游戏Agent需要明确知道自己的身份和立场脱敏会破坏角色一致性。创意协作比如头脑风暴、创意写作Agent需要知道“我是谁”来贡献差异化的视角脱敏会导致输出同质化。强身份依赖比如权限管理、审计追踪Agent需要知道自己的权限边界脱敏会导致权限失控。在这些场景里身份脱敏反而会带来问题。所以这套方案不是万能的需要根据具体场景选择。7.3 混合模式部分脱敏、动态脱敏对于介于两者之间的场景可以考虑混合模式。比如部分脱敏隐藏Agent的编号和层级关系但保留角色标签“你是财务专家”。这样Agent知道自己的专业领域但不知道自己在系统中的位置。动态脱敏根据任务类型动态决定脱敏程度。任务明确时完全脱敏任务模糊时保留部分身份信息。我目前在生产环境里用的是部分脱敏。隐藏了Agent的编号和层级但保留了角色标签。这样既减少了部落主义又保留了专业分工的优势。实测下来Token消耗比完全脱敏高约15%但任务成功率比完全脱敏高约8%。这个 trade-off 在我的场景里是值得的。8. 几个容易被忽略的工程细节8.1 消息ID的生成与追踪身份脱敏后Agent不知道消息来自谁但系统需要知道。所以Harness需要维护一个消息ID映射表每条脱敏后的消息都有一个唯一的消息IDHarness通过这个ID追踪消息的原始发送方和接收方。这个映射表的设计要注意两点一是ID不能包含身份信息不能用“AgentA-001”这样的格式要用随机UUID二是映射表要有TTL消息处理完成后一段时间自动清理避免无限增长。我一开始用自增整数做消息ID结果Agent通过ID的大小顺序推断出了消息的先后关系间接暴露了身份。后来改成了UUID这个问题就解决了。8.2 错误处理与重试机制隔离网关引入了一个新的故障点如果Harness挂了整个协作就断了。所以错误处理和重试机制很重要。我的做法是Harness维护一个消息队列Agent发送的消息先入队Harness异步处理。如果Harness处理失败消息留在队列里等待重试。重试策略是指数退避第一次重试等1秒第二次等2秒第三次等4秒最多重试5次。同时Agent端要有超时机制。如果Agent发送消息后一段时间比如30秒没有收到响应就认为Harness出了问题触发降级逻辑比如直接点对点通信绕过Harness。这个降级逻辑在Harness恢复后会自动切回。8.3 监控与可观测性身份脱敏后调试变得困难了。以前你可以直接看“Agent A发给Agent B的消息”现在你只能看到“消息ID xxx从某个Agent发往某个Agent”。所以监控和可观测性变得尤为重要。我在Harness里加了几个关键指标消息吞吐量每秒处理多少条消息脱敏延迟从消息入队到脱敏完成的时间路由准确率路由决策被Agent接受的比例上下文裁剪命中率裁剪后的上下文被Agent实际使用的比例这些指标帮助我快速定位问题。比如有一次路由准确率突然下降查下来发现是Agent的能力注册表没有及时更新导致Harness把任务路由给了错误的Agent。8.4 安全边界脱敏不等于无权限最后强调一点身份脱敏不等于权限脱敏。Agent不知道自己的身份但仍然需要遵守权限规则。Harness在路由消息时会检查目标Agent是否有权限访问消息中的数据。如果没有权限Harness会拒绝路由并返回错误。这个检查是在脱敏之后、路由之前做的。Agent看不到身份信息但Harness知道每条消息的原始发送方和接收方可以基于原始身份做权限校验。这样既实现了身份脱敏又没有牺牲安全性。我在实际项目里踩过的一个坑是一开始把权限校验也脱敏了结果Agent A把敏感数据发给了没有权限的Agent BB直接处理了数据造成了数据泄露。后来加回了权限校验这个问题就解决了。9. 从Harness到Agent框架一些延伸思考Harness和Agent框架的关系我琢磨了很久。一开始我觉得Harness应该集成到Agent框架里作为框架的一个模块。后来发现这样不行因为不同Agent框架的实现差异太大Harness集成进去会变得很臃肿。现在的做法是Harness作为独立的中间层通过标准接口与Agent框架对接。Agent框架只需要实现两个接口send发送消息和receive接收消息。Harness负责剩下的所有事情。这样Harness可以适配任何Agent框架不管是基于Python的、基于Rust的、还是基于其他语言的。这个设计还有一个好处Harness可以独立演进。Agent框架的更新不影响HarnessHarness的优化也不影响Agent框架。两者解耦各自迭代。如果你正在做Agent开发我建议把Harness作为一个独立的关注点来设计。不要把它塞进Agent框架里也不要让它承担太多职责。只做隔离和路由其他事情交给别人。这个原则让我的系统稳定了很多也更容易维护。最后分享一个我在实际使用中发现的小技巧Harness的日志要分级。DEBUG级别记录完整的消息内容包括脱敏前的用于调试INFO级别只记录消息ID和路由结果用于监控ERROR级别记录异常和失败原因用于告警。这样既保证了可调试性又避免了日志泄露敏感信息。这个分级策略在排查线上问题时特别有用你可以快速定位到某条消息的完整链路而不用在浩如烟海的日志里翻找。