news 2026/6/11 19:27:52

调查研究-168 MiroFish 本地化部署分析:主仓库、Zep Cloud、离线 Fork 与真正可控的多智能体沙盘

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
调查研究-168 MiroFish 本地化部署分析:主仓库、Zep Cloud、离线 Fork 与真正可控的多智能体沙盘

MiroFish 本地化部署分析:主仓库、Zep Cloud、离线 Fork 与真正可控的多智能体沙盘

最近 MiroFish 这个项目热度非常高。它的定位很有想象力:不是让一个大模型回答问题,而是让系统根据用户上传的现实材料,自动构建一个由大量智能体组成的“平行数字世界”,再通过这些智能体之间的互动、争论、传播和行为演化,推演一个复杂事件未来可能的发展方向。

这类项目很容易让人兴奋。因为它把大模型应用从“问答工具”推进到了“场景模拟”。传统 ChatGPT 式问答,本质上是单个模型在压缩已有知识、推理可能结果;而 MiroFish 的叙事是:先把现实世界里的实体、关系和背景抽出来,再生成大量具有不同身份、人格、记忆和行为逻辑的 Agent,让这些 Agent 在模拟环境里互动,最后生成预测报告和可交互的数字沙盘。

这背后代表的是一个重要方向:AI 不再只是生成文本,而是开始模拟系统。

但真正准备部署 MiroFish 时,一个问题会马上出现:它到底能不能完全本地部署?如果我不想用 Minimax、OpenAI、阿里百炼这类云端模型,只想免费、本地、私有化运行,它是否可行?如果官方主仓库不支持完整本地化,社区里又是怎么解决的?

本文围绕这个问题展开。

一、MiroFish 到底是什么

MiroFish 可以理解成一个“多智能体社会仿真系统”。

它的基本流程大致是:

用户上传一份种子材料,比如新闻、政策草案、金融报告、小说文本、舆情资料;系统从这些材料中提取实体、关系、背景和事件脉络;然后构造知识图谱;再根据知识图谱生成一批 Agent Profile;最后让这些 Agent 在模拟社交环境中互动,生成传播、争论、态度变化、群体分化等过程,并输出一份分析报告。

从产品表达上看,它像是“预测未来”。从工程角度看,它更准确的说法是“基于种子材料的多智能体情景推演”。

这两种表述有本质差别。

“预测未来”容易让人误解为它真的有稳定、可验证、可量化的预测能力。但当前阶段,MiroFish 更适合被看作一个复杂系统推演工具:它可以帮助用户观察某类事件在不同人群、组织、媒体、平台和意见领袖之间可能如何传播;也可以帮助用户构建小说角色群体、舆情传播场景、政策反应场景、市场情绪场景。

它不是水晶球。它更像一个由 LLM 驱动的数字沙盘。

这个定位非常重要。因为如果把它当成“绝对预测工具”,会高估它;如果把它当成“复杂场景模拟工具”,它就很有价值。

二、MiroFish 的核心架构

从代码结构和运行流程看,MiroFish 主要包含几层。

第一层是前端界面。它提供上传材料、创建项目、查看图谱、运行模拟、生成报告、交互查看结果等功能。

第二层是 Flask 后端。后端负责任务编排,包括文件解析、本体生成、图谱构建、Agent Profile 生成、仿真配置生成、模拟运行、报告生成等。

第三层是大模型调用层。MiroFish 并不绑定某一个模型厂商,而是通过 OpenAI-compatible API 调用模型。也就是说,只要你的模型服务兼容/v1/chat/completions这种接口格式,理论上就可以接入 MiroFish。

第四层是图谱与记忆层。主仓库默认依赖 Zep Cloud。它用 Zep 来存储和检索实体、关系、episode、上下文等内容。

第五层是仿真层。MiroFish 使用 CAMEL-AI / OASIS 相关能力来模拟社交平台式的 Agent 行为。也就是说,它当前更偏“社交传播仿真”和“群体行为仿真”,不是机器人、物理世界、运动控制那种仿真。

这几个部分中,真正影响本地化程度的主要有两个:大模型层和图谱记忆层。

大模型层可以本地化。你可以用 Ollama、LM Studio、llama.cpp server、vLLM 等方式提供 OpenAI-compatible API。

