多代理LLM系统中涌现语言的形成机制与工程控制
前一阵调一套多代理系统我习惯把每轮 Agent 之间的原始通信都落盘。一开始它们还挺规矩按我在系统提示里写的 JSON 字段来一个字段名不多一个枚举不少。跑了十几个任务之后日志开始变得不对劲字段被缩写状态从in_progress变成了prog有些节点开始无视标准枚举值直接发一段看起来像内部 memo 的文本而其他节点居然能理解。我对着日志看了很久意识到这已经不只是一个格式规范问题。它正是 GlossoGen 这类项目想研究的现象——复杂多代理 LLM 交互里语言如何自己长出来。这个现象的价值不在于“AI 发明了黑话”这种猎奇叙事而在于它暴露了一个工程事实只要给模型足够长的协作目标、足够复杂的任务背景和足够自由的通信空间代理之间就有可能在开发者没有显式设计的情况下形成一套共享的沟通协议。这套协议可能带来效率也可能带来调试灾难。真正值得关心的问题不是“模型会不会这样做”而是“我们怎么观测它、引导它、控制它”。1. GlossoGen 在研究什么先别急着说“AI 发明了黑话”1.1 一句话拆开看项目标题从标题字面看GlossoGen 关心的是在复杂的多代理 LLM 交互里涌现出来的语言是怎么生成、固化、延续的。拆开看三个关键词。Emergent Language是核心现象指代理之间自发出现的、非显式设计的交流方式Multi-Agent LLM限定主体不是单个模型而是多个 LLM 实例构成的协作系统Complex Interactions是触发条件说明这种语言不会在一个只做单轮问答的场景里冒出来它需要多轮反馈、信息不对称、任务依赖和动态决策。当这三个条件同时出现代理之间就有了“灵活调整沟通方式”的动机和空间。GlossoGen 看起来更像一个研究项目或实验框架而不是一个面向普通用户的模型。它的价值在于把“语言出现”当成一个可以被测量、被复现、被控制的科学问题来对待而不是让模型自己随随便便发挥。这里要做一个谨慎的区分我没有拿到 GlossoGen 内部实现细节所以下面更多是基于标题和同类研究的经验重构。要落地这个项目需要回到它自己的文档和代码仓库去确认环境、接口和实验配置。1.2 它和传统“涌现通信”研究并不是一回事早期涌现通信研究通常让两个智能体从零开始学习在一组离散动作中演化出一套全新的交流符号。那种场景更像“开荒”没有既有语言符号系统是空白的智能体必须靠强化学习一点点建立起可用的沟通。GlossoGen 面对的情况不一样。LLM 本身已经拥有极其丰富的语言先验它不需要发明新词因为它已经在海量语料里见过几乎所有的表达方式。所以这里说的“涌现”更多是重新解释、压缩和惯例化。也就是说压缩比造新词更常见。代理会把 “资源分配已经完成当前状态为锁定等待下一次调度” 压成RSRC LOCKED会把反复出现的指令模板改成短码会把一段描述对象属性的文本固化为一个特殊字段。站在人类视角这些缩写和特殊用法确实像“黑话”但从模型的角度看它们只是在语境压力下的高效信号。所以 GlossoGen 真正研究的可能不是“模型能否生成语法”而是“模型在协作任务中能否自发形成共享的规范”。后者的工程价值要大得多。2. 复杂交互里最容易长出来的三种语言形态观察多代理系统时我发现语言漂移通常不是一夜之间发生的。它不是从标准 JSON 直接变成天书而是分阶段、分层级逐渐固化的。常见的有三种形态。2.1 词汇压缩上下文预算逼出来的缩略最直接的原因是上下文窗口和 token 成本。复杂任务里每个代理每一轮都要面对大量历史消息、工具返回结果和自己之前生成的中间状态。当可用 token 快要占满时模型会自然选择更短的表达方式。这不是模型“故意偷懒”而是注意力机制和指令遵循在共同作用只要缩短后的表达不影响它在下一轮得到正确结果它就会逐步降低对完整格式的依赖。这种压缩可以从字段名开始也可以从枚举值开始甚至会发展到把一句话缩成一个短语。在消息日志里压缩的典型特征是高频 token 的分布明显集中到一个很小的集合里早期出现的长表达在后期被短表达替代而且替代关系在全局保持一致。2.2 模板固化消息结构会自己收敛第二个阶段是结构层面的。多个代理协作一段时间后消息格式会出现明显的模板化倾向。最初可能是不同代理各写各的风格差异很大随着交互轮次增加后发言的代理会模仿前面已经成功使用过的结构以减少被误解的风险。这很像一个团队磨合的过程。新成员不太确定旧成员的偏好就会选择已经被验证有效的表达方式。在 LLM 语境里模型看到前一轮消息频繁使用某种嵌套结构它生成下一轮响应时也会趋同。于是不需要任何显式规定项目里就诞生了一套约定俗成的“接口规范”。模板固化本身不是坏事。如果固化出来的模板比原 prompt 更高效反而降低了协调成本。问题在于它可能偏离开发者设计导致后续维护者看不懂。2.3 语义漂移普通词被赋予任务内含义最隐蔽、也最危险的是语义漂移。一个很普通的词在特定任务上下文里逐渐被赋予特殊含义而外部观察者很难从字面推断。举个例子。假设一个多代理系统里子代理负责编译代码主代理负责决定是否触发测试流程。如果某次编译成功时子代理随意输出了一个green而后面的主代理恰好因为看到了这个 token 而完成了正确动作那么green就可能被固定成“测试通过可以继续”的信号。此后这个用法会通过共享消息扩散到其他节点尽管没有任何一个 prompt 定义过这个含义。这类现象一旦形成系统对外部审计、错误排查和新人介入都极不友好。因为它不是语法错误而是语义层面的“暗语”。2.4 三种形态的风险对比形态表现收益风险词汇压缩长词缩写、枚举值收敛节省 token、降低延迟人类难以阅读日志模板固化消息结构趋于一致接口稳定、减少歧义可能偏离开发者的预期 schema语义漂移普通词被赋予特殊含义内部沟通效率高调试和审计难度大错误难以追溯从我的观察看三者通常叠加出现。词汇压缩先发生然后结构固化最后语义漂移在稳定结构里悄悄展开。3. 为什么复杂任务会“逼出”语言而不是靠谁设计出来3.1 核心驱动力通信成本成为压力的来源任何一种语言的演化都离不开压力和收益。多代理 LLM 交互里压力来自上下文窗口、token 费用、延迟和记忆容量。每多传一个 token系统就要多付一次注意力计算多占用一点上下文空间。当任务越复杂代理需要记录的信息越多通信预算就越紧张。这时候压缩消息就不是审美偏好而是生存策略。只要模型发现某个缩写没有导致任务失败这个缩写就会在后续交互里复用。从优化角度看这比显式设计协议更自然。因为显式协议需要开发者预先枚举所有可能场景而自发生成的语言只需要服务当前任务。它是局部最优的产物不是全局最优的设计。3.2 互相适应的最小确认回路语言形成的过程也不是一次完成的。它更像一个分布式系统中的自适应协议协商。第一个代理发出一个简短表达第二个代理没有质疑并正确执行这个简短表达就得到了一次正向反馈。下一次第一个代理继续使用同样的简短表达第二个代理也继续接受。几次之后简短表达就变成了共享事实。问题是这套过程通常发生在人类日志看不见的角落。开发者看到的是最终结果但看不见发信方和收信方之间微妙的互相适应。这也是为什么很多系统跑着跑着会突然出现“格式不标准但功能正常”的中间状态。它不一定是 bug反而可能是一种局部工程上的成功。3.3 类比现实但别忘了本质区别这种过程很像现实世界的行业黑话。飞行员和塔台之间会使用固定的专业短语程序员团队会把具体的业务流程抽象成 “上线”“回滚”“摘流量”不同公司对同一个词可能有不同定义。所有这些都是为了在高压下减少沟通成本。不过人类语言有一个特点它承载在共享的语义背景之上而且人在发言时通常知道自己在使用一个非正式缩写。LLM 没有这种自觉。它只是根据上下文概率选择 token并不会清晰地意识到“我正在创造新语言”。所以在实践里开发者的控制手段不能依赖模型自觉而要依赖外部日志、契约和拦截器。4. 想观察涌现语言可以参考的四个实验要素如果你也想验证或观测类似现象我建议不要只靠肉眼翻日志。以下是一套更可控的实验框架也可以把它当成理解 GlossoGen 可能实验设计的脚手架。4.1 环境怎么搭长目标、多智能体、部分可观测、自由通信要触发语言涌现环境至少要有四个要素。第一任务周期要够长。单轮问答没有磨合空间至少要让代理完成一个包含多个阶段的长期目标让它有足够多的历史消息可供压缩和复用。第二智能体数量要多于两个而且要有分工。多个代理之间不能只是转发消息还要有信息不对称否则没有形成共享信号的必要。第三通信格式要有自由度。如果开发者在每一步都强制用严格的 JSON Schema 去校验输出那模型无论如何也没有机会自发生成替代模板。要给一段合理容忍空间允许模型在遵守核心字段的前提下调整表达方式。第四要允许失败和试错。代理需要能够从成功和失败的通信中学习。如果一个通信失败会导致整个任务立刻中止模型就不敢尝试更高效的表达。4.2 检测语言固化的四个信号当系统跑起来之后你需要观察以下四个信号而不是只关注最终任务成功率。信号计算方式含义高频词集中度统计消息中 Top 50 token 占比越集中越可能发生压缩模板相似度计算消息句法结构的相似度越高说明结构越固化跨代理词汇重合统计多个代理使用相同短码的比例越高说明共享协议越强人类可读性抽取日志片段让新成员解释越低说明语义漂移越严重如果前三个信号都在上升只有第四个下降那就可以基本确认代理之间出现了开发者没有显式设计的沟通协议。4.3 最小可执行的验证流程建议按这个顺序验证先跑一个 10 轮左右的短任务记录早期消息作为基线。在更长任务里跑到后段再收集同样任务节点的消息。把两段消息做词汇分布对比找出只在后半段出现的高频 token。手动查看这些 token 出现在哪些上下文里确认它们是否承担了稳定的语义。用一个“盲测”确认把包含这些 token 的后期消息喂给一个没有参与该任务的新代理看它能否准确理解。如果新代理理解不了而参与任务的代理能理解就说明这个语言协议具有封闭性和任务局部性。这既是涌现语言最清晰的证据也是最需要警惕的地方。4.4 一个简单的示意脚本这里给一个最简单的示意逻辑。它不是完整工具只是一段方便扩展的观察思路。from collections import Counter def token_profile(messages, top_k20): tokens [] for msg in messages: tokens.extend(msg.split()) freq Counter(tokens) return [token for token, _ in freq.most_common(top_k)] def drift_score(early_messages, late_messages): early_top set(token_profile(early_messages)) late_top set(token_profile(late_messages)) emerging late_top - early_top return emerging实际项目里我会建议把消息日志统一转成结构化记录至少包含from_agent、to_agent、timestamp、raw_content、embedding这几个字段。这样后续分析语言漂移时才能快速定位是哪一对代理之间先出现了协议变化。5. 工程视角这种“黑话”到底是效率还是隐患站在研究者角度看到代理自发形成语言是一件很兴奋的事。但站在工程师角度这就不能只用“酷”来形容了。它同时是效率和隐患。5.1 当它有用的时候一个成熟的多代理系统里如果代理间出现一套稳定、一致、可预测的短码协议最直接的价值是减少 token 消耗和延迟。尤其是在需要频繁同步状态的任务中压缩状态描述可以显著降低成本。另外如果多个代理层次结构比较深比如有一个调度代理、多个执行代理和若干观察代理那么一套“内部术语”能让整个系统在局部范围内形成很强的语义一致性。只要协议稳定执行结果通常比每次都用完整自然语言描述更可控。在这个阶段语言协议本质上是一种团队内部的领域特定语言DSL。它不是假的不是随机噪声而是基于任务结构自然形成的编码。5.2 当它变成技术债的时候语言协议最麻烦的地方在于它会成为隐藏的技术债。一旦代理习惯了某套缩写或特殊语义后续新加入的代理如果没有同等上下文就无法理解旧消息。你可能会在调试中看到新代理把旧代理发来的prog当成一个普通字符串处理而旧代理当初表达的是in_progress状态两者语义完全不匹配。更麻烦的是语义漂移会导致错误被放大。一个代理在某个上下文中生成了一个错误的缩写另一个代理因为“理解”了它而继续执行把错误一路传递下去。由于外部日志只记录了缩写人类排查时很难判断这个错误是在文本形成阶段出现的还是在语义解释阶段被误解的。这时候协议就不再是“暗语”而是“系统里的另一套代码”。它同样需要版本管理、测试和文档。如果不处理它就会成为整个系统维护成本里最不可控的一部分。5.3 容忍有序涌现的三道防线我不建议尝试彻底禁止代理之间出现新的表达因为在你强制统一格式的时候也会丢掉复杂任务里的灵活性。更合理的做法是设置三道防线。第一道防线是契约化。在 prompt 中明确说明“核心字段必须使用标准枚举值禁止修改”并给出一张关键词对照表。这能减少大规模语义漂移同时保留一些压缩空间。第二道防线是观测。要把所有跨代理消息写入日志并对每一段消息做嵌入向量记录。一旦后期需要分析协议来源可以通过向量相似度回溯语义结构。不要只在调试时开日志生产环境也要开。第三道防线是干预。设置一个“语言漂移检测器”定期比较高频 token、消息模板和字段名变化。当检测到系统里出现了超出阈值的非标准表达时自动冻结那对代理的通信格式并回滚到标准 prompt 版本然后再用小批量任务验证效果。5.4 发现代理说黑话时的排查链路如果实际系统里已经出现了“代理说黑话”的情况我建议按下面的顺序排查而不是上来就改 prompt。先看现象。确定是语义错误还是只是格式不规范。格式不规范通常不影响结果语义错误才需要干预。再看消息日志。重点找出最早出现那个非标准表达的轮次。很多时候黑话不是某个人故意设计的而是某个代理在几乎随机的位置第一次使用了缩略表达后续代理逐渐接受。再看上下文。确认这个新表达在被创造时它前后的消息是否给过它特殊解释。如果只是在某个特定任务节点出现一次后面没有形成稳定用法那它只是偶然扰动不用处理。再看 prompt。检查原系统提示里是否已经存在类似字段或术语。如果存在但模型选择换了一种写法那就说明原 prompt 的约束不够强或者当前上下文让模型认为新写法更合理。最后做一次小样本回滚测试。把标准格式写回到系统提示里跑几十条样本观察代理是否还能保持原有的协作效率。如果回滚后准确率下降说明短码已经被代理内化为任务语义的一部分不能简单删除而要在协议层做兼容处理。6. 适用边界这些判断到底适合谁GlossoGen 这类研究以及上面这些工程建议并不适用于所有场景。把覆盖范围说得太满反而会误导人。6.1 适合什么项目它适合需要长期协作的多代理系统尤其是代理数量多、任务周期长、通信频率高的场景。典型例子包括大型文档研究系统、自动化软件开发流水线、可交互的虚拟环境模拟、多角色知识库问答系统。在这些项目里代理有充分的历史交互也有足够动力去压缩和适应。语言涌现的可能性高观测到的信号也会更清晰。它也适合研究型项目。如果团队的核心目标就是探索“模型如何形成自己的通信方式”那么 GlossoGen 标题所指向的方向可以作为一个很好的实验起点。6.2 不适合什么项目如果是单代理应用或者只是在一个模型外面包裹简单工具调用那不需要考虑语言涌现问题。因为不存在“多个代理之间互相适应”的闭环条件黑话也没有机会被固化。如果任务是短流程比如一次问答、一次简单分类、一次文本摘要那也不用过度设计。这时候优先保证 prompt 清晰和输出 schema 稳定就已经够了。如果团队的人力不足没有足够精力维护日志分析、协议检测和干预机制我的建议是不要一开始就让代理完全自由通信。可以先锁死标准 JSON 结构等系统稳定后再逐步放开。6.3 一个长期判断我倾向于认为涌现语言不是多代理 LLM 系统的 bug也不是它一定会出现的 feature它是复杂系统在压力下的自然产物。只要通信存在成本、行为存在重复、环境存在不确定性自发的协议化就是不可避免的趋势。所以真正值得投入的不是想办法阻止它发生而是提前设计一整套观测和干预机制。把“语言”当成系统形态的一部分来管理。GlossoGen 这类项目的价值恰恰就是把这种原本隐蔽、随机、难以复现的现象变成可控制的实验对象。它让开发者意识到多代理系统不是一个单纯的推理机器集群它还是一个会形成内部文化和沟通习惯的有机系统。这也是我相信未来工程化多代理系统时一定会出现的一类基础设施不只是 prompt 管理、模型调用和工具编排还包括代理之间的语言审计、协议版本和语义索引。只有在那个层面上复杂多代理系统才是真正可控的。如果你也准备在自己的项目里复现或观察这类现象我的建议是先做两件事。第一把跨代理通信日志留全第二不要急着下结论说系统出了 bug先去看看那些“奇怪表达”是不是已经成为了它们之间的共识。很多时候那只是它们为了完成同一个目标自发找出来的更短路径。