基于 Mirobody 进行开发
开发环境搭建
从源码检出运行 Mirobody Python 引擎:虚拟环境、可编辑安装、Docker 里的 Postgres 与 Redis,以及测试套件。
Mirobody 是一个 Python 服务(requires-python = ">=3.12")。在它上面做开发,就是创建虚拟环境、以可编辑模式安装本包、用 Compose 起 Postgres 与 Redis,然后运行 mirobody serve。没有编译步骤。
pyproject.toml 声明了 requires-python = ">=3.12"
用于起 Postgres(pgvector/pgvector:pg17-trixie)与 Redis(redis:7.0-alpine)容器
mirobody/res/*.bin、*.npz、*.npy 和 *.gz 都是 LFS 对象
搭建工作副本
Section titled “搭建工作副本”克隆仓库
git clone https://github.com/thetahealth/mirobody.gitcd mirobody启动 Postgres 与 Redis
compose.yaml 定义了四个服务:pg、redis、mirobody 和 mirobody_worker。本地开发只需要那两个后端存储;应用本身运行在你的宿主机上:
docker compose up -d pg redis它们在宿主机上发布 18082 → Postgres 和 18089 → Redis。
创建虚拟环境并安装
python3 -m venv venvsource venv/bin/activate # Windows 下:venv\Scripts\activatepip install --upgrade pippip install -e .pip install -e . 装到的是引擎:作为库的 ① 采集与 ② 标准化,不带数据库驱动、不带 HTTP 服务。要动对话服务或那两个 agent,就得装 [agents] extra,它会把 [server] 一并带上:
pip install -e '.[agents,test]' # 做开发要的就是这个pip install -e '.[cn]' # 阿里云 OSS + 火山引擎 Arkpip install -e '.[indicator-build]' # 只在要重新生成术语包时才用整个仓库不存在任何 Node.js 依赖。
写好 .env 与你的配置覆盖文件
.env 只承载两个变量:加载哪个配置文件,以及用来加密敏感值的密钥。
echo "ENV=localdb" > .envecho "CONFIG_ENCRYPTION_KEY=$(openssl rand -hex 16)" >> .envconfig.yaml 是仓库自带的只读模板。你的改动写进 config.<ENV>.yaml;当 ENV=localdb 时,就是 config.localdb.yaml:
JWT_KEY: 'a 32-byte random string'
EMAIL_PREDEFINE_CODES: caregiver@mirobody.ai: '111111'
OPENROUTER_API_KEY: 'sk-or-...'凡是键名里含 _KEY、_PASSWORD、_PASS、_PWD、_SECRET、_SK 或 _TOKEN 的值,都会在首次加载时用 CONFIG_ENCRYPTION_KEY 自动加密。完整的键清单见配置。
把应用指向发布出来的端口
config.yaml 里预置的是容器网络地址(PG_HOST: 10.108.0.2、REDIS_HOST: 10.108.0.9),因为应用容器是在那里找到它们的。运行在宿主机上的进程要走发布出来的端口,所以要覆盖掉:
PG_HOST: localhostPG_PORT: 18082REDIS_HOST: localhostREDIS_PORT: 18089运行
mirobody serve服务监听 http://localhost:18080。用 caregiver@mirobody.ai 加你写在 EMAIL_PREDEFINE_CODES 里的验证码登录。
后台工作指的是 IndicatorSync 与 ProfileRefresh 这两个任务队列。它们运行在第二个进程里,不在 Web 服务进程内:
mirobody worker五个配置键告诉引擎去哪里找你自己的代码。每个键都是一个目录列表,而且默认只有一条(包内那条)。把你自己的加上并列在最前面,它就会先于内置目录被扫描:
| 键 | 默认值 |
|---|---|
MCP_TOOL_DIRS | mirobody/agent/tools |
MCP_RESOURCE_DIRS | mirobody/agent/resources |
AGENT_DIRS | mirobody/agent |
PROVIDER_DIRS | mirobody/pulse/providers |
SKILL_DIRS | mirobody/agent/skills |
因为一切都在运行期发现,新增一个工具、agent 或 provider 只需要新增文件再重启进程:没有注册表要改,也不需要重新构建。
测试就放在它所覆盖的代码旁边:比如 mirobody/mcp/service.py 的测试就是 mirobody/mcp/test_protocol.py。testpaths 已经设好,所以整个套件就是一句裸 pytest:
pip install -e '.[agents,test]'pytest# 全部通过,没有失败不需要数据库、不需要网络、不需要 API key。只装 '.[test]'(不带 [agents])也是官方支持的一种精简安装:它只运行引擎那部分测试,并打印一行提示,说明 agent 层的测试被跳过了。
有两个套件承载着这个项目对外的主张,也是你改动 ② 标准化任一半之后该运行的:
| 套件 | 覆盖什么 |
|---|---|
mirobody/test_engine.py | golden LOINC 编码:把整条链钉住(别名索引 → 常见度先验 → axis 表) |
mirobody/test_engine_coverage.py | 对外公布的准确率数字,197/197,带一个覆盖率下限,掉下去就让构建失败 |
mirobody/mcp/test_protocol.py | MCP 线上行为:版本协商、resultType、server/discover |
mirobody/pulse/gate_tests/ | 每家厂商载荷一份快照 → StandardPulseData |
mirobody/pulse/aggregate/ | 日聚合、CGM 指标、来源优先级(唯一会碰配置的套件) |
pytest 之外的检查
Section titled “pytest 之外的检查”lint-imports # 两条 import-linter 契约lint-imports 强制执行这两条 import-linter 契约,把 langchain*、deepagents、langgraph 挡在 agent/ 与 server/ 之外,详见引擎即库。
Pulse gate 测试
Section titled “Pulse gate 测试”provider 管线的验收套件在 mirobody/pulse/gate_tests/:它把录下来的厂商载荷重放过 format_data(),再和存好的快照比对;不需要服务、不需要数据库、不需要网络:
pytest mirobody/pulse/gate_tests -vpytest mirobody/pulse/gate_tests --update-snapshots # 在形状被有意改动之后细节(包括怎么加一个用例)见Provider 测试。
带注解的目录树在安装指南里:各个包、扩展目录、部署相关文件都在那份树里标注清楚了。那是唯一的一份,本页不再重复。
分支、规范,以及一个 PR 需要什么
接入一个新的健康数据源
gate 测试与线上 Pulse 路由
用容器运行起整套栈