开始使用
快速开始
克隆 Mirobody,运行 ./deploy.sh,在 localhost:18080 登录,然后填一个 LLM key。
从一个空目录到登录进 Mirobody 的一条路径:克隆、运行 ./deploy.sh、打开浏览器、用演示账号登录,然后填一个 LLM key。全程运行在 Docker 里,本页不需要宿主机上有 Python 或 Node。
| 要求 | 为什么 |
|---|---|
| Docker + Docker Compose | deploy.sh 会构建一个镜像并启动四个容器。 |
| Git | 用来克隆仓库。 |
| Git LFS | mirobody/res/ 下的术语与指标资源是 LFS 对象。未安装 LFS 获得的是指针文件,启动会失败。 |
1. 克隆仓库
Section titled “1. 克隆仓库”在克隆之前装好 Git LFS:apt install git-lfs、brew install git-lfs,Git for Windows 自带。
git lfs install # once per machinegit clone https://github.com/thetahealth/mirobody.gitcd mirobody2. 运行部署脚本
Section titled “2. 运行部署脚本”./deploy.sh这个脚本做四件事:
写出 .env
设置 ENV=localdb,并生成一个 32 字符的 CONFIG_ENCRYPTION_KEY。已存在的文件不会被改动。
写出 config.localdb.yaml
你的覆盖文件,预置了一个随机 JWT_KEY、演示登录验证码,以及被注释掉的 LLM key 占位。
构建镜像
一个 Ubuntu 24.04 镜像,内含 Python 虚拟环境与 Node.js。如果 hub.docker.com 不通,脚本会回退到 docker.1ms.run 镜像源,npm 也会指向 registry.npmmirror.com。
启动整套服务
docker compose up -d,然后在前台跟踪日志。四个容器会起来:pg(18082)、redis(18089)、mirobody(18080)、mirobody_worker。
3. 打开 Web 客户端
Section titled “3. 打开 Web 客户端”打开 http://localhost:18080。引擎会把进程旁边 frontend/ 目录里预构建好的 Web 客户端提供出去,它刻意放在 Python 包之外,这样 wheel 装的是引擎,而不是 8 MB 的 JavaScript。
deploy.sh 会在 config.localdb.yaml 里写入三个预置账号。任选一个,用对应的码作为验证码:
demo1@mirobody.ai777777只把这段从 config.localdb.yaml 里删除是不够的:config.yaml 模板自己也带一个预置账号(caregiver@mirobody.ai),而且它先加载。正确做法是把这个键覆盖成空值:
EMAIL_PREDEFINE_CODES:验证码需要 Mandrill 或 SMTP,而克隆下来试用的部署两者都没有,因此登录页默认落在密码这
一栏,把邮箱验证码留作第三栏。底层接口接收邮箱(或 username)加一个不少于八位的密码:
curl -X POST localhost:18080/password/register -H 'Content-Type: application/json' \ -d '{"email":"you@example.com","password":"at-least-8-chars"}'它返回 token 并创建账号;用同样的请求体调 POST /password/login 即可再次登录。哈希是
pgcrypto 在 Postgres 内部算的 bcrypt,所以密码不会在 Python 里被哈希、比较或写进日志,仓库
里也不预置任何密码。对已有密码的账号,register 会拒绝而不是覆盖;密码错误与账号不存在
返回完全相同的结果;两条都是刻意为之。
预置的演示记录
Section titled “预置的演示记录”compose.yaml 设了 SEED_DEMO_DATA=true,所以这条路启动完带着数据,而不是一个空库。一位合成
用户 Demo (synthetic) 会被共享进每一个预置账号的关爱圈,带着 2024-04-16 至 2026-04-15 之间
的 244 项指标和五份 agent 可读的文档。用演示账号登录时,你自己没有任何数据,读到的记录属于
另一个人。
先提问,而不是先看数据表。在问答页问:「她最近一次的 LDL 胆固醇是多少,和一年前比怎么样?」
答案来自她预置的历史,而 agent 往往会自己指出最新那次面板已经过去一年多。她的下一次面板被
刻意留在预置数据之外,以文件形式随包发布:mirobody/demo/lab_report_2025-10-15.pdf。
在数据页上传它(或用问答页的 +),前两个步骤就会在一份真实文档上运行:十二个分析物带着单位被 读出,各自解析到编码,LDL 序列多出第四个点;再问同一个问题,答案就变了。
所有数值均为合成,PDF 上也印着这一点。fixture 是随包 vendor 进来的,因此灌数据不需要联网、不
需要任何 API key;它是 upsert,重启不会灌重。承载真实数据的部署请设 SEED_DEMO_DATA=false。
5. 添加 LLM key
Section titled “5. 添加 LLM key”登录进去了,但 agent 还没有可调用的模型。编辑 config.localdb.yaml,至少设置一个 key:
# Pick whichever provider you have a key for. One is enough to start.OPENROUTER_API_KEY: 'sk-or-...'# GOOGLE_API_KEY: 'AIza...'# OPENAI_API_KEY: 'sk-...'然后重启两个应用容器:
docker compose restart mirobody mirobody_worker每个 agent 各自能用哪些模型,是在 PROVIDERS_DEEP 与 PROVIDERS_BASE 下按 agent 配置的,config.yaml 里的默认值已经引用了上面这些键名。
embedding key
Section titled “embedding key”对话需要的是 LLM key。embedding key 是另一把,而且是可选的,它换来的是自由文本检索指标和 规整的显示名:
EMBEDDING_PROVIDER: gemini # 默认值GOOGLE_API_KEY: 'AIza...' # gemini 对应的 embedding key# EMBEDDING_PROVIDER: qwen # 另一个支持的 provider# DASHSCOPE_API_KEY: 'sk-...'不配它也能用:浏览记录、以及按名称查询指标,这两条路径都是纯 SQL。会降级的是模糊关键词
检索:它会退回成列出指标目录,而不是报错;指标名也会保持数据源原本的拼写
(AlanineAminotransferase-ALT),而不是 embedding 那一遍产出的显示名。如果配了 embedding key
但它不工作,失败是静默的,docker compose logs mirobody_worker 是它唯一说话的地方。
6. 验证安装
Section titled “6. 验证安装”# All four containers up?docker compose ps
# Liveness — returns JSON with the service name, version, and counts of# tools, resources and agents that were discovered at startup.curl http://localhost:18080/api/health
# MCP discovery — JSON-RPC 2.0 over POST, lists the registered tools.curl -X POST http://localhost:18080/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'如果 /api/health 返回 "tools": 0,说明工具目录没扫到,检查 MCP_TOOL_DIRS 和启动日志(docker compose logs mirobody)。
三层配置、各组配置键,以及哪些值会被加密。
本地 Python 开发、PyPI 包,以及仓库结构。
服务、worker、agent 与 Pulse 是怎么拼在一起的。
把 Claude Desktop、Cursor 或任意 MCP 客户端指向这个服务。