跳转到主要内容
Mirobody 通过单个 config.yml 文件配置 —— 一组扁平的键,由 C++ 内核解析。把提交在仓库里的模板复制成 config.yml 再编辑;每个键都有可用的默认值,所以你只需设置真正要改的那些。
cp config.example.yml config.yml
配置更改在重启后生效。config.yml 已被 git 忽略 —— 只提交 config.example.yml

解析顺序

配置按键从分层来源合并,高优先级覆盖低优先级:
优先级来源说明
1(最高)环境变量任何键都可被同名环境变量覆盖。
2config.yml你的本地文件(已被 git 忽略)。
3远程配置仅当 CONFIG_SERVERCONFIG_TOKENENV 三者都设置时拉取。
4(最低)config.example.yml提交在仓库里的默认值模板。

加密的密钥

任何以 gAAAA 开头的字符串值都会被当作 Fernet token,在设置了 CONFIG_ENCRYPTION_KEY 时于加载时解密(config.yml 和远程拉取都适用)。反过来,键名包含 _KEY_PASSWORD_PASS_PWD_SECRET_SK_TOKEN 的值,会用同一个 CONFIG_ENCRYPTION_KEY 自动加密 —— 于是你填进去的明文密钥会被改写成静态的 gAAAA…
# 生成一个密钥
openssl rand -hex 32

# 经环境提供(不存进 config.yml)
export CONFIG_ENCRYPTION_KEY="<your-key>"
PG_ENCRYPTION_KEY 有意自动加密(不做 _KEY 后缀处理)—— 它是用来加密数据列的密钥,因此必须保持可读,以便引导数据库启动。生产环境把它放在环境变量或密钥管理器里。

HTTP 服务器

config.yml
HTTP_HOST: '0.0.0.0'      # 监听所有接口
HTTP_PORT: 8080           # 默认端口
# HTTP_URI_PREFIX: ''     # 把整个应用挂到子路径下,例如 '/mirobody'
HTTP_ROOT: 'res/htdoc'    # 为非 API 的 GET 提供的静态 Web 客户端

# CORS(取消注释以为浏览器客户端启用)
# HTTP_HEADERS:
#   Access-Control-Allow-Origin: '*'
#   Access-Control-Allow-Methods: 'GET, POST, PUT, DELETE, OPTIONS'
#   Access-Control-Allow-Headers: 'Authorization, Content-Type, X-Timezone'
#   Access-Control-Max-Age: '86400'
鉴权用的是 Authorization 头里的 bearer token(不是 cookie),所以本地使用时 Access-Control-Allow-Origin: '*' 没问题。不要把 '*'Access-Control-Allow-Credentials: 'true' 一起用 —— 浏览器会拒绝;需要携带凭据时改用固定 origin。生产环境把 origin 限制到你的域名。

日志

config.yml
LOG_LEVEL: 'INFO'     # debug | info | warning | error | critical(大小写不敏感)
LOG_NAME: 'mirobody'
LOG_DIR: ''           # 留空 => stdout;设一个路径则写日志文件

LLM 提供商

至少设置一个提供商密钥以启用对话。Agent 在请求时按提供商名挑客户端;默认提供商回退是 gemini-2.5-flash。工具执行方式因提供商而异:OpenAI 和 Gemini 在进程内本地运行内置的 MCP 工具,而 MiroThinker 在提供商侧执行工具(因此需要一个公网可达的 MCP_PUBLIC_URL)。

Google Gemini

config.yml
GOOGLE_API_KEY: 'AIza...'    # AI Studio 密钥(也会读取为 GEMINI_API_KEY)
要覆盖 HIPAA/BAA,把 Gemini 经 Vertex AI 而非 AI Studio 路由:
config.yml
GOOGLE_GENAI_USE_VERTEXAI: '1'
VERTEX_ACCESS_TOKEN: ''      # OAuth 访问令牌,例如 `gcloud auth print-access-token`(约每小时轮换)
GCP_PROJECT: ''              # Google Cloud 项目 id(也会读取为 GOOGLE_CLOUD_PROJECT)
VERTEX_LOCATION: 'us-central1'
# VERTEX_BASE_URL: ''        # 可选的 host 覆盖(主权云 / 区域)

OpenAI

config.yml
OPENAI_API_KEY: 'sk-...'
# OPENAI_BASE_URL: ''        # 指向任意 OpenAI 兼容端点(OpenRouter、DeepSeek、Groq…)
要覆盖 HIPAA/BAA,把 GPT 跑在你自己的 Azure OpenAI 资源里 —— 设置了 AZURE_OPENAI_ENDPOINT 时客户端会自动切到 Azure 模式:
config.yml
AZURE_OPENAI_ENDPOINT: 'https://my-resource.openai.azure.com'
AZURE_OPENAI_DEPLOYMENT: 'gpt-4o-mini'
AZURE_OPENAI_API_VERSION: '2024-10-21'
AZURE_OPENAI_API_KEY: ''     # 或 AZURE_OPENAI_KEY

MiroThinker

config.yml
MIROTHINKER_API_KEY: '...'   # MiroThinker 提供商必需
# MIROTHINKER_BASE_URL: '...'   # 端点覆盖 *(待核实)*
# MIROTHINKER_MODEL: '...'      # 模型名 *(待核实)*
MiroThinker 在提供商侧运行工具:MiroMind 的端点会经公网回调到服务器的 /mcp,所以你还必须设置一个公网可达的 MCP_PUBLIC_URL。localhost 或私网地址不行。

设备本地 Gemma(可选)

原生应用可以完全在设备本地运行 Gemma 4 E2B(Android/iOS 上经 LiteRT-LM,Electron 上经 llama.cpp)—— 无密钥、无网络。如果你自托管了一个 Gemma 运行时(例如 Ollama),把独立服务器指向它:
config.yml
# GEMMA_CHAT_BASE_URL: 'http://localhost:11434/v1'   # 回退到 OLLAMA_BASE_URL
# GEMMA_CHAT_MODEL: 'gemma-4-e2b'                     # 你的运行时提供的标签
# GEMMA_CHAT_API_KEY: ''                              # 本地服务器通常留空

Embeddings

config.yml
EMBEDDING_PROVIDER: 'gemini'   # embeddings 提供商(使用上面的 Gemini/Google 密钥)

数据库

二进制里只编译进一个 SQL 后端(在构建期经 MIROBODY_DATABASE_BACKEND 选定 —— 参见 安装指南)。下面这些键配置的是 PostgreSQL 后端,即桌面默认:
config.yml
PG_HOST: '127.0.0.1'
PG_PORT: 5432
PG_USER: 'postgres'
PG_DBNAME: 'mirobody'
PG_SCHEMA: 'public'
PG_PASSWORD: 'REPLACE_THIS_VALUE_IN_PRODUCTION'
PG_ENCRYPTION_KEY: 'REPLACE_THIS_VALUE_IN_PRODUCTION'   # 加密敏感数据列
SQLite 后端(移动端 / 自包含构建)无需连接设置。MySQL、DuckDB、ClickHouse 各有类似的键块。

缓存

缓存层是可选的。让 REDIS_HOST 留空,服务器就用进程内的内存 KV 存储 —— 单实例运行没问题。设置 REDIS_HOST 以在多实例间共享缓存状态:
config.yml
# REDIS_HOST: ''
# REDIS_PORT: 6379
# REDIS_PASSWORD: ''

文件存储

上传的文件和生成的资源(例如图表)会写入一个存储后端,在运行时选定。默认是本地文件系统;其他后端(S3 / S3 兼容、阿里云 OSS、Azure Blob)通过填写各自的块来启用。
config.yml
LOCAL_STORAGE_DIR: '_local/storage'          # 对象写入位置
LOCAL_STORAGE_URL_PREFIX: '/files'           # 本服务器提供对象的 URL 路径
LOCAL_STORAGE_SECRET: 'REPLACE_THIS_VALUE_IN_PRODUCTION'  # 预签名 URL 的 HMAC 密钥(设置了 URL 前缀时需 >=16 字符)
# LOCAL_STORAGE_PREFIX: ''                   # 对象键前缀(留空 => 'mirobody')
# LOCAL_STORAGE_BASE_URL: ''                 # 公开前缀 / CDN 基址
上传的可选静态加密:设置 FILE_ENCRYPTION_KEY(一个可轮换的列表 —— 最后一个密钥负责加密,所有密钥都可解密)外加一个稳定的 FILE_KEY_SEED。参见 config.example.yml 里的注释。

长期记忆

remember / recall_memory 工具存储持久事实。每个后端都会编译进来;在运行时挑一个:
config.yml
MEMORY_PROVIDER: 'local'   # local(默认)| mem0 | zep | everos
local 把事实连同 1024 维 embeddings 存进应用数据库,按进程内余弦相似度排序 —— 无需额外服务。其他后端经 HTTP 与远程记忆服务通信。

鉴权

邮箱验证码

Web 客户端的默认登录方式。本地测试用预置验证码:
config.yml
EMAIL_PREDEFINE_CODES:
  demo1@mirobody.ai: '777777'
  demo2@mirobody.ai: '777777'
  demo3@mirobody.ai: '777777'
生产环境切勿保留预置验证码。

JWT

config.yml
JWT_KEY: 'REPLACE_THIS_VALUE_IN_PRODUCTION'    # HS256 密钥(256 位):`openssl rand -hex 32`
JWT_SALT: 'REPLACE_THIS_VALUE_IN_PRODUCTION'
# JWT_PRIVATE_KEY: |                            # 设置以启用 RS256 —— 优先于 JWT_KEY,并发布 JWKS
#   -----BEGIN PRIVATE KEY-----
#   ...
只设置一种签名模式:JWT_KEY 用于 HS256,或 JWT_PRIVATE_KEY 用于 RS256(经发布的 JWKS 启用第三方令牌校验)。cli/jwt_keygen 工具可生成一对 RSA 密钥。

社交登录(可选)

Google、Apple、X 登录经 Firebase;WeChat 和 GitHub 是直连;Tanka 二维码登录默认开启。
config.yml
FIREBASE_PROJECT_ID: ''          # 校验 Google/Apple/X 的 ID token
# FIREBASE_WEB_API_KEY: ''       # Web 应用浏览器 apiKey
# FIREBASE_MESSAGING_SENDER_ID: ''
# APPLE_CLIENT_ID: ''
# WECHAT_APPID: ''
# WECHAT_SECRET: ''
# GITHUB_CLIENT_ID: ''
# GITHUB_CLIENT_SECRET: ''
# TANKA_LOGIN_ENABLED: true      # 二维码登录;设为 false 可隐藏按钮

OAuth 2.0 授权服务器

Mirobody 内嵌一个 OAuth 2.0 授权服务器(授权码 + PKCE),让 MCP 客户端可以经浏览器获取令牌,而不必粘贴 bearer token。它配合上面的 JWT 密钥工作;所有 OAUTH_* 键都有可用默认值。
config.yml
# JWT_ISS: ''          # 铸进自签名令牌的 iss/aud/client_id/scope 声明
# JWT_AUD: ''
# OAUTH_RESOURCE_PATH: '/mcp'   # 这些令牌保护的资源
发现文档在 /.well-known/oauth-authorization-server/.well-known/openid-configuration/.well-known/jwks.json 提供。

MCP 公开 URL

config.yml
# MCP_PUBLIC_URL: 'https://yourdomain.com'
MCP_PUBLIC_URL 是你 MCP 端点对外可达的基址(<MCP_PUBLIC_URL>/mcp)。它是 MiroThinker 提供商(工具在提供商侧运行)必需的,也是把 MCP 服务器暴露给 ChatGPT Apps、远程 Claude Desktop 及其他 MCP 客户端所必需的。本地开发没有公网域名时,用隧道打通它:
1

安装并运行 ngrok

ngrok http 8080
2

设置隧道 URL

config.yml
MCP_PUBLIC_URL: 'https://abc123.ngrok-free.app'
参见 ChatGPT Apps

健康圈(Care circles)

在单用户内核之上的可选分享功能。规模由上限约束(0 禁用对应项):
config.yml
CIRCLE_MAX_PER_USER: 5    # 一个用户可拥有的最大圈子数
CIRCLE_MAX_MEMBERS: 5     # 每个圈子的最大成员数(待处理的邀请也计入)
分享默认关闭;AI 助手对另一位成员的数据是只读的。参见 架构概览

对话限流

对每个用户的 Agent / 实时轮次设上限:
config.yml
CHAT_RATE_MAX: 5           # 每个用户每个窗口的最大轮次(0 = 不限)
CHAT_RATE_WINDOW_SEC: 60   # 窗口长度(秒)

远程配置(可选)

从一个服务而非本地文件拉取配置 —— 仅当三者都设置时生效:
config.yml
# 经环境变量:
# CONFIG_SERVER=https://config.example.com
# CONFIG_TOKEN=<作为 X-Config-Token 发送的 bearer>
# ENV=prod                  # 选择远程环境

配置最佳实践

  • ✅ 提交 config.example.yml
  • ❌ 绝不提交带真实凭据的 config.yml(它默认已被 git 忽略)
  • ✅ 经环境变量提供 CONFIG_ENCRYPTION_KEY,而非写进文件
  • 把每一个 REPLACE_THIS_VALUE_IN_PRODUCTION 占位符替换成强随机值
  • 当其他服务需要校验你的令牌时,使用 RS256(JWT_PRIVATE_KEY
  • 生产环境限制 CORS origin
  • 让 PHI 留在设备本地,或把托管 LLM 调用经 BAA 覆盖的通道路由(Vertex AI / Azure OpenAI)
python3 -c "import yaml; yaml.safe_load(open('config.yml'))"
没有输出表示语法有效。服务器也会在启动时报告配置错误,而不是静默降级。

下一步

快速开始

用这份配置构建内核并运行

Provider 集成

接入新的健康数据源

API 参考

HTTP、WebSocket、MCP 和 FHIR 端点

生产部署

后端、密钥与加固