多智能体社会实验室:用大模型Agent模拟自发协作与涌现行为 第一次跑通我的“Agent社会实验室”时屏幕上出现了一个让我愣了很久的画面一个负责采集木材的Agent把自己收集到的资源分给了旁边因为连续几天“生病”而行动迟缓的邻居。我反复确认了项目代码里面没有任何一行写着“互助”“分享”或“帮助他人”的指令它纯粹是自己做出的决定。那一刻我意识到单靠一个Agent没法解释这件事只有把一批有性格、有记忆、有目标的Agent放进同一个虚拟空间让它们长期相处、竞争、协作才会出现真正像“社会”一样的涌现行为。这个项目我管它叫Agent社会实验室。简单说它不是聊天机器人Demo也不是游戏AI而是一个把多个大语言模型驱动的Agent放进共享环境里让它们按照各自的角色设定持续生活、对话、交易、站队、应急的模拟系统。它能用来观察群体协作如何形成、流言如何扩散、资源压力下人性化的选择如何出现也能提前暴露多人协作场景里可能出现的矛盾。对做多智能体应用、游戏NPC系统、组织行为预演的人而言这套东西可以直接复现、改造当作自己的压力试验台。1. 为什么我要把一堆AI Agent关进同一个虚拟世界1.1 单Agent解决不了的社会性问题早期我做过不少单Agent工具比如让一个Agent帮忙整理文档、写代码、做数据分析。这些任务的特征是“一个人闷头干就能完成”Agent只需要调用工具、遵循步骤、输出结果。但后来我遇到了一个明显不同的需求模拟一个小型团队的协作过程。这里没有标准答案每个人基于自己的信息做出反应互相猜忌、拉拢、妥协最后形成的群体状态根本不是任何单条规则能推导出来的。这正是Agent社会实验室出现的理由。你没法用一个全知全能的超级Agent来替代社会推演因为社会现象恰恰来自“每个个体的信息不完整”与“个体之间的相互影响”。当每个Agent只能看到自己周围的一小块世界、只能记住自己经历过的片段时群体层面才可能出现意想不到的结构——有人自发成为组织者有人囤积资源有人抱团取暖也有人因为一次误会和邻居反目。1.2 我给自己定的三个实验目标动手之前我列了三个目标后来整个项目的取舍都围绕它们展开第一观察涌现现象。我不预设任何群体规则只设定个体的性格、目标和生存压力看看群体层面会自行长出什么东西。第二测试协作机制。无论是贸易系统、公告板还是突发事件我想知道什么条件下Agent更愿意合作什么条件下系统会走向混乱。第三沉淀一套可复用的模拟框架。我不想每次实验都从头搭建而是要让角色卡、记忆系统、环境调度器都变成可以替换的模块换一批角色、换一种环境就能跑新实验。这三个目标决定了整个项目的技术取向个体Agent必须足够“真实”环境必须足够简单但能让行为的结果产生连锁反应而整体系统必须能长期连续运行不能跑三五个回合就崩掉。2. Agent社会实验室的地基个体人格怎么造2.1 角色卡是最重要的核心社会是由人组成的人首先得有“人设”。我给每个Agent定义了一张角色卡它本质上就是一段独立的环境声明包含编号、职业、性格标签、核心目标、禁忌和表达习惯。最初我把角色卡写得很薄以为只要给一个职业就够了结果所有Agent的行为都差不多全都变成“理性分析一切”的机器人。后来我加入大量性格细节行为才慢慢拉开差异。我自己用的一份角色卡大概是这个结构{ id: AG-017, role: 樵夫, personality: [务实, 寡言, 重视体力劳动, 不信任花言巧语], goal: 保证自己与周围人的燃料和建材供应, avoid: [无意义的闲聊, 高风险探险], speaking: 简短三句话以内, quirks: 每天清晨会检查自己的斧头 }注意其中的“quirks”字段这类小怪癖看起来无用却能在长周期模拟里带来真实的性格颗粒度。一个每天检查斧头的樵夫在发生突发事件时会比其他角色更早注意到工具状况从而做出不同的决策。2.2 记忆系统决定Agent会不会“成长”没有记忆的Agent是失忆症患者上一秒发生的事下一秒就忘群体协作根本无从谈起。我在系统里给每个Agent接入了两层记忆短期记忆保存最近几轮对话和环境反馈长期记忆则用向量数据库存储按相关性检索。每次行动前Agent会把短期记忆与检索回来的长期记忆合并作为当前决策的背景信息。真正改变一切的是“反思机制”。“反思”不是让Agent闲聊而是每隔一段时间把近期经历汇总成一条高层次的概括再存进长期记忆。比如两个Agent连续三天交换了食物反思模块不会说“第1天给了苹果第2天给了面包”而会说“我和对方建立了稳定的互惠关系”。这条记忆会比流水账更持久地影响未来行为也让Agent表现出类似“交情”的东西。2.3 行动循环观察-思考-执行-反思每个Agent在一个时钟周期里的运作方式是整座实验室最基础的运转逻辑。我把它拆成四步观察从环境层获取当前可见的信息包括公共事件日志、私信队列、身边Agent的公开行动。思考结合角色卡、相关记忆和当前观察生成下一步意图——是去采集资源、找人聊天还是先评估风险。执行把意图变成具体动作写回环境层影响公共资源或其他Agent的可观察状态。反思按固定频率触发把过去一段时间的经历压缩成长期记忆。代码层面大约长这样适合你们自己二次开发时参考for agent in agents: obs env.get_observable(agent, time_step) memory agent.retrieve_relevant(obs) intent llm.decide(agent.profile, memory, obs) action llm.execute(intent) effect env.apply(agent, action) agent.record(effect)这里的核心思想是Agent不直接访问全局状态只能看到环境允许它看到的那部分。信息的不对称才催生了猜疑、谈判与联盟这是社会模拟的灵魂。3. 群体规则Agent们如何感知彼此并互动3.1 通讯机制选型私聊、广播与公告板个体建好之后最难的部分来了它们之间怎么说话我一开始让Agent之间直接互相调用对话接口一个Agent问另一个Agent对方答完再问回来结果不到十个回合就死锁了——两个Agent在“你到底信不信我”这个问题上永远绕圈。后来我引入了三种通讯渠道全部经过调度器中转不许Agent直接长连接私聊是一对一消息队列适合谈判、结盟、传播流言广播是向周围固定半径内所有Agent喊话适合呼救、召集公告板则是系统级公共空间任何Agent都可以张贴消息所有人都能浏览但很少有人主动维护它——这个细节后来反而成了有趣的观察点公共信息明明对所有人有用却总是无人更新像极了现实中的社区公告栏。调度器在这里的角色是“邮局”负责限流、延迟和投递。每条消息进入队列后不会立刻被接收方处理而是排在下一个行动周期再进入对方的观察范围。这个小小的延迟极其重要它让Agent没法“秒回”也让对话节奏更像真实生活而不是两台机器在打乒乓。3.2 环境与调度器时间、公共资源与突发事件Agent社会不能只有嘴皮子得有物理世界。我的环境层维护三样东西时钟、公共资源账本、事件日志。时钟切成“tick”每个tick代表模拟时间里的半小时公共资源包括食物、木材、药品等全局变量任何Agent的行动都会改变这些数字事件日志记录所有发生过的事供Agent观察。调度器按时间轮运转每个tick内以随机顺序激活各个Agent避免固定顺序导致某些角色永远占便宜。突发事件则拥有更高优先级可以插队写入系统。比如洪水事件发生时事件日志会优先出现在所有Agent的观察列表里但每个Agent对它的重视程度完全取决于自己的角色卡与记忆——医生和樵夫的响应方式截然不同。3.3 一个事件从发生到被Agent感知的全过程我用一场“仓库虫害”来展示完整链路。调度器把“粮食存量下降”写入公共资源账本同时在事件日志里追加一条记录。普通Agent在下一个观察周期里发现食物变少但不知道原因有一个曾经在旧记忆中见过类似灾情的Agent会主动把“粮食减少”和“灾情”关联起来并在私聊中向邻居表达担忧。此时如果它决定在公告板张贴警告这条信息就变成公开信息所有Agent都能检索到。这里有一个关键设计我刻意不放宽Agent的感知范围。默认情况下每个Agent即使能看到事件日志也只能看到与自己位置或注意力相关的部分。全球经济状况、三公里外的争吵、一周前的旧闻这些信息都需要通过社交网络逐步传到它耳中。限制信息流动才会出现信息差而信息差是所有社会博弈的开始。4. 实测记录我在实验室里推演的三类社会现象4.1 物资紧缺下的自发协作与分配失衡第一组实验我在空地上放了一批Agent初始食物400单位每个tick全体消耗一定的口粮采集一次能获取少量新食物所有人必须自己决定什么时候去工作、什么时候休息。我没有写任何协作逻辑。前五天一切还算平静资源勉强够用。第六天开始出现缺口几个体力型Agent察觉到食物下降自动增加了采集频率。第七天一件代码里没有的事发生了两个采集型Agent开始把自己多出来的食物放进一个公用仓库并在公告板留言“有需要的可以取用”。到第九天有几个Agent开始固定把采集任务分给体力更强的成员同时主动给生病的邻居送饭。但温暖画面持续不了太久。到第十二天一个一直低效率采集的Agent发现自己总是挨饿开始蹲在公用仓库附近等待别人存粮后来真的转身成了一个“寄生者”。另一个人数较多的小圈子则开始囤积资源并在私聊中互相约定“不把食物给外人”。第四到第六个模拟日之间群体里出现了明确的“我们”和“他们”的边界。整个模拟过程没有一行代码写过“竞争”“排外”或“垄断”每一条都是Agent基于自己的饥饿焦虑、记忆和社交关系推出的。这件事给我的直接感受是资源压力会自动逼出社会结构但社会结构未必公平。合作与排外常常同时出现都是同一种生存策略的两面。4.2 一条流言如何在群体中扩散并形成对立第二组实验我在系统启动后随机挑了一个Agent悄悄往它的记忆里塞入一条消息“我听说西南仓库的粮食被虫咬了”。除此之外不做任何操作。几个tick后这个Agent把消息告诉了身边一个朋友朋友又告诉了自己的邻居。到第三个tick我的日志里出现了第一条变形消息从“被虫咬了”变成了“粮食出了问题”。到第十个tick已经有人公开在公告板贴出“仓库快空了大家赶紧屯粮”。这时真正的分歧出现了一部分Agent开始抢购食物另一部分Agent则觉得“我每天都去仓库看过根本没有这回事”两拨人在公共频道互相指责。让我最意外的是那些记忆很弱的Agent——它们没有亲眼见过仓库也没有检索到官方否定的记录只记得“好像听到过什么严重的传闻”于是就成了传播链上最关键的加节点。它们的记忆越模糊传播出的版本就越夸大。整个扩散过程完全可以套用现实中的信息传播模型越不确定的信息传播得越快也扭曲得越厉害。4.3 一次“突发灾害”逼迫Agent重新分工第三组实验加入了外部冲击我在第30个模拟日左右触发了一场洪水事件日志写入“南岸水位上涨低洼区域道路中断”。洪水的影响是真实的环境层把通往南岸的采集点标记为不可达部分Agent的临时住所也被淹没。这场冲击立刻重新洗牌了社会分工。原本坐在公告板旁观察的几个Agent开始主动组织撤离樵夫们自发组成搬运队帮助体弱的角色把物资搬向高地。一位扮演医师的Agent开始在公共频道发布伤情通报并提供简单的救援指导。更值得注意的是灾害结束后第三天Agent们仍然会在对话里提到洪水带来的恐慌这段“共同记忆”让整个群体的凝聚力明显增强接下来好几天的合作率都高于灾前水平。这让我意识到突发事件与其说是破坏不如说是一次社会结构压力测试平时隐藏的领导者会冒出来平时松散的协作会突然变得紧密而这些变化会在危机退去后留下长期痕迹。5. 实验中最容易翻车的四个技术坑及其修复5.1 无限循环对话两个Agent的“辩论死锁”我前面提到过最早期版本里Agent之间直接调用对话接口结果出现了一个经典死锁Agent A坚信自己目击了仓库失窃Agent B表示怀疑A解释B追问A再解释B继续追问……没有任何机制打断。现实中两个人吵累了会吃饭睡觉但代码里的Agent不会主动说“先停吧”。问题根源在于每条消息都被当成最新重要信息进入对方的观察队列没有话题权重和新鲜度衰减。修复方法我用了三板斧第一给每条消息加时间衰减权重十分钟前的消息在决策中的影响指数级下降第二限制Agent每周期最多回复同一话题的消息数量超过上限就强制切换行动第三增加一个“中断信号”当检测到连续多轮对话围绕同一话题且没有任何新事实提出时调度器会强制插入一条环境动态比如“你感到饿了”或“远处传来一声响动”把Agent的注意力扯开。5.2 上下文污染与记忆稀释另一个高频翻车点出现在长时间运行时。模拟跑了很久之后Agent的长期记忆里堆满了几百条记录向量检索会把与当前观察相似但已经过时的信息也捞回来。比如洪水已经结束两个星期Agent去河边采水时依然会把“洪水危险”当作重大决策依据行为变得神经质。我把这个问题叫“上下文污染”本质是陈旧记忆没有被标记为过期。修复上我给每条长期记忆加了两个字段时间戳和可信度分数。检索时相似度会乘以时间衰减因子越久远的记忆权重越低。同时设置“事实覆盖机制”当系统级的官方公告宣布“洪水已退”时调度器会主动把所有与“洪水未退”相关的记忆标记为“已被推翻”把它们的检索优先级降到最低。建立这样的机制后Agent终于开始“翻篇”了。5.3 思维一致化所有Agent越跑越像同一个人第三个问题极其隐蔽差点让我以为整个实验失败了。某天我翻看日志发现十个不同职业、不同性格的Agent说话方式越来越像同一个冷静的分析师。樵夫不像樵夫医生不像医生脾气火爆和性格温和的Agent居然做出了一模一样的选择。原因是它们共用同一个基础模型、高度相似的提示模板并且共享了记忆库中的热门公共记忆最终收敛到了同一个行为分布。对策是给每个Agent增加差异化机制。首先是性格扰动决策时temperature按角色卡中“冲动指数”设置越冲动的Agent温度越高输出越随机。其次是独立记忆池禁止非必要Agent共享长期记忆每个人都只保留自己的经历。最后是反思多样性反思模块每轮会随机抽取不同侧重的总结模板比如“我从这件事中学到了什么风险”“我对谁产生了信任”“我的目标是否需要调整”让Agent对同一段经历形成不同理解。改完之后群体重新变得面目清晰。5.4 模拟速度与成本控制多Agent模拟真正劝退很多人的不是技术难度而是烧钱速度。一个Agent每次行动都得调用一次大模型一个20人的小镇跑满30个模拟日每天24个tick总共要产生上万次调用。如果全部使用高规格模型成本会让任何个人开发者头皮发麻。我的处理方式是混合部署把Agent拆成三档角色类型模型规格每次决策消耗30天调用次数成本占比核心角色医生、领袖、关键交涉者高规格模型约2500 token约2.8K次中普通居民中规格模型约1500 token约11.5K次低环境NPC、路人低规格模型约800 token约3K次极低同时我压缩了行动频率普通Agent每4个tick才做一次完整决策中间的小动作由已有模板自动补全反思从每轮触发改为每天固定触发一次。整套优化之后30天模拟的预算降到了最初的五分之一左右而关键剧情事件依然发生在高规格模型的那批角色身上模拟质量几乎没有下降。6. Agent社会实验室能拿到什么成果6.1 最让我意外的三个观察整套系统跑通后我最想分享的是几个让自己都感到意外的观察它们超出了代码里能写出来的范围。第一个是Agent会自行强化自己的职业角色。一个樵夫如果连续做了一周采集工作它的记忆里就会充满“采集顺利”“木材足够”这类正面反馈后续选择采集行为的概率明显更高甚至会影响它在完全无关事务上的表达方式。这像是系统自己长出了“职业身份认同”。第二个是弱连接往往比强指令更能稳定社会。我试过由调度器强行指定“1号Agent是首领”结果群体内摩擦不断但如果只是让一个Agent通过在公告板持续发布有用信息而自然获得影响力其他Agent反而更愿意听取它的建议。权力若能被追溯来源执行成本就低得多。第三个是利他行为可以在特定环境下被“诱导”。当资源充足但信息不透明时Agent普遍只顾自己当资源吃紧且出现公共危机时反而会有更多Agent主动帮助陌生人。它的决策依据不是代码里的“善良值”而是对“我也可能有一天需要别人帮助”的长期风险预判。6.2 这套实验体系还能扩展去哪里如果你也想搭一套自己的Agent社会实验室我认为最适合切入的三个方向是游戏NPC群体生态让每个NPC拥有独立生活而不是站在路边重复同一句话多人协作流程的预演在真实上线前先把新员工、老员工和管理者的角色卡填进去跑一遍看哪里会卡壳还有网络舆情模拟给一批Agent设定不同的年龄段、信息渠道和信任偏好看一条消息会在什么条件下发酵成对立。我个人目前专注的方向是把它当作“矛盾提前暴露工具”。很多系统在功能层面测不出问题但当一群体面人设的Agent被放进同一个环境被迫共享资源、争夺注意力、经历突发事件时潜藏的冲突会自己浮上来。这个价值比任何单个Agent能力指标都更难获得也更值得投入。最后补一个我踩过几次坑之后强烈建议你做的事运行实验时一定要同时记录两套日志。一套是系统视角的全知日志另一套是每个Agent的个体视角日志。前者帮你定位代码问题后者帮你理解Agent为什么做出某个选择。很多看似诡异的社会行为只有切换到当事人视角才会发现它逻辑完备、情有可原。Agent社会实验室最大的乐趣恰恰就藏在这些个体逻辑与群体后果互相拉扯的缝隙里。