图谱记忆层才是麻烦点。主仓库默认依赖 Zep Cloud,而不是本地 Neo4j、SQLite、Graphiti 或本地 JSON。

所以,MiroFish 官方 Docker 部署不等于完全本地部署。

三、为什么说主仓库不能算完全本地化

MiroFish 主仓库提供 Docker Compose。表面上看,只要执行:

cp.env.example .envdockercompose up-d

就能在本地或服务器上跑起来。

Docker Compose 会启动 MiroFish 容器,映射前端端口和后端端口,通常是:

3000 -> 前端 5001 -> 后端 API

并且会挂载上传目录:

./backend/uploads:/app/backend/uploads

这说明前端、后端、上传文件目录都可以本地运行。

.env里仍然需要配置:

LLM_API_KEY=xxx LLM_BASE_URL=xxx LLM_MODEL_NAME=xxx ZEP_API_KEY=xxx

这里的关键不是 LLM,而是ZEP_API_KEY

如果你使用 Minimax、OpenAI、阿里百炼、DeepSeek、OpenRouter,这当然是云端。如果你使用 vLLM、Ollama、LM Studio,那么 LLM 可以是本地的。

但只要ZEP_API_KEY仍然存在,图谱记忆层就仍然依赖 Zep Cloud。

所以主仓库的本地化程度应该这样描述:

前端:本地 后端:本地 上传文件:本地 LLM:可本地,也可云端 图谱/记忆:默认 Zep Cloud

而不是:

前端:本地 后端:本地 LLM:本地 Embedding:本地 图数据库:本地 图谱检索:本地 记忆更新:本地

这就是很多人部署时容易误解的地方。

Docker 只是让应用容器化。容器化不等于全链路本地化。

四、Zep Cloud 为什么成为本地化卡点

Zep 是一个 Agent Memory / Context Graph 服务。它不是简单的向量数据库,也不是普通关系数据库。它的核心价值在于把对话、事件、文档、行为等内容组织成可检索、可更新、带时间属性的知识图谱。

MiroFish 用 Zep 做什么?

大致包括:

创建 graph 设置 ontology 添加 episode 处理实体与关系 读取 nodes 读取 edges 搜索上下文 为 Agent Profile 和报告生成提供图谱记忆

也就是说,Zep 不只是一个旁路依赖,而是 MiroFish 主流程的一部分。

过去 Zep 有 Community Edition,可以本地部署。但现在 Zep Community Edition 已经废弃,不再维护。官方当前给出的路线是:使用 Zep Cloud,或者使用开源的 Graphiti,企业客户可以走 BYOC。

这意味着你不能简单地在本地启动一个旧版 Zep CE,然后认为问题解决了。

旧版能不能跑是一回事,是否长期可靠、是否兼容当前 SDK、是否值得作为新项目依赖,是另一回事。

对个人开发者来说,现实选择只有三个:

第一,使用 Zep Cloud 免费额度。

第二,改造 MiroFish,把 Zep 替换成本地图谱存储。

第三,直接使用社区离线 Fork。

五、社区第一种路线:主仓库 + 本地 LLM + Zep Cloud

这是最容易跑通的路线。

架构是:

MiroFish Docker + 本地 vLLM / Ollama / LM Studio + Zep Cloud

这种方式不算完全本地化,但非常适合第一阶段测试。

如果你已经有 A6000、4090、A100、H100 这类显卡,可以直接用 vLLM 部署 Qwen 系列模型,然后让 MiroFish 调用本地 OpenAI-compatible API。

示例:

CUDA_VISIBLE_DEVICES=0vllm serve Qwen/Qwen2.5-32B-Instruct\--host0.0.0.0\--port8000\--served-model-name qwen-local\--gpu-memory-utilization0.85\--max-model-len32768

MiroFish.env

LLM_API_KEY=local LLM_BASE_URL=http://host.docker.internal:8000/v1 LLM_MODEL_NAME=qwen-local ZEP_API_KEY=你的_Zep_Cloud_Key

如果 MiroFish 容器和 vLLM 服务在同一台 Linux 宿主机上,可能需要在docker-compose.yml中加:

extra_hosts:-"host.docker.internal:host-gateway"

这种方案的好处是非常明确的:变量少,排错简单,主仓库兼容性最好。

它的缺点也很明确:材料、图谱、记忆相关数据会经过 Zep Cloud,不是完全私有化。

如果你只是想体验 MiroFish,或者验证它是否值得深入改造,这条路线最合理。

不要一开始就追求完全本地化。因为 MiroFish 本身有很多不稳定因素:模型 JSON 输出、ontology generation、图谱构建耗时、OASIS 仿真成本、报告生成稳定性。如果你一上来再叠加图谱层替换,排错会非常混乱。

六、社区第二种路线:把 Zep 替换成本地 JSON 文件

社区里已经有人尝试把 Zep Cloud 完全移除,改成本地 JSON 文件存储。

这个方向的核心思路是:

Zep Cloud -> 本地 JSON nodes -> nodes.json edges -> edges.json episodes -> episodes.jsonl semantic search -> keyword search

这种方案的优点是极其简单。

它不需要 Neo4j,不需要 Graphiti,不需要 Zep Cloud,不需要额外数据库。所有图谱节点、边、事件都写在本地目录里,比如:

uploads/graphs/{graph_id}/

它非常适合小规模 demo、离线演示、个人测试。

但它的问题也同样明显。

第一,关键词搜索不能等价替代语义检索。

第二,JSON 文件不适合大规模并发写入。

第三,图遍历能力弱。

第四,长期维护、迁移、查询优化都比较麻烦。

第五,它更像“为了完全离线而做的轻量替换”,不是严肃生产级图谱层。

所以这条路线的判断是:

想快速离线:可以 想长期做产品:不够 想大规模 Agent 仿真:不稳 想保持图谱能力:不合适

如果只是想把 MiroFish 作为个人工具或演示项目,本地 JSON 方案很有性价比。

如果你想把它并入自己的 AI Agent 平台、机器人云端编排系统、企业内部沙盘系统,那就不该停留在 JSON 文件层。

七、社区第三种路线:MiroFish-Offline

目前社区里更像“完整本地化方案”的,是 MiroFish-Offline 这个 Fork。

它做了几件关键改造:

Zep Cloud -> Neo4j Community Edition 云端 LLM -> Ollama 本地模型 云端 embedding -> Ollama nomic-embed-text 中文 UI -> 英文 UI

它的 Docker Compose 不再只是启动 MiroFish 一个容器,而是会启动多个服务:

MiroFish 应用 Neo4j Ollama

部署流程大致是:

gitclone MiroFish-OfflinecdMiroFish-Offlinecp.env.example .envdockercompose up-ddockerexecmirofish-ollama ollama pull qwen2.5:32bdockerexecmirofish-ollama ollama pull nomic-embed-text

然后访问:

http://localhost:3000

这条路线的意义很大。

因为它证明了一件事:MiroFish 不是理论上不能完全本地化,而是主仓库当前没有把本地化作为默认架构。

只要把 Zep Cloud 替换成 Neo4j,把 LLM 替换成本地服务,把 embedding 替换成本地模型,MiroFish 这类项目完全可以在本地硬件上跑。

但 MiroFish-Offline 也不是完美答案。

第一,它是社区 Fork,不是主仓库官方长期维护版本。

第二,它默认使用 Ollama,适合快速部署,但对高吞吐、大并发、显存利用率要求高的场景,不如 vLLM。

第三,它替换了图谱存储层,但你仍然需要验证图谱构建质量、查询质量、报告生成质量是否和原版一致。

第四,它偏英文 UI,对中文材料、中文场景、中文舆情推演是否稳定,需要自己测试。

第五,Fork 与主仓库会逐渐分叉,后续主仓库的新功能、Bugfix、接口变化,不一定能自动同步。

所以,MiroFish-Offline 是很好的参考实现,但不一定适合作为长期技术底座直接依赖。

八、如果是有 A6000 的服务器,应该怎么选

如果你有 A6000 这种 48GB 显存的卡,不应该长期用 Ollama 作为核心推理服务。

Ollama 的优势是简单。它适合个人电脑、快速体验、低门槛部署。

但如果目标是更高吞吐、更好并发、更强显存管理、更适合生产化的 OpenAI-compatible 服务,vLLM 更合适。

