LLM多智能体经济仿真实验:100个Agent的货币为何停止流动?
2026/9/15 1:57:05 网站建设 项目流程

看到这个标题,我第一反应是:这不就是我上个月那个复现实验的死法吗?100 个 LLM agent 在一座虚拟小镇里各自生产、买卖、雇佣,跑满 26 周之后,货币终于停在某个账户里再也不动了。很多跑过 Agent 仿真的朋友应该都有同感——让 LLM agent 聊天容易,让它们形成持续的经济循环,太难了。这篇博客就把这个实验从头到尾拆一遍:实验怎么做、agent 怎么活、钱是怎么一步步死掉的。适合正在做多智能体仿真、LLM agent 应用开发,或者单纯对“AI 社会实验”感兴趣的人参考。

1. 这个实验到底在模拟什么:从 100 个 agent 到 26 周

1.1 为什么用 LLM agent 而不是传统智能体

我见过太多人一提到经济仿真,第一反应是用纯数学建模:设定一组供给函数、需求函数、价格弹性,然后解一个方程组。那种做法很成熟,但它模拟的是“人假设出来的理性行为”,不是“人在具体环境里长出来的行为”。LLM agent 不一样,它每一步决策都是自然语言推理出来的,会受到记忆、情绪、偏见和上下文影响,所以会做出很多传统模型根本预测不到的事情。

举个例子。传统模型里,一个面包师“决定”涨不涨价,是由价格弹性系数算出来的;而在 LLM agent 实验里,面包师会看到“最近顾客抱怨面包太硬”这条记忆,于是决定降价同时改进配方。这种决策很难提前写成规则。100 个 agent 各自有身份、目标、技能和社交圈,它们之间的对话和交易又相互影响,整个经济系统就变成了一种涌现行为。

这也是为什么很多论文和团队开始用 LLM agent 做社会仿真。相比传统 ABM(Agent-Based Modeling),LLM agent 最大的优势是“行为合理但不完全确定”。同样的初始条件,跑到第 10 周可能有的小镇繁荣,有的小镇萧条。这种多样性恰恰是研究经济系统最需要的。

1.2 26 周这个时间窗口为什么是关键

我看到这个实验的设置是 26 周,第一反应是“很典型的半年级实验周期”。如果只跑 4 到 8 周,agent 的初始库存还没消化完,关系网络也刚刚建立,经济趋势根本看不出来。但如果跑到 52 周甚至更久,一方面 LLM 调用成本会涨得离谱,另一方面很多 agent 在中期就会出现严重的记忆混乱,最后得出的结果很难说到底是经济规律还是模型失效。

26 周正好落在“短期噪声过去、长期趋势显现”的窗口里。按我的复现经验,前 2 到 4 周属于起步期,大家在熟悉环境和角色;第 5 到 12 周是活跃期,交易频繁,价格也能稳住;第 13 到 20 周开始,贫富差距拉大、部分角色失去需求,交易量会出现明显下滑;第 20 周之后如果不做干预,整个系统就进入“慢性死亡”阶段。所以 26 周这个长度,刚好能把经济从上行到停滞的完整生命周期展示出来。

有朋友可能会问,为什么是“货币停止流动”而不是“系统崩溃”?因为 agent 不会像服务器那样直接宕机,它们还在对话、还在生产、甚至还在打招呼,只是没有任何交易发生了。这个状态其实比崩溃更值得分析,因为它说明经济结构出了问题,而不是技术栈出了问题。

2. 让 agent 活起来的关键细节:记忆、决策与环境交互

2.1 记忆系统的设计:短期上下文 + 长期档案

刚开始跑这种大规模 LLM agent 仿真时,我犯过一个错误:以为把整段历史都塞进 prompt 让模型看就行。实际上 26 周里 100 个 agent 的交互日志,怕是几百万 token 都不够,别说上下文窗口放不下,就算放得下,普通开源模型也早就“记不清前面发生了什么”。

