前一阵调一套多代理系统,我习惯把每轮 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_k=20): 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,先去看看那些“奇怪表达”是不是已经成为了它们之间的共识。很多时候,那只是它们为了完成同一个目标,自发找出来的更短路径。