所以更合理的本地化路线是:

MiroFish-Offline + Neo4j 本地图数据库 + vLLM 本地大模型 + Ollama 只做 embedding,或替换为专门的 embedding 服务

示例架构:

MiroFish Backend -> OpenAI-compatible LLM API -> vLLM + Qwen2.5-32B / Qwen3-32B -> Graph Storage -> Neo4j -> Embedding API -> Ollama nomic-embed-text / bge-m3 / Qwen embedding

这样做比纯 Ollama 更适合你的服务器资源。

模型选择上,优先考虑 Qwen 系列。原因不是“Qwen 一定最强”,而是 MiroFish 主仓库原本就偏 Qwen 生态,很多提示词、JSON 输出、本体生成和中文场景,对 Qwen 更友好。

建议顺序:

Qwen2.5-32B-Instruct:稳定、非强 reasoning,适合 JSON 管线 Qwen3-32B:能力更强,但要处理 thinking 输出污染 Qwen3-14B:测试成本低 DeepSeek-R1-Distill-Qwen-32B:推理强,但 JSON 稳定性风险更高 GLM-4.5-Air:Agent 能力强,但部署和兼容性需要单独验证

不要一开始就用强 reasoning 模型跑全流程。

MiroFish 的很多步骤要求模型返回严格 JSON。如果模型输出<think>、解释文本、Markdown code fence、多余前后缀,很容易导致 JSON 解析失败。

所以本地模型部署时,真正关键的是两个字:稳定。

不是越会推理越好,而是越能按格式返回越好。

九、MiroFish 本地部署最常见的坑

第一个坑:把 Docker 部署误认为完全本地化。

Docker 只是运行方式,不代表依赖都在本地。只要.env里还有云端 API key,就不是真正本地化。

第二个坑:本地模型服务地址写错。

MiroFish 在 Docker 容器里访问宿主机,不一定能直接用localhost。容器里的localhost指的是容器自己,不是宿主机。

如果 vLLM 跑在宿主机上,MiroFish 容器里通常应该访问:

http://host.docker.internal:8000/v1

Linux 下还要配:

extra_hosts:-"host.docker.internal:host-gateway"

第三个坑:本地模型不支持response_format

一些 OpenAI-compatible 服务只是“接口像 OpenAI”,但不代表完整支持所有参数。比如某些本地模型服务对:

{"response_format":{"type":"json_object"}}

支持不完整,可能直接 500,或者忽略,或者返回非 JSON。

第四个坑:reasoning 模型污染 JSON。

Qwen3、DeepSeek-R1 这类模型可能输出思考过程。即使最终答案里有 JSON,只要前面夹杂了<think>或解释文本,后端如果直接json.loads(),就会失败。

第五个坑:仿真成本被低估。

MiroFish 不是一次聊天。它会多轮调用模型:生成 ontology、构建 graph、生成 profile、生成 config、运行 simulation、生成 report。Agent 数量和轮数一上来,token 消耗、时间和失败概率都会上升。

第六个坑:把 MiroFish 当生产级预测系统。

当前它更适合研究、演示、创作、辅助分析和情景推演。严肃决策不能直接依赖一次模拟结果。正确用法是把它当“生成假设和观察路径”的工具,而不是当“给最终答案”的系统。

十、如果我要自己长期维护,应该怎么改

如果只是玩,直接用主仓库或 MiroFish-Offline 就够了。

如果要长期维护,正确做法不是简单改几个 API Key,而是重构图谱层。

核心是抽象一个 GraphStorage 接口。

例如:

classGraphStorage:defcreate_graph(self,graph_id):...defset_ontology(self,ontology):...defadd_episode(self,episode):...defupsert_node(self,node):...defupsert_edge(self,edge):...defsearch(self,query):...defget_nodes(self):...defget_edges(self):...

然后实现多个 backend:

ZepGraphStorage Neo4jGraphStorage JsonGraphStorage GraphitiGraphStorage

这样以后就可以通过环境变量切换:

GRAPH_BACKEND=zep GRAPH_BACKEND=neo4j GRAPH_BACKEND=json GRAPH_BACKEND=graphiti