实验中真正能落地的是分层记忆结构。我给每个 agent 设计了三层记忆:第一层是角色长期档案,写清楚身份、目标、技能和性格,这部分基本不变;第二层是阶段性摘要,每 4 周把这段时间发生的关键事件压缩成一段话,比如“你是小镇里最受欢迎的铁匠,上周接到了 3 个工具订单”;第三层是工作记忆,也就是最近一周的具体事件和对话。

实际跑下来,我建议不要把第三层做得太长。25 个事件或 4000 个 token 左右就够用了,太长反而会让模型在当前决策和旧记忆之间反复摇摆。另外要给记忆打上时间戳,避免 agent 用三个月前的库存信息来做今天的采购决策。这看起来是细节,但对经济系统的影响非常大,因为一旦 agent 基于过期信息做决策,市场就会产生一堆虚假供需信号。

2.2 决策循环:感知 → 计划 → 行动 → 观察

LLM agent 的决策不是简单调用一次 API 然后等输出,而是要走一个完整的循环。我用的循环结构是:感知环境 → 检索记忆 → 生成计划 → 执行工具调用 → 观察结果 → 更新记忆。

感知环境这一步,agent 能看到的信息包括当前金币数、库存、本周市场上挂出的订单、自己和几个关键角色的关系值。这里有个很容易踩坑的地方:如果你把所有市场信息全部塞给 agent,它会陷入“信息过载”,决策质量反而变差。更稳妥的做法是只把与它角色相关的订单展示出来,比如铁匠只看工具类、木材类订单,不要让铁匠去关注面包价格。

生成计划时,大多数实验会让 LLM 直接输出 JSON 格式的动作,常见的动作就是“生产、购买、出售、雇佣、社交、休息”。我不建议让 agent 输出自然语言再让解析器去匹配动作,那样很容易出现语义歧义。项目里我用的是函数调用或者严格 JSON Schema 输出,这样解析起来最稳。

2.3 经济交互:市场、价格与账户怎么落地

这个实验里最核心的经济交互就是交易。我复现时采用的是“集中市场 + 每周结算”的模式:每天 agent 可以提交买卖意图,系统按价格和时间优先原则撮合,每周结束后统一结算账户和库存。

价格形成机制上,第一次跑的时候我用的是“双向拍卖”,让买卖双方各自报价,系统撮合。这个方式很经典,但是对 LLM 调用量消耗极大,每个 agent 每轮都要出价,100 个 agent 跑起来成本很高。后来我调成“参考价 + 波动”:系统维护一个商品的基础价格,agent 可以在基础价上下 20% 的区间内报价,这样就大幅降低了决策复杂度。

账户和库存校验是最容易被忽略的部分。很多 agent 模型框架里,工具调用失败就失败了,但在经济系统里,余额不足会导致交易取消、违约记录、信誉下降,进而影响后续合作。所以我在账户上做了硬校验:不允许负余额、不允许卖出自己没有的库存,所有交易必须走统一结算接口。之后你会发现,什么时候开始频繁出现“余额不足”报错,往往就是经济危机的第一信号。

3. 逐步搭出一个能跑 26 周的仿真环境

3.1 最小可行版本:参数、角色与初始资源

如果要从零开始复现,我不建议一上来就设计 100 个不同的角色,那只会让你在调 prompt 的时候疯掉。我建议先设计 10 个角色,跑通流程后再扩展到 100 个。

下面是我实际用过的初始设定,你可以直接抄作业。角色类型包括:农民、面包师、铁匠、矿工、木匠、伐木工、裁缝、商人、医师、旅店老板。每个角色的初始金币我设置为 800 到 1200 之间随机,初始库存按角色配置,比如农民有 30 单位小麦种子,面包师有一间烤炉和 10 单位面粉,商人只有 500 金币和 5 单位杂货。

这里有一个很重要的设计:每周每个 agent 要缴纳 8 金币的“社区维护费”。这个费用设定有两个目的,一个是给系统一个持续的通缩压力,让 agent 不能躺着吃老本;另一个是创造一个强制需求,让 agent 必须每周都想办法赚钱。很多实验跑不出经济衰退,就是因为 agent 没有任何固定支出,攒够钱就躺平,经济自然冻结。

