01

鱼群中的每条鱼

千千万万个独立人格的智能体,如何涌现出群体的智慧与疯狂

想象你站在海边,看到一群鱼

没有一条鱼在指挥,但整群鱼却像有灵魂一样——突然转向、同步闪避、集体加速。这就是群体智能

MiroFish 就是这样一个引擎:它创造成千上万个拥有独立人格、记忆和行为的智能体(Agent),让它们在数字世界中自由互动——然后观察群体行为如何涌现。

💡
核心理念

预测未来不需要一个全知全能的预言家。只要模拟足够多个真实的人,观察他们如何互动,群体涌现的结果就是最可信的未来预测。

每条鱼都有名字和性格

在 MiroFish 中,每个 Agent 都不是一个随机数,而是一个有血有肉的虚拟人物。系统使用 大语言模型 从种子材料中提取人物信息,生成详细的人设

🎓

学生

活跃度 0.8,晚间高峰活跃,发帖频率高,影响力低。愤怒时可能成为舆论引爆点。

🏢

大学官方

活跃度 0.2,仅工作时间,响应慢(60-240分钟),但影响力极高(3.0)。发言风格严谨保守。

📰

媒体机构

全天候活跃,快速响应事件(5-30分钟),影响力高(2.5)。内容以报道和评论为主。

👨‍⚕

教授/专家

活跃度中等,影响力 2.0。通常保持中立,但一旦发声就会被大量引用。

代码翻译:一条鱼的身份证

以下是 MiroFish 中 Agent 人设数据的结构,每条"鱼"都有这样的完整档案:

Python 代码
@dataclass
class OasisAgentProfile:
    user_id: int
    user_name: str
    name: str
    bio: str
    persona: str
    mbti: str = None
    profession: str = None
    interested_topics: List[str] = []
通俗解释

定义一个"虚拟人物档案"的数据结构

每个角色有一个唯一的数字编号

在模拟世界中的用户名(自动生成)

角色的真实姓名

一段简短的自我介绍

长达 2000 字的详细人设,包含性格、背景、立场

MBTI 人格类型(如 INTJ、ENFP),决定思维方式

职业,影响发言风格和活跃时段

感兴趣的话题列表,决定会关注哪些事件

🌊
为什么需要 2000 字的人设?

简短的"他是一个学生"远远不够。LLM 需要知道:这个学生是大几的?什么专业?经历过什么?对哪些话题敏感?只有这样,模拟中的每个决策才真实可信。

鱼群的对话:当事件发生时

当一个新闻事件在模拟世界中爆发,不同角色的 Agent 会如何反应?点击下方按钮,观看一场模拟对话:

注意每个角色的反应速度和风格都不同——这正是人设数据的功劳。学生立即愤怒,媒体快速跟进,教授理性呼吁,学校慢慢回应,校友带着情感反思。

测验:你理解鱼群了吗?

如果要模拟一场大学舆情事件,以下哪种做法最接近 MiroFish 的思路?

为什么 MiroFish 的 Agent 人设需要长达 2000 字的描述,而不是简单的几个标签?

02

知识图谱:鱼群游弋的水域

从新闻稿到关系网络——MiroFish 如何理解现实世界的复杂关联

种子材料就像一滴水

你给 MiroFish 一篇新闻报道、一份分析报告,甚至一部小说——它需要从这些种子材料中提取出所有重要的人物、机构、事件,以及它们之间的关系。

这就像往平静的池塘里滴入一滴墨水——MiroFish 需要理解这滴墨水的每一个分子,才能在后续模拟中让整池水真实地波动。

1
本体生成(Ontology)

LLM 分析文本,定义"有哪些类型的角色和关系"——比如学生、教授、大学、媒体,以及它们之间可能存在的"就读于""隶属于""报道"等关系

2
图谱构建(Graph Building)

将文本分块后发送给 Zep,让它从文本中提取出具体的实体节点和关系边

3
人设生成(Profile)

对图谱中每个实体,用 LLM 生成详细人设,并从 Zep 检索更多上下文信息来丰富人设

系统架构:三大核心组件

点击下方组件,了解它们各自的职责:

文本分析层

📋
本体生成器
🧑
人设生成器

知识图谱层

🗺
图谱构建器

外部服务

Zep Cloud
🧠
LLM
点击任意组件,了解它的职责

代码翻译:本体是如何定义的

MiroFish 让 LLM 分析文本后生成的本体包含实体类型和关系类型:

Python 代码
ontology = {
  "entity_types": [
    {"name": "Student",
     "description": "在校学生",
     "attributes": [{"name": "full_name"}]},
    {"name": "Person"},  # 兜底
    {"name": "Organization"}  # 兜底
  ],
  "edge_types": [
    {"name": "STUDIES_AT",
     "source_targets": [
       {"source": "Student",
        "target": "University"}]}
  ]
}
通俗解释

定义"世界中有哪些类型的角色和关系"

实体类型列表——这个世界中有哪几种角色

学生类型,有一个属性用来存全名

描述"在校学生"这个角色是什么

角色的属性,比如名字

兜底类型:任何不属于特定类型的个人

兜底类型:任何不属于特定类型的组织

关系类型列表——角色之间可以有什么联系

定义"学生就读于大学"这种关系

关系的方向:学生 → 大学

数据流:从文本到图谱

点击"下一步"观看一篇新闻稿是如何变成知识图谱的:

M
MiroFish 核心
L
LLM 大脑
Z
Zep 图谱
P
人设工厂
点击"下一步"开始

测验:你理解知识图谱了吗?

MiroFish 的本体定义中,为什么必须有 Person 和 Organization 这两个"兜底类型"?

在 MiroFish 的本体定义中,实体类型的命名格式有什么要求?

03

数字沙盘推演

OASIS 模拟引擎如何让成百上千个 Agent 在 Twitter 和 Reddit 上同时"活"起来

想象一个平行宇宙的微博和 Reddit

MiroFish 的模拟引擎叫 OASIS——它创建了两个平行运行的社交媒体平台:一个类似微博/Twitter,一个类似 Reddit。

每个 Agent 都在这两个平台上拥有账号,按照自己的人设发帖、评论、点赞、转发。没有人在幕后操控它们的每一步行动——它们的行为完全由自己的性格和 LLM 的推理决定。

🐦

Twitter 平台

短文本、快节奏、病毒式传播。Agent 可以发帖、转发、点赞、关注。信息像鱼群一样快速扩散。

📌

Reddit 平台

长文本、深度讨论、社区投票。Agent 可以发帖、评论、投票。更适合表达复杂观点和立场。

每条鱼的作息表:模拟配置

MiroFish 使用 LLM 为每个 Agent 智能生成活动配置,包括活跃时段、发言频率、响应速度、情感倾向和影响力权重:

Python 代码
@dataclass
class AgentActivityConfig:
    activity_level: float = 0.5
    posts_per_hour: float = 1.0
    active_hours: List[int] = []
    response_delay_min: int = 5
    sentiment_bias: float = 0.0
    stance: str = "neutral"
    influence_weight: float = 1.0
通俗解释

定义每个 Agent 的活动参数配置

整体活跃度(0.0-1.0),0.2=官方/0.8=学生

每小时预期发帖数,学生可能 0.6,官方仅 0.1

活跃的时段(24小时制),如学生=[18-23]

对热点事件的最小响应延迟(分钟)

情感倾向(-1.0 负面 到 +1.0 正面)

立场:supportive/opposing/neutral/observer

影响力权重——决定发言被看到的概率

模拟中国人的一天

模拟时间按照中国人的真实作息来推进。以下是系统默认的时间段配置——注意晚间 19-22 点的活跃度是凌晨的 30 倍:

0-5 点 深夜时段 — 活跃度 0.05(几乎没人发帖,模拟中 95% 的 Agent 在睡觉)
6-8 点 早间时段 — 活跃度 0.4(开始刷手机,但还没有太多互动)
9-18 点 工作时段 — 活跃度 0.7(媒体和官方活跃,学生上课间隙偷看)
19-22 点 晚间高峰 — 活跃度 1.5(所有人都在线,舆论的核爆时刻!)
23 点 深夜下降 — 活跃度 0.5(夜猫子还在,但大部队已退场)
关键设计

