跳转到内容
快速开始

基于 Mirobody 进行开发

开发环境搭建

从源码检出运行 Mirobody Python 引擎:虚拟环境、可编辑安装、Docker 里的 Postgres 与 Redis,以及测试套件。

Mirobody 是一个 Python 服务(requires-python = ">=3.12")。在它上面做开发,就是创建虚拟环境、以可编辑模式安装本包、用 Compose 起 Postgres 与 Redis,然后运行 mirobody serve。没有编译步骤。

Python ≥ 3.12

pyproject.toml 声明了 requires-python = ">=3.12"

Docker + Compose

用于起 Postgres(pgvector/pgvector:pg17-trixie)与 Redis(redis:7.0-alpine)容器

Git + Git LFS

mirobody/res/*.bin*.npz*.npy*.gz 都是 LFS 对象

克隆仓库

Terminal window
git clone https://github.com/thetahealth/mirobody.git
cd mirobody

启动 Postgres 与 Redis

compose.yaml 定义了四个服务:pgredismirobodymirobody_worker。本地开发只需要那两个后端存储;应用本身运行在你的宿主机上:

Terminal window
docker compose up -d pg redis

它们在宿主机上发布 18082 → Postgres18089 → Redis

创建虚拟环境并安装

Terminal window
python3 -m venv venv
source venv/bin/activate # Windows 下:venv\Scripts\activate
pip install --upgrade pip
pip install -e .

pip install -e . 装到的是引擎:作为库的 ① 采集与 ② 标准化,不带数据库驱动、不带 HTTP 服务。要动对话服务或那两个 agent,就得装 [agents] extra,它会把 [server] 一并带上:

Terminal window
pip install -e '.[agents,test]' # 做开发要的就是这个
pip install -e '.[cn]' # 阿里云 OSS + 火山引擎 Ark
pip install -e '.[indicator-build]' # 只在要重新生成术语包时才用

整个仓库不存在任何 Node.js 依赖。

写好 .env 与你的配置覆盖文件

.env 只承载两个变量:加载哪个配置文件,以及用来加密敏感值的密钥。

Terminal window
echo "ENV=localdb" > .env
echo "CONFIG_ENCRYPTION_KEY=$(openssl rand -hex 16)" >> .env

config.yaml 是仓库自带的只读模板。你的改动写进 config.<ENV>.yaml;当 ENV=localdb 时,就是 config.localdb.yaml

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.2REDIS_HOST: 10.108.0.9),因为应用容器是在那里找到它们的。运行在宿主机上的进程要走发布出来的端口,所以要覆盖掉:

config.localdb.yaml
PG_HOST: localhost
PG_PORT: 18082
REDIS_HOST: localhost
REDIS_PORT: 18089

运行

Terminal window
mirobody serve

服务监听 http://localhost:18080。用 caregiver@mirobody.ai 加你写在 EMAIL_PREDEFINE_CODES 里的验证码登录。

后台工作指的是 IndicatorSyncProfileRefresh 这两个任务队列。它们运行在第二个进程里,不在 Web 服务进程内:

Terminal window
mirobody worker

五个配置键告诉引擎去哪里找你自己的代码。每个键都是一个目录列表,而且默认只有一条(包内那条)。把你自己的加上并列在最前面,它就会先于内置目录被扫描:

默认值
MCP_TOOL_DIRSmirobody/agent/tools
MCP_RESOURCE_DIRSmirobody/agent/resources
AGENT_DIRSmirobody/agent
PROVIDER_DIRSmirobody/pulse/providers
SKILL_DIRSmirobody/agent/skills

因为一切都在运行期发现,新增一个工具、agent 或 provider 只需要新增文件再重启进程:没有注册表要改,也不需要重新构建。

测试就放在它所覆盖的代码旁边:比如 mirobody/mcp/service.py 的测试就是 mirobody/mcp/test_protocol.pytestpaths 已经设好,所以整个套件就是一句裸 pytest

Terminal window
pip install -e '.[agents,test]'
pytest
# 全部通过,没有失败

不需要数据库、不需要网络、不需要 API key。只装 '.[test]'(不带 [agents])也是官方支持的一种精简安装:它只运行引擎那部分测试,并打印一行提示,说明 agent 层的测试被跳过了。

有两个套件承载着这个项目对外的主张,也是你改动 ② 标准化任一半之后该运行的:

套件覆盖什么
mirobody/test_engine.pygolden LOINC 编码:把整条链钉住(别名索引 → 常见度先验 → axis 表)
mirobody/test_engine_coverage.py对外公布的准确率数字,197/197,带一个覆盖率下限,掉下去就让构建失败
mirobody/mcp/test_protocol.pyMCP 线上行为:版本协商、resultTypeserver/discover
mirobody/pulse/gate_tests/每家厂商载荷一份快照 → StandardPulseData
mirobody/pulse/aggregate/日聚合、CGM 指标、来源优先级(唯一会碰配置的套件)
Terminal window
lint-imports # 两条 import-linter 契约

lint-imports 强制执行这两条 import-linter 契约,把 langchain*deepagentslanggraph 挡在 agent/server/ 之外,详见引擎即库

provider 管线的验收套件在 mirobody/pulse/gate_tests/:它把录下来的厂商载荷重放过 format_data(),再和存好的快照比对;不需要服务、不需要数据库、不需要网络:

Terminal window
pytest mirobody/pulse/gate_tests -v
pytest mirobody/pulse/gate_tests --update-snapshots # 在形状被有意改动之后

细节(包括怎么加一个用例)见Provider 测试

带注解的目录树在安装指南里:各个包、扩展目录、部署相关文件都在那份树里标注清楚了。那是唯一的一份,本页不再重复。