另外建议把时间粒度设为“1 周 = 1 个决策周期”,agent 每周只做一次大决策,比如“这周我全力生产工具”或“这周我外出社交找合作”。如果时间粒度过细,比如每小时决策一次,100 个 agent 跑 26 周的成本会高到难以承受,而且行为也不会更真实。

3.2 关键代码骨架:agent 主循环与工具函数

代码层面我建议保持精简。下面这个骨架是我反复迭代后的一个稳定版本,用 Python 写,重点是让你看清 agent 主循环的逻辑,而不是追求工程上的复杂。

from dataclasses import dataclass, field import json @dataclass class AgentState: id: int role: str gold: float inventory: dict # 商品名 -> 数量 long_term_memory: list = field(default_factory=list) short_term_memory: list = field(default_factory=list) reputation: dict = field(default_factory=dict) @dataclass class Order: agent_id: int order_type: str # "buy" 或 "sell" item: str quantity: int price: float def build_context(agent: AgentState, world_state, week: int) -> str: context = f"你是一个{agent.role},当前是第{week}周。\n" context += f"金币:{agent.gold:.2f},库存:{agent.inventory}\n" context += f"本周市场订单:\n" for order in world_state.orders[-20:]: context += f"- {'买入' if order.order_type == 'buy' else '卖出'} {order.item} x{order.quantity},单价 {order.price:.2f}\n" context += f"近期记忆:\n" context += "\n".join(agent.short_term_memory[-5:]) return context def agent_step(agent: AgentState, world_state, llm_predict_fn): prompt = build_context(agent, world_state, world_state.week) response = llm_predict_fn(prompt) try: decision = json.loads(response) except json.JSONDecodeError: decision = {"action": "wait", "reason": "解析失败"} execute_action(agent, world_state, decision) def execute_action(agent: AgentState, world_state, decision): action = decision.get("action") if action == "produce": recipe = world_state.recipes.get(decision.get("item")) if not check_inventory(agent, recipe.inputs): agent.short_term_memory.append("想生产但原料不足") return consume(agent, recipe.inputs) add_inventory(agent, recipe.output) agent.short_term_memory.append(f"生产了{recipe.output},花费{recipe.cost}金币") agent.gold -= recipe.cost elif action == "sell": order = Order(agent_id=agent.id, order_type="sell", item=decision["item"], quantity=decision["quantity"], price=decision["price"]) if validate_sell(agent, order): world_state.orders.append(order) elif action == "buy": order = Order(agent_id=agent.id, order_type="buy", item=decision["item"], quantity=decision["quantity"], price=decision["price"]) if validate_buy(agent, order): world_state.orders.append(order)

这个骨架里最核心的一点是所有操作都要经过校验,不能允许 agent 凭空卖出自己不存在的商品,也不能允许它抵押未来的收入进行透支。真实经济系统里当然有借贷,但那属于另一个模块,建议第一版先砍掉。跑通基础交易后,再慢慢加入雇佣、投资和借贷。

3.3 每一周结束后的数据统计与干预点

只看交易日志是看不出经济趋势的,必须每周做一次数据统计,把整个系统的状态数字化。我每周必看的指标有五个:交易总量、参与交易的角色比例、平均成交价、库存积压量、货币集中度。

货币集中度我用基尼系数计算,这个数字在实验中非常重要。我见过一个很真实的现象——前两周基尼系数只有 0.35,看起来还算健康;第 10 周涨到 0.55,第 16 周突破 0.7,这时候再往后跑,交易量就会断崖式下跌。因为货币已经集中到了少数几个商人手里,其他人没有购买力,市场也就没有流动性了。

干预点要不要设计?这取决于实验目的。如果目的是观察“自然状态下经济会不会停滞”,那就不做任何干预,让系统自己演化;如果目的是验证“外部投放货币能否延长系统存活”,那可以在固定的周次注入新货币,比如设置第 10 周、第 20 周各注入 5000 金币并定向分发给低收入 agent。我建议第一遍跑的时候先不加干预,因为你只有看过完整的死亡曲线,才知道干预的价值在哪里。