这些时段不是硬编码的——LLM 会根据事件性质调整。比如突发热点可能导致凌晨仍有大量讨论(off_peak_hours 缩短),而学生群体的晚间高峰可能延后到 21-23 点。

模拟运行时的真实消息流

当模拟开始后,系统通过监控线程实时读取每个 Agent 的动作日志(actions.jsonl),记录发帖、评论、点赞等行为:

拖拽匹配:Agent 配置连连看

将左侧的 Agent 类型拖到右侧对应的最佳活动配置上:

大学官方
媒体机构
大学生
教授/专家

活跃度 0.8 · 晚间 18-23 点 · 响应 1-15 分钟 · 影响力 0.8

拖到这里

活跃度 0.2 · 工作时间 9-17 点 · 响应 60-240 分钟 · 影响力 3.0

拖到这里

活跃度 0.5 · 全天 7-23 点 · 响应 5-30 分钟 · 影响力 2.5

拖到这里

活跃度 0.4 · 白天+晚间 8-21 点 · 响应 15-90 分钟 · 影响力 2.0

拖到这里

测验:你理解模拟引擎了吗?

MiroFish 的模拟是在几个平台上同时进行的?

在默认的时间配置中,晚间高峰(19-22 点)的活跃度是凌晨低谷(0-5 点)的多少倍?

04

上帝视角的报告

ReportAgent 如何像一位全知记者,检索模拟世界的每个角落

想象一位拥有读心术的记者

模拟结束后,MiroFish 需要把成千上万个 Agent 的互动整理成一份人类可读的预测报告。这不是简单的摘要——ReportAgent 需要"潜入"模拟世界,像一位拥有上帝视角的记者,检索每一条线索。

它使用 ReACT(推理+行动)模式工作——每个章节都经过多轮思考、检索、再思考的过程。

1

规划大纲

2

逐章生成

3

组装报告

4

交互对话

记者的四件法宝

ReportAgent 有四个强大的检索工具,每个章节至少调用 3-5 次:

🔍
深度洞察(InsightForge)

自动将问题分解为多个子问题,从多个维度检索图谱,整合语义搜索、实体分析、关系链追踪的结果。最强大的工具。

🌊
广角全景(PanoramaSearch)

获取模拟的完整全貌——区分当前有效事实和已过期的历史事实,帮你看清舆论是如何演变的。

快速检索(QuickSearch)

轻量级快速查询,适合验证某个具体事实。比如"确认一下校方什么时候发的声明"。

💬
深度采访(InterviewAgents)

调用 OASIS 的真实采访 API,对正在运行的模拟 Agent 进行双平台采访。获取各角色的第一人称观点。

代码翻译:ReACT 循环的精髓

ReportAgent 生成每个章节时的核心逻辑——不断"思考-行动-观察"循环:

Python 代码
for iteration in range(max_iterations):
    response = llm.chat(messages)
    tool_calls = parse_tool_calls(response)

    if "Final Answer:" in response:
        return extract_final_answer(response)

    if tool_calls:
        result = execute_tool(tool_calls[0])
        messages.append(observation)
通俗解释

最多循环 5 轮(每章最多调 5 次工具)

把之前所有的对话发给 LLM,让它思考

检查 LLM 的回复里有没有工具调用

如果 LLM 说"我写好了"——提取最终答案

返回章节内容,ReACT 循环结束

如果 LLM 想调工具——执行第一个工具

拿到工具结果,追加到对话历史

下一轮循环,LLM 看到工具结果后继续思考

💡
为什么必须至少调 3 次工具?

ReportAgent 有一条硬规则:每个章节至少调用 3 次检索工具,否则拒绝输出。如果 LLM 想偷懒直接写答案,系统会强制它先去检索数据。这确保报告的每一句话都有模拟数据支撑,而不是 AI 编造的。

旁观 ReACT:记者的工作现场

以下是 ReportAgent 撰写"舆论传播分析"章节时的真实工作过程——点击观看:

测验:你理解报告生成了吗?

ReACT 模式的核心工作方式是什么?

为什么 ReportAgent 强制每个章节至少调用 3 次检索工具?

05

从种子到预测

把所有拼图拼在一起——MiroFish 的完整工作流和你能用它做什么

五大步骤,从新闻到未来

MiroFish 的完整工作流分为五个阶段,每个阶段都由不同的服务组件负责:

1
图谱构建

上传种子材料(新闻/报告/小说)→ 本体生成器定义实体和关系类型 → 图谱构建器调用 Zep 提取节点和边 → 人设生成器为每个实体创建详细人设

2
环境搭建

配置生成器用 LLM 智能设置模拟参数 → 时间配置(按中国人作息)→ Agent 活动配置 → 初始事件(第一枪由谁打响)→ 平台配置

3
开始模拟

OASIS 引擎在 Twitter + Reddit 双平台并行 → Agent 按人设自主互动 → 监控线程实时记录动作 → 可选:将活动动态更新到 Zep 图谱

4
报告生成

ReportAgent 用 ReACT 模式撰写预测报告 → 先规划大纲(2-5 章)→ 逐章多轮检索+生成 → 分章节实时保存 → 组装完整报告

5
深度互动

用户可以与模拟世界中的任意 Agent 对话(Interview)→ 也可以与 ReportAgent 对话,追问细节 → 从上帝视角探索预测的未来

代码仓库地图

MiroFish 采用前后端分离架构,核心逻辑在后端 Python 服务中:

backend/app/ Python 后端核心
services/ 业务逻辑层——每个文件对应一个核心能力
ontology_generator.py LLM 分析文本,生成实体和关系类型定义
graph_builder.py 调用 Zep API 构建知识图谱(异步+进度跟踪)
oasis_profile_generator.py LLM + Zep 检索,为实体生成详细人设(支持并行)
simulation_config_generator.py LLM 智能生成模拟参数(时间/事件/Agent/平台)
simulation_runner.py 启动/监控/停止模拟进程,实时解析动作日志
report_agent.py ReACT 模式的报告生成器,四大检索工具
api/ Flask API 路由,连接前端和后端服务
models/ 数据模型和任务管理
frontend/ Vue.js 前端,可视化操作界面

数据流全景:种子的旅程

点击"下一步",跟踪一条新闻从上传到变成预测报告的完整路径:

📄
种子材料
📋
本体
🗺
知识图谱
🧑
人设
🎮
OASIS
📝
预测报告
点击"下一步"开始旅程

不只是预测——鱼群引擎的应用场景

MiroFish 的群体智能引擎可以预测万物。以下是已经实现的案例:

📰

舆情推演

武汉大学的舆情事件——上传舆情报告,模拟学生、校方、媒体、校友各方的反应,预测舆论走向。

📚

小说结局预测

《红楼梦》失传结局——上传前 80 回,让角色们在模拟世界中继续生活,预测最可能的结局走向。

💰

金融预测

上传金融信号和政策草案,模拟投资者、机构、监管者的行为,预测市场可能的反应。

🎭

政策模拟

上传政策草案,模拟不同群体(企业、民众、媒体)对新政策的反应,预判社会影响。

最终测验:你理解 MiroFish 了吗?

以下哪个顺序正确描述了 MiroFish 的工作流?

MiroFish 项目是开源的还是商业闭源的?

MiroFish 的名字中的"Fish"暗示了什么核心理念?

课程结束

恭喜你完成了 MiroFish 交互式课程!现在你已经理解了:

多智能体 每个 Agent 都有独立人格、记忆和行为,群体的互动涌现出预测
知识图谱 从种子材料中提取实体和关系,构建数字世界的"水域地图"
OASIS 模拟 双平台并行,按真实作息推进时间,Agent 自主演化社会行为
ReportAgent ReACT 模式的"全知记者",四大检索工具确保报告基于真实数据
完整工作流 从种子到预测的五步流程,每步环环相扣
🐟
继续探索

MiroFish 在 GitHub 上开源:github.com/666ghj/MiroFish。你可以克隆代码、上传自己的种子材料,让鱼群预测你关心的未来。