这才是合理的软件架构。

主仓库现在的问题不是“不能改”,而是图谱层和 Zep 的耦合比较重。社区 PR 和 Fork 本质上都在做同一件事:拆掉 Zep 依赖,换成本地存储。

但如果只是硬改,把一堆zep_xxx.py改成本地 JSON 或 Neo4j,会留下新的技术债。更干净的做法是先建立抽象层,再适配不同存储。

长期看,最好的方向应该是:

LLM Provider 可切换 Embedding Provider 可切换 Graph Backend 可切换 Simulation Engine 可切换 Report Agent 可切换

这样 MiroFish 才能从一个“依赖特定云服务的开源项目”,变成一个真正可私有化部署的多智能体仿真平台。

十一、推荐路线

如果只是体验 MiroFish:

主仓库 Docker + Zep Cloud 免费额度 + 本地 vLLM 或云端模型

这是最稳路线。

如果目标是尽快完全离线:

MiroFish-Offline + Neo4j + Ollama

这是最省事的完全本地化路线。

如果你有 A6000,并且希望性能更好:

MiroFish-Offline + Neo4j + vLLM 跑 Qwen2.5-32B / Qwen3-32B + 本地 embedding 服务

这是更适合服务器的路线。

如果你想长期做成自己的平台:

Fork 主仓库 抽象 GraphStorage 支持 Zep / Neo4j / JSON / Graphiti LLM 接 vLLM Embedding 本地化 保留 Docker Compose 一键启动

这是最正确但成本最高的路线。

十二、和普通 Agent 项目的区别

MiroFish 的价值不在于“它又调用了几个工具”。

很多 Agent 项目本质上是:

用户提问 LLM 判断意图 调用工具 返回结果

这类系统适合执行任务,比如查天气、调用数据库、控制设备、写代码、整理文档。

MiroFish 的逻辑不同。它更像:

用户提供现实材料 系统构建世界模型 生成一批具有差异化立场和行为的 Agent 让 Agent 之间互动 观察群体演化 生成结构化报告

它不是任务执行 Agent,而是群体模拟 Agent。

这类架构对未来 AI 应用很有启发。

因为现实世界里很多问题不是“查一个答案”就能解决的,而是涉及多个主体、多个立场、多个时间阶段和多个反馈回路。

比如:

一个产品发布后,用户会怎么反应? 一个政策出台后,不同群体会怎么理解? 一个舆情事件会不会扩散? 一个品牌声明是否会二次引爆? 一段小说剧情继续发展,人物关系会如何变化? 一个公司组织调整,会对员工情绪产生什么影响?

这些问题用单轮问答很难回答。即使回答了,也更像主观分析。

多智能体仿真至少提供了一种新的方法:把问题拆成主体、关系、环境、事件和行为,然后观察系统演化。

这就是 MiroFish 最值得研究的地方。

十三、它适合接入什么系统

MiroFish 不适合直接接入实时语音助手的低延迟链路。

比如一个语音机器人用户说一句话,系统要在几百毫秒到几秒内响应,这种场景不适合让 MiroFish 跑完整仿真。

MiroFish 更适合做后台推演模块。

例如:

用户提交一个复杂问题 系统进入后台推演 MiroFish 构建场景并运行模拟 生成报告 前端或语音助手再把结论摘要返回给用户

它适合“慢任务”,不适合“实时问答”。

如果放到一个更大的 AI 操作系统里,MiroFish 的定位应该是:

不是对话层 不是语音层 不是设备控制层 而是云端智能编排中的复杂情景推演模块

它可以成为 Agent 系统里的一个工具:

simulate_scenario(seed_docs, goal, agent_count, rounds)

调用后返回:

关键角色 传播链条 分歧点 潜在风险 可能结果 建议动作 反事实变量

这比把它当成独立玩具更有价值。

十四、最终判断

MiroFish 主仓库当前不能算完全本地化项目。

它可以 Docker 部署,可以本地跑前后端,可以接本地 LLM,但默认图谱记忆层仍然依赖 Zep Cloud。由于 Zep Community Edition 已经废弃,主仓库不是靠简单加一个本地 Zep 容器就能完整离线。

社区的解决方式主要有三种。