4. 为什么货币最终停止流动:我复盘出的 6 个原因

4.1 目标饱和:所有 agent 都“赚够了”

这个原因最容易被忽略,却是我复现时第一个踩中的坑。很多实验在设计角色 prompt 时,会给 agent 一个目标,比如“存够 3000 金币就退休”。前几周 agent 都干劲十足,可当一部分人真的达到目标后,它们就开始减少生产和交易频率。

问题在于,经济系统是需要持续买卖的,只要有一部分人退出交易,另一部分人的收入就会下降;收入下降之后,那些计划攒钱的人发现“怎么越攒越少”,于是只能更拼命地生产,结果生产出来的东西没人买,形成恶性循环。我的建议是,给 agent 设计“消费型目标”而不是“储蓄型目标”,比如“想给自己建一栋新房子”或“想买一套高级工具”,这样需求会一直存在,而不是赚够就躺平。

4.2 通缩预期:agent 学会了“等等再买”

这个现象非常有意思。当市场连续几周出现价格下跌时,LLM agent 会从自己的记忆里学到“东西越来越便宜”,于是它的决策会倾向于“再等等,晚点买更划算”。所有买家都开始等待,需求就会骤然萎缩;卖家为了吸引买家只能继续降价,于是形成自我实现式的通缩螺旋。

如果 agent 是传统的数学建模个体,它只会在价格低于某个阈值时买入,不会产生“预期”这种微妙的东西。但 LLM agent 会结合近期的记忆做趋势判断,这个能力在大部分时候是好事,但在通缩环境里反而会加速经济崩溃。解决办法之一是给商品设定价格下限,让卖家不能无限降价;也可以用社区舆论机制,让“对未来价格感到乐观”的 agent 在公共对话中发出信号,稳定群体的预期。

4.3 货币蓄水池:少数 agent 掌握了大部分余额

跑这种实验,你一定会在某个节点发现,货币并不是均匀分布在所有人手里的,而是大量沉淀在少数几个“聪明”的 agent 手里。这些 agent 通常扮演商人或大户,它们懂得低价囤货、高价卖出、合理控制库存,结果就是利润不断向它们集中。

当大部分 agent 的余额接近零时,即使系统里还有充足的货币总量,市场上也没有足够的需求方。这就是我前面提到的基尼系数飙升阶段。很多初学者看到总货币量没变,就以为经济是健康的,但结构问题已经非常严重。实验里如果想避免这种单一结局,可以给商人角色加一个“高库存成本”,让商人不能无限囤货,逼着它把钱重新花回市场。

4.4 记忆与上下文的失真:agent 选择性遗忘交易机会

还有一个技术层面的原因。到第 15 周以后,agent 的长期记忆摘要已经非常长,你在构建 context 时必然会做截断。截断的逻辑决定了 agent 还能记住什么——如果它的工作记忆里只剩“最近很穷”这样的情绪性总结,而忘了“上周有农民找我预购工具”这样的具体线索,那它就会做出相当保守的决策。

记忆系统在这里成了经济系统的“信息瓶颈”。我实际对比过不同记忆方案:只保留摘要时,经济衰退速度明显更快;保留关键交易细节和人物关系时,经济活跃期可以延长到 20 周左右。所以如果你发现实验里的 agent 行为越来越“呆板”,先别急着怪模型,回去查查它的记忆里到底还剩下什么。

4.5 工具链的意外失败:不是不想买,是买不了

这个原因很不“经济学”,但特别现实。LLM 在生成 JSON 动作时,可能偶尔会生成一个非法的数字字段、一个不存在的商品名,或者一个超出合理范围的离谱价格。你的解析器要不就得容错,要不就返回“wait”动作,让 agent 这周什么都不干。

当一个 agent 连续几周工具调用失败时,它的行为就会变得消极,甚至从记忆里得出结论“这个市场交易太困难了,不如自己闷头生产”。这会导致整个市场的有效交易量比决策量低不少。排查方法是单独统计“工具调用成功率”,我建议至少保持在 95% 以上。如果低于这个值,你需要重试机制或者更宽松的解析规则,而不是把锅甩给模型能力。

