
就在你说“MiroFish”这四个字的时候我脑子里蹦出来的不是一条鱼而是一整个鱼群。这个名字起得很准单条鱼没什么智商但鱼群能集体转向、能躲避捕食者、能在几秒钟内把一次扰动放大成一场浪潮。MiroFish 干的就是这件事——它是一个基于大模型的多智能体社会仿真引擎你给它一个种子事件它就生成成百上千个有性格、有立场、有记忆的虚拟用户把这群人丢进一个模拟出来的社交环境里让他们自己发帖、评论、点赞、转发、互喷、抱团然后你站在上帝视角看这条信息是怎么被推着往前走、怎么变形、怎么失效的。我把它用在了几个偏运营侧的场景上新产品概念放出去之前先跑一遍看话题会不会歪社区做活动预案先看哪种规则设置会引爆冲突文案 A/B 拿不准调性先让虚拟用户投票。如果你做产品运营、市场调研、社区治理、品牌声誉监测或者是想学多智能体系统怎么从论文落到能跑的工程这套东西值得花两三个晚上折腾一下。1. 先把它讲透MiroFish 到底是什么能解决什么问题1.1 鱼群隐喻背后的技术本体MiroFish 的内核其实是两件事拼起来的一个是多智能体仿真一个是大模型人格化。早几年的社会仿真智能体行为靠的是规则表或者简单的概率模型比如“如果看到负面帖子有 30% 概率转发”跑出来的结果像一堆僵尸在按开关宏观趋势能看但细节经不起推敲因为它不会“换个说法”。大模型进来之后最大的变化是智能体可以说人话了它会根据自己的人设、当下的情绪、上下文语境生成一条你可能真在评论区见过的留言。这两者叠加之后MiroFish 的定位就很清楚了它不是一个“预测未来”的黑箱它是一个低成本的推演沙盘。真正的价值不在于它告诉你“明天热搜第一是什么”而在于它能在几分钟内给你跑出二十种可能的分支走向让你提前看到“如果这个环节处理不好舆论会往哪边塌”。这是它跟我用过的所有问卷工具、专家访谈最大的区别。1.2 和传统调研方式的正面对比我做过几年用户研究问卷和深访都跑过实话实说多智能体仿真替代不了它们但它在某个特定维度上是碾压式的。把几个维度拉平了对比一下对比维度传统问卷/深访专家判断MiroFish 仿真样本规模几百到几千份个位数数百到数万智能体单次周期一周到一个月几天十几分钟到几小时单次成本人力样本费咨询费模型调用费通常个位数到两位数可重复性差样本不可复现极差强固定种子可复现能否看到中间过程看不到看不到每一轮都能看到表达偏差受社会期望影响大受个人经验影响大有但可调节能否做反事实推演不能勉强强改参数立刻重跑最后一行才是关键。问卷只能告诉你“现在是什么”仿真是少数能低成本回答“如果当时那样做会怎样”的工具。我们有一次讨论要不要在活动规则里加一条限制两拨人吵了两天最后直接跑了两组仿真各 500 个智能体、25 轮四十分钟出结果虽然不能直接拍板但至少把讨论从“我觉得”拉到了“数据显示哪边更容易起冲突”。1.3 适用边界什么场景该用它什么场景别碰我踩过的最大的坑就是一开始把它当预测机用。适合它的场景我总结成三类一是话题走向预判新品命名、slogan 调性、活动主题放出去会往哪个方向解读二是群体情绪演化一个负面体验在社区里从零星抱怨到集中爆发的路径长什么样中间有没有灭火窗口三是规则设计的 A/B 推演同一套社区规则不同措辞、不同执行力度群体的反应差异有多大。不该用它做的事情也很明确。任何需要精确到小数点的量化结论比如“转化率会提升 3.2%”它给不了也不该给。依赖真实身份、真实地域分布的调查它替代不了。还有一类我要特别提醒仿真结果不能对外当成真实调研结论发布生成的虚拟人设也不要挂真实人物、真实品牌的敏感信息上去。这是基本的职业操守比技术本身重要。我自己的做法是仿真只作为内部讨论的输入任何对外材料里从来不给仿真数据单独背书的资格。2. 核心架构拆解一次推演背后到底跑了几套系统2.1 三层结构环境层、智能体层、观测层把整套东西拆开看其实是三层。环境层负责模拟一个社交平台该有的东西用户关系图谁关注谁、内容池每条帖子、互动行为点赞、评论、转发、收藏、以及最关键的推荐流——智能体不是自己想看什么就看什么它是被推荐算法喂内容的。这一层是整个仿真里最容易被忽视、但对结果影响最大的部分后面我会单独展开。智能体层是每个虚拟用户本身包含人设、记忆、决策和行为生成四个模块。观测层是我最喜欢的一层它负责埋点、统计、以及在仿真结束后由一个“洞察智能体”把海量日志压缩成一份人话报告。没有这一层你面对的就是几万条 JSON 日志根本读不动。三层之间是单向依赖环境层给智能体提供信息智能体把行为写回环境层观测层只读不写。这个设计让整个系统可以并行跑也方便你单独替换某一层做实验——比如我换过一次推荐算法其他都不动专门看推荐权重怎么影响话题的扩散速度。2.2 智能体的四个核心部件人设卡是整个仿真的地基。一份合格的人设至少要有年龄、职业、城市量级、兴趣爱好、性格倾向、表达风格、活跃时段、以及一条很关键的“初始立场”——对当前话题是中立、支持、还是反感。少了立场这一项跑出来所有人都是理中客结果毫无意义。我一般会按目标人群的真实结构去配比比如一个偏年轻女性向的产品我会把 18–30 岁女性智能体的比例拉到 60% 以上。记忆模块分两层。短期记忆就是最近若干轮的上下文让对话能接得上长期记忆是把智能体过去的行为压缩成摘要存起来需要的时候按相似度捞出来。没有长期记忆的智能体特别“健忘”它会反复问同一个问题、反复被同一类内容激怒跑长了就像个失忆症患者。决策模块是行为空间的派发器。每个时间步智能体要看一眼推荐流然后从“潜水、点赞、评论、转发、发帖、取关”这几个动作里选一个。这里有个实操细节潜水必须占大头。真实社交平台里 90% 的用户是只看不说的如果你让每个智能体每轮都必须动一下整个环境会吵得像个菜市场噪音会完全淹没信号。反思模块是 MiroFish 这类系统里最有意思的一块。智能体每隔几轮会把自己最近的行为总结成一段观点判断比如“这个品牌的售后问题被反复提到我开始有点不信任了”。这段总结会反过来影响它后续的行为权重。正是这个机制让宏观层面出现了“情绪拐点”而不是一条平滑上升的直线。2.3 推荐算法才是真正的“气氛开关”我做过一组对照实验同一批人设、同一个种子事件、同一个模型配置只改推荐算法里的热度计算权重跑出来的结果完全是两个故事。第一组里一条吐槽帖在第 6 轮就冲到了头部随后情绪开始雪崩第二组里同样一条帖子被压在长尾里二十多轮过去还是零星几条。这个差异不是模型随机性造成的纯粹是推荐逻辑决定的。我常用的几个关键参数和它们的作用参数含义调大的效果我的常用区间时间衰减系数内容热度随时间打折的速度新内容更容易冒头话题更新快0.3 ~ 0.8互动权重点赞/评论/转发的加权争议内容更容易被推上去评论权重 2~3 倍于点赞兴趣匹配权重内容与用户画像的契合度占比信息茧房加重跨圈扩散变难0.4 ~ 0.7随机探索比例推荐流里插随机内容的概率观点更分散极端化减弱0.05 ~ 0.15注意探索比例这个参数是新手最容易忽略的。设成 0整个仿真会变成几个彼此封闭的回音室你会看到所有圈层同时极端化最后得出的结论会严重偏离现实。2.4 模型选型与成本控制不是所有智能体都值得用最贵的模型。我的做法是分层大约 85% 的普通用户交给便宜的小模型它们的任务只是“看到这条内容按我的人设决定点不点赞、说句话”这类判断对模型能力的上限要求并不高剩下 15% 的高影响力节点——也就是仿真里的意见领袖、活跃创作者——用强模型因为它们的内容会被大量转发输出质量直接决定整个传播链的质量。这个分层策略看起来简单但对成本的影响是量级上的。我最初全量用强模型跑过一次 800 个智能体、30 轮的推演账单看得我心口疼改成分层之后同样的规模跑下来成本降到了原来的四分之一不到而结果的宏观趋势几乎没变。3. 从零跑通第一场推演完整实操记录3.1 环境准备这套东西对硬件的要求不算离谱纯 CPU 能跑小规模但真正跑起来还是建议有独显。我的开发机是 32G 内存加一张 16G 显存的卡跑 1000 智能体以内的场景够用如果你要上到几千个那瓶颈其实不在显存而在模型 API 的并发和你的钱包。# 基础环境我习惯用 conda 隔开 conda create -n mirofish python3.11 -y conda activate mirofish # 拉代码 git clone 仓库地址 mirofish cd mirofish # 装依赖注意这一步有时候会因为某个包的版本冲突卡住 pip install -r requirements.txt # 有几个包在 3.11 上需要单独处理实测下面两行能解决大部分安装报错 pip install --upgrade pip setuptools wheel pip install pandas2.1.4 numpy1.26.4依赖装完之后先别急着跑全量做一遍冒烟测试把智能体数量设成 5轮数设成 3能跑通再往上加。我见过太多人一上来就开 2000 个智能体然后因为一个字段名写错白烧了几十块钱的调用费。3.2 关键配置模型接入与环境变量配置这块最容易出问题的不是参数本身而是模型接口的兼容性。不同厂商的接口在返回格式、并发限制、超时策略上都有差异所以配置项要写清楚。# 复制一份配置模板改完记得加进 .gitignore cp .env.example .env # 编辑 .env我本地是这么配的# ---- 模型接入 ---- LLM_API_KEY你的密钥 LLM_BASE_URL你的接口地址 LLM_MODEL_NAME主模型名称 # ---- 分层调度 ---- # 普通用户走的小模型 AGENT_CHEAP_MODEL小模型名称 # 意见领袖走的主力模型 AGENT_CORE_MODEL主力模型名称 # 高层节点占比 CORE_AGENT_RATIO0.15 # ---- 仿真参数 ---- MAX_AGENTS500 MAX_ROUNDS25 RANDOM_SEED20240517 # ---- 并发控制 ---- MAX_CONCURRENCY8 REQUEST_TIMEOUT60 RETRY_TIMES3RANDOM_SEED这一项一定要写死。我最早没在意这个同一个配置跑两次结果差了将近 40%排查了一整晚才发现是采样随机性在作祟。固定种子之后同样的输入基本能复现出同样的宏观趋势虽然微观上单条评论不会逐字一致但这已经足够做对照实验了。MAX_CONCURRENCY是最需要按你的接口额度来调的一项。设太高会被限流设太低跑得慢到你想砸键盘。我的经验是先从 4 开始逐步加到开始出现超时错误再退回上一档那个值就是你这套环境的上限。3.3 人设文件决定成败的一步人设是整场推演的地基。我见过有人随手让模型生成 200 个“普通用户”结果所有智能体说话一个腔调跑完什么信息都提取不到。我的做法是分两步走。第一步用脚本批量生成初稿把人群结构的约束条件写死在提示里import json from itertools import islice # 目标人群结构按真实业务里的用户分布来配 SEGMENTS [ {name: 学生党, ratio: 0.25, age: (16, 24), traits: [价格敏感, 表达直接, 易受同伴影响]}, {name: 职场新人, ratio: 0.35, age: (23, 30), traits: [注重效率, 爱种草, 理性对比]}, {name: 资深用户, ratio: 0.25, age: (28, 40), traits: [经验丰富, 爱挑刺, 观点稳定]}, {name: 路人围观, ratio: 0.15, age: (20, 45), traits: [极少发言, 随大流, 容易被高赞影响]}, ] def build_profile_prompt(segment, idx): return f 生成一个虚拟社交平台用户画像编号 user_{idx}。 所属群体{segment[name]} 年龄范围{segment[age][0]}-{segment[age][1]} 性格标签{, .join(segment[traits])} 要求 1. 输出 JSON字段包含 nickname、age、occupation、interests(数组)、 tone(说话风格20字内)、stance(对话题的初始态度取值: 支持/中立/反感)、 activity(活跃度 0-1 的小数)、influence(影响力 0-1 的小数) 2. stance 的分布要接近真实讨论支持和中立占多数反感应控制在两成左右 3. tone 要具体不要写友好正常这种废话 第二步是人工抽查。这一步千万别省。我会随机抽 20 条人设读一遍主要看三件事立场分布是不是合理、说话风格有没有明显重复、有没有出现不合规的表达。抽出来的问题多了就说明提示词要改别硬着头皮往下跑。3.4 启动仿真与参数含义配置和人设都齐了就可以起跑了。我一般分两阶段先小规模验证再放大。# 阶段一冒烟验证5 个智能体跑 3 轮只看流程能不能通 python run_simulation.py \ --agents 5 \ --rounds 3 \ --config configs/smoke.yaml \ --output outputs/smoke_test # 阶段二正式推演 python run_simulation.py \ --agents 500 \ --rounds 25 \ --seed 20240517 \ --recsys weighted_hot \ --output outputs/exp_20240517_a # 想跑对照实验就换个推荐策略其他一律别动 python run_simulation.py \ --agents 500 \ --rounds 25 \ --seed 20240517 \ --recsys time_decay \ --output outputs/exp_20240517_b几个参数的实际含义--rounds不是“发帖轮数”而是时间步每一轮里所有智能体都会读一次推荐流并做一次决策。25 轮大概能覆盖一个话题从萌芽到平息的全周期如果是那种高烈度的争议事件我会开到 40 轮以上因为衰减尾巴比想象中长。--recsys切换的是推荐策略。做对照实验时除了这一个参数其他全都不能动包括种子。这一点看起来是常识但我自己就犯过两次错——一次是忘了把人设文件对齐一次是轮数差了一轮导致两组数据完全没法比。3.5 读结果把日志变成能看懂的结论仿真跑完之后目录里通常会有三类东西原始行为日志、按轮次的指标序列、以及一份自动生成的洞察报告。我个人的习惯是把报告当索引真正的判断一定回到原始数据去看。核心看这几个指标话题扩散半径也就是有多少比例的智能体至少参与过一次讨论。这个数字低于 5% 说明种子事件没跑起来通常是人设里立场分布太温和或者推荐权重把内容压住了。情绪极性曲线按轮次画出来的正面/负面比例走势。我最关心的是这条曲线有没有出现拐点比如负面比例在第 8 到第 12 轮之间突然加速上升那个位置往往就是“灭火窗口”的位置。实操里这个窗口比结论本身更有价值。意见领袖更替率。仿真里影响力最高的那批智能体在不同轮次是不是同一批人。如果更替率高说明话题不断在被新的人接棒属于典型的“越滚越大”如果从头到尾都是同一批人在说那说明这是个封闭的小圈子话题扩散潜力有限。沉默螺旋指数这是我自己的叫法用来衡量“持少数意见的人是不是越来越不说话”。算法很简单把每轮里少数派立场的发言量除以他们的智能体总数看看这条线是不是在往下掉。掉得越快说明环境越不健康这也是我判断一个社区规则设计是否合理的重要参考。提示洞察报告里的措辞是模型生成的读的时候要留个心眼。我遇到过报告把“讨论量上升”总结成“情绪恶化”回去看原始数据才发现上升的其实全是玩梗的中性内容。报告只用来定位不用来下结论。4. 踩坑实录跑不出结果的时候该查什么4.1 六个高频问题速查现象大概率原因处理办法智能体集体复读评论区全是同款句子人设同质化或温度参数过低提高生成温度重做人设里加差异化表达风格所有立场最后都收敛成一派探索比例太低形成回音室把随机探索比例调到 0.1 以上跑到一半大量超时并发超过接口承载能力降低并发数打开重试和指数退避两轮就没人说话了活跃度分布不合理或者时间衰减太快检查活跃度均值衰减系数调到 0.3 以下两次运行结果完全不同随机种子没固定写死 seed并记录所有参数账单远超预期全量用了强模型改分层调度把普通用户切到小模型4.2 让结果更“像人”的五个调参技巧第一给每个智能体配一个“口头禅”或者表达习惯。有人爱用省略号有人爱用反问有人一个短句拆成三条发。这一条改动看起来很小但对可读性的提升巨大我自己看日志的时候一眼就能认出是哪个智能体在说话。第二情绪要有惯性和衰减。一个智能体被激怒之后不应该下一轮立刻恢复平静。我在决策模块里加了一个情绪值被负面内容刺激会上升每轮自然衰减一小截。加了这一项之后情绪曲线的形状明显更接近真实讨论里的“余波”。第三让一部分智能体主动唱反调。真实社群里永远有人为了反对而反对。我在人设里专门留了 5% 左右的“杠精”角色配置成高活跃、低信任度。少了这批人仿真结果的乐观程度会明显虚高。第四时间要分昼夜。不同时段的活跃智能体比例不一样深夜的讨论往往更情绪化、更极端。加一个简单的时间权重表就能让话题的节奏带上真实的呼吸感。第五给事件加“外部冲击”。比如在第 10 轮插入一条官方回应或者一条竞品的新消息看群体怎么被扰动。这是我用得最多的玩法因为现实里几乎不存在没有外部干扰的干净推演。4.3 复现性做对照实验的底线我把这一条单独拎出来讲因为它是我吃过最大亏的地方。有一次我做了三组对比结论都写好了回头发现三组的轮数不一样一组是 25 轮、一组是 30 轮、一组是 20 轮那组数据直接被我自己废掉了白跑一整天。我的做法是维护一张实验记录表每次跑之前先填跑完再补结果字段说明实验编号日期加序号唯一种子事件原文不要改写后再填人设文件哈希用人设文件的哈希值保证三组完全一致智能体数量精确到个位轮数精确到轮推荐策略参数名加取值模型配置主模型、小模型、温度随机种子数字成本记录调用量方便下次估算这张表看着笨但它能救你。跑仿真的人最容易陷入的自我怀疑就是“这个差异到底是参数造成的还是随机性造成的”有了这张表你至少能把一半的可能性排除掉。5. 落地扩展把这套东西接进真实工作流5.1 三个可以直接抄的场景玩法场景一新品命名与话术预演。把三到五个候选名分别作为种子事件各跑一组 300 智能体、15 轮的快速仿真重点看两件事会不会被往奇怪的方向联想以及第一波讨论里出现的高频词是什么。这个玩法我从第一版用到现在成本极低但确实拦下过两个有歧义的名字。注意这里的判断标准不是“好评率”而是联想方向是否可控。场景二社区规则的冲突压力测试。一条新规则上线前把它写进环境配置里跑一组包含高争议种子的推演看规则能不能压住冲突、会不会误伤正常讨论。我一般会跑两版一版措辞强硬、一版措辞柔性对比冲突峰值出现的轮次和强度。这个玩法比开会辩论高效得多因为它至少把“双方各自想象的场景”具体化了。场景三危机响应的预案演练。把一条负面体验作为种子跑完整周期找出情绪加速度最大的那几个轮次然后反问自己如果现实里在这个轮次介入我们手上有什么牌这个练习做上三五次团队对节奏的感知会明显不一样。我自己的体验是演练完再看真实舆情会本能地去判断“现在处在第几轮”这个直觉很值钱。5.2 成本与算力估算成本基本由三部分构成智能体数量、轮数、模型档次。它们大致是乘法关系所以任何一个翻倍总量都会翻倍。规模档位智能体数轮数单轮调用量级适用场景冒烟5 ~ 203 ~ 5几十次流程验证、参数调试快速200 ~ 50015 ~ 25数千次命名预演、话术对比标准500 ~ 200025 ~ 40上万次情绪演化、规则测试大规模2000 以上40 以上数万次以上结构性研究、多圈层扩散我的建议很直接先用冒烟档把流程跑顺再用快速档做三到五组对照确认有信号了再上标准档。绝大多数人一上来就跑标准档结果跑到一半发现人设写错了只能重来。另外如果只是自己学习完全可以只跑快速档把省下来的钱和时间花在调参上。仿真的价值有一大半来自参数敏感性分析而不是规模本身。5.3 结果怎么用才不出错最后这点可能是整篇里最重要的。仿真的输出是假设不是结论。我的用法是把它当成一个“提出好问题”的机器。跑完一组之后我会问自己三个问题这个现象在真实数据里有没有影子如果没有是仿真错了还是我的观察窗口太窄如果我要验证它最小成本的实验是什么这三个问题走完仿真就从一个玩具变成了工作流里真实的一环。另外一件必须守住的事是合规与边界。虚拟人设不要挂真实人物信息仿真过程里生成的对话内容不要当成真实用户言论对外传播任何对外表述都要明确说明这是仿真推演的结果。我自己在团队里定了一条规矩仿真结论进决策层必须配一份现实数据作为交叉验证只有一份仿真数据就下结论一律打回。再补一个很实用的扩展方向。这套引擎跑通之后最省力的二次开发不是去改仿真内核而是改观测层。比如把结果直接落到 BI 看板上、或者接一个自动生成日报的脚本把每轮的关键指标推成一条消息。我后来加了一个很小的定时任务每天早上把前一天的推演指标汇总一下发出来团队看数据的习惯就这么慢慢养成了。做工具这件事降低使用门槛永远比提升功能上限更能改变行为。