第一种,主仓库继续用 Zep Cloud,但把 LLM 换成本地 Ollama、vLLM、LM Studio。这是最稳的体验路线。

第二种,改代码,把 Zep 替换成本地 JSON 文件。这是最轻量的完全离线路线,但图谱能力下降明显。

第三种,使用 MiroFish-Offline,把 Zep 替换成 Neo4j,把云端模型替换成本地 Ollama。这是目前最接近完整本地部署的社区方案。

如果只是想体验,优先主仓库 + Zep Cloud + 本地 vLLM。

如果明确要求“免费、本地、离线”,优先研究 MiroFish-Offline。

如果想长期做成自己的系统,不要直接押注某个 Fork,而是 fork 主仓库,抽象 GraphStorage,把 Zep、Neo4j、Graphiti、本地 JSON 都做成可切换 backend。

MiroFish 这个项目真正值得学习的不是某个部署脚本,而是它代表的应用范式:

文档输入 结构化世界建模 多智能体社会模拟 群体行为涌现 报告与交互分析

这是一种很有潜力的 AI 应用方向。

但当前阶段,它不是一个开箱即用的生产级预测平台,而是一个值得研究、值得改造、值得借鉴的多智能体数字沙盘。

理解这一点,部署路线就清楚了。

不要被“Docker 部署”误导,也不要被“预测万物”迷惑。

MiroFish 的正确打开方式是:先把它作为实验系统跑通,再判断哪些模块值得吸收,最后决定是否把它改造成自己可控的本地化推演平台。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 19:27:52

Diablo Edit2:暗黑破坏神2终极存档编辑器,打造完美角色体验

Diablo Edit2&#xff1a;暗黑破坏神2终极存档编辑器&#xff0c;打造完美角色体验 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 想要彻底掌控你的暗黑破坏神2游戏角色吗&#xff1f;Diablo Edi…

作者头像 李华
网站建设 2026/6/11 19:27:52

Notepad4:轻量级文本编辑器的终极使用指南

Notepad4&#xff1a;轻量级文本编辑器的终极使用指南 【免费下载链接】notepad2 Notepad4 (Notepad2⨯2, Notepad2) is a light-weight Scintilla based text editor for Windows with syntax highlighting, code folding, auto-completion and API list for many programming…

作者头像 李华
网站建设 2026/6/11 19:26:52

ROS2 环境搭建与基础通信:状态发布订阅与 /cmd_vel 速度控制

1. ROS2 是什么ROS2 可以理解成机器人系统里的“通信框架”。机器人不是一个大程序写到底&#xff0c;而是由很多小程序组成。每个小程序负责一件事&#xff0c;例如&#xff1a;状态读取 速度控制 摄像头读取 目标识别 急停保护 任务状态机这些小程序之间通过 ROS2 通信。2. N…

作者头像 李华
网站建设 2026/6/11 19:25:53

从数据手册到实战:MSC8252 DSP电气特性与高速接口设计指南

1. 项目概述&#xff1a;从数据手册到设计实战拿到一颗像飞思卡尔&#xff08;现恩智浦&#xff09;MSC8252这样的高性能双核数字信号处理器&#xff08;DSP&#xff09;&#xff0c;第一感觉往往是兴奋&#xff0c;紧接着可能就是面对上百页数据手册的“敬畏”。尤其是“电气特…

作者头像 李华
网站建设 2026/6/11 19:22:55

艺学启航:学编程,先学会找bug

上周帮一个刚学编程的朋友看代码。他对着屏幕上的红色报错&#xff0c;足足坐了两个小时。我扫了一眼&#xff0c;是个常见的索引越界问题&#xff0c;三分钟就解决了。他挺纳闷的&#xff0c;问我为啥他能折腾半天&#xff0c;我一眼就能看出来。我说这跟智商没关系&#xff0…

作者头像 李华
网站建设 2026/6/11 19:22:53

Gradle 8.0 升级预警:识别并修复废弃API,确保构建兼容性

1. 为什么Gradle 8.0升级需要提前预警 最近在编译项目时&#xff0c;你可能遇到过这样的警告&#xff1a;"Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0"。这不是普通的警告&#xff0c;而是Gradle在向你发出升级前…

作者头像 李华