4.6 缺少外生货币注入:系统从内生循环走向焓死

最后回到一个基本的宏观经济学问题:任何封闭的内生循环,都会因为储蓄、损耗、费用上缴而逐渐失去流动性。现实经济体中总会有某种外部资金投放机制,比如基础设施支出、社会福利发放、出口收入等,让新的货币进入市场。但在很多仿真实验里,这部分被省略了。

加上我前面提到的每周社区维护费,100 个 agent 每周要上交 800 金币,26 周就是 20800 金币退出流通。如果系统没有任何外部注资,这笔钱就被“烧”掉了。初始总量 10 万金币看似很多,去掉维护费、再减去一部分被囤积的份额,真正在市场上流动的货币会越来越少,直到临界点。货币停止流动不是随机事件,而是内生系统的必然归宿。

5. 常见问题与排查技巧实录:这条死亡曲线我完整跑过

5.1 这些坑我全都踩过,帮你提前避开

第一个坑是“所有 agent 共用一套 prompt 模板”。我一开始为了让代码统一,写了同一个系统提示词,只是把角色名替换一下。结果跑出来的 agent 行为超级一致,大家全都倾向于“稳一点、多存钱”,没有人愿意冒险投资,经济活动很快就收缩了。后来我给每个职业写了附加的角色卡,包括性格偏好和风险承受度,情况才明显改善。

第二个坑是“交易异步结算搞出来的超卖问题”。多个 agent 在同一周同时提交卖出订单,系统如果没有统一结算,很容易出现库存明明已经被卖给甲了,又签给乙的情况。我后面引入了“订单簿冻结机制”,撮合之前先锁定库存,结算完成后再释放,这才解决了重复卖货的问题。

第三个坑是成本估算失误。100 个 agent 跑 26 周,每个 agent 每周至少一次 LLM 调用,这就是 2600 次调用;如果你还加了对话、社交和雇佣模块,轻松破 5000 次调用。用最强的商业模型跑一次可能要烧掉几百块。我的建议是先在本地用小模型跑通全流程逻辑,最后再换强模型做正式实验,别拿钱开玩笑。

5.2 遇到这些问题,按表排查

下面这个速查表是我跑完整个实验后整理的,基本覆盖了最常遇到的异常现象。

现象排查方向处理方式
交易量骤降但 agent 都在说话工具调用是否频繁失败检查 JSON 解析逻辑,加错误重试
货币集中度过高,多数人余额近零囤积行为、价格机制失效给商人加库存成本,或对超量余额收闲置费
agent 说“没钱买东西”但市场总货币充足货币沉淀在少数账户里设计定向低息贷款或周期性基础收入
行为越来越同质化记忆被压缩太狠放宽检索阈值,保留更多差异化细节
价格一路下跌没人接盘通缩预期形成设置价格下限,或通过社区公告稳定预期
部分角色彻底“躺平”生存目标设置不合理改成消费型目标,或增加随机需求事件

5.3 想让系统活得更久,我有几个调节手段

如果实验目的不是看它怎么死,而是想看一个经济系统怎么可持续地运转,我试验下来效果最好的三个手段是:周期性基础收入、随机需求事件、价格下限机制。

周期性基础收入我设置为每 4 周给每个 agent 发放 50 金币,这个数量不大,但足以让低收入群体恢复最基本的购买力;随机需求事件包括“连续暴雨导致木材产量下降”或“小镇举办庆典,需要大量面包和酒”,这类事件会突然制造需求,打破通缩预期;价格下限机制最简单,系统撮合时如果买家出价低于成本价,就把订单挂起,避免无休止的降价螺旋。

我个人的体会是,让经济持续运转的关键不是让 agent 变得更有钱,而是不断制造“想要购买的理由”。只要每个角色持续有目标、有消费场景、有外部事件刺激,货币就会流动起来。反过来,一旦需求侧枯竭,无论你给模型多强的推理能力,经济系统都一样会停摆。这也是这个实验最有价值的地方,它用最直观的方式告诉我们:货币流动的前提不是算法,而是欲望。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询