> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirobody.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 架构概览

> Mirobody C++ 引擎的结构：LLM 客户端、MCP 工具、Agent、健康 vendor 与内嵌的 FHIR R4。

Mirobody 是一套 **C++11 引擎**。它可以在桌面/服务器上独立运行，也可以在 Android / iOS 应用内**端侧**运行，因此健康数据无需离开手机。它用 CMake 构建（Windows 上外加 vcpkg），由五个可以独立扩展的部分组成。

<Frame caption="Mirobody：一个 C++ 核心（LLM 客户端 · MCP 工具 · Agent · 健康 vendor · FHIR R4），以独立二进制、Android JNI 库或 iOS C API 的形式交付。">
  <img src="https://mintcdn.com/thetahealth/5myzHHPHug2m7fAL/images/architecture_cn.svg?fit=max&auto=format&n=5myzHHPHug2m7fAL&q=85&s=8e649984f60e4e39100ee5b4b210b8dd" alt="Mirobody architecture overview" width="1060" height="660" data-path="images/architecture_cn.svg" />
</Frame>

## 五个部分

| 部分            | 路径                                  | 说明                                                                                                                                                                           |
| ------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **LLM 客户端**   | `src/llm/`                          | 每个 provider 一个流式 `llm::Client`：`OpenAIChatClient`、`GeminiClient`、`MiroThinkerClient`，外加 `EmbeddingClient` 以及实时的 `OpenAIRealtimeClient` / `GeminiLiveClient`（WebSocket 上的音频）。 |
| **MCP 工具**    | `src/mcp/` + `res/mcp_tools/`       | 通过 `/mcp` 端点（JSON-RPC 2.0）暴露的服务端工具。九个内置工具是在编译时自注册的 C++ 文件。                                                                                                                   |
| **Agent**     | `src/chat/` + `res/agents/base.cpp` | 一个 Agent（"Base"）：按 provider 选择一个 LLM 客户端，构建 system prompt，把这一轮流式返回，其间调用 MCP 工具。                                                                                              |
| **健康 vendor** | `src/health/vendor/`                | 每个数据源一个 `vendor::Vendor`，置于 authorize / fetch / webhook 契约之后，通过注册表按 id 解析。                                                                                                   |
| **FHIR R4**   | `src/fhir/`                         | 内嵌的 RESTful FHIR R4 端点 + 术语（单位归一化为 UCUM）。                                                                                                                                    |

Agent 和工具都在**编译时自注册**：把一个 `.cpp` 丢进相应的 `res/` 目录并重新构建 —— `CMakeLists.txt` 会用 `CONFIGURE_DEPENDS` glob `res/mcp_tools/*.cpp`（以及 `res/agents/`）。

## Agent

Mirobody 运行**一个简单的 Agent** —— [`res/agents/base.cpp`](https://github.com/thetahealth/mirobody/blob/main/res/agents/base.cpp)。它没有 Agent 循环，没有 planner，也没有中间件。每一轮它按 **provider 名称**选择一个 LLM 客户端，构建一段固定的内联 **system prompt**（当前时间、回复语言，以及使用文件 / 健康工具的引导），并把 **provider 的事件直接流式返回**，让模型调用内置的 MCP 工具。

<Note>
  该 Agent 刻意保持轻量：它选择一个 **provider**，构建提示词，流式返回一轮，并按需调用 MCP 工具。你选择的是一个 **模型**（`provider`），而不是 Agent 类型。
</Note>

### 支持的提供商

该 Agent 注册最多四个 provider 客户端，以 `/api/providers` 选择器展示的模型名为键：

* **`gemini-2.5-flash`** —— Google Gemini 2.5 Flash（**默认** provider），`GeminiClient`。
* **`gpt-5-nano`** —— OpenAI GPT-5 nano，`OpenAIChatClient`。
* **`mirothinker-1.7`** —— MiroThinker（MiroMind），`MiroThinkerClient`。
* **`gemma-4-e2b`** —— 端侧 Gemma 4 E2B，通过本地 OpenAI 兼容端点提供服务（仅在设置了 base URL 时才注册）。

原生应用还会在**端侧**运行 **Gemma 4 E2B**（Android/iOS 上用 LiteRT-LM，Electron 上用 llama.cpp）—— 完全离线、无需 API 密钥。**工具执行因 provider 而异：** OpenAI 和 Gemini 把工具作为 function-call 描述符接收，引擎以已认证用户的身份在**本地进程内**执行每次调用；MiroThinker 则在 **provider 侧**运行工具 —— MiroMind 通过公网在 `MCP_PUBLIC_URL` 反向访问你的 `/mcp` 端点。实时音频聊天可通过 WebSocket 经 OpenAI Realtime 和 Gemini Live 使用。

配置见 [工具与 Agent 概览](/zh/tools/overview)。

## MCP 工具

工具是 [`res/mcp_tools/`](https://github.com/thetahealth/mirobody/tree/main/res/mcp_tools) 中的 C++ 文件。每个声明一个 `Tool` —— 名称、描述、一个 `auth` 标志、一张 `Param` 表以及一个 handler —— 并通过 `MIROBODY_REGISTER_TOOL(...)` 自注册。C++11 没有运行时反射，因此参数显式声明，注册表会把它们展开成 MCP 的 `inputSchema` 以及 OpenAI / Gemini 的 function 描述符。

```cpp theme={null}
// res/mcp_tools/echo.cpp — the smallest complete tool
const Tool kEcho = {
    "echo",
    "Echo back the provided text.",
    false,                                                    // auth
    { Param("text", Type::String, Required, "Text to echo back") },
    &echo,
};
MIROBODY_REGISTER_TOOL(kEcho);
```

默认提供九个工具：`list_files`、`read_file`、`family_health`、`whoami`、`recall_memory`、`remember`、`render_chart`、`summarize_conversation` 和 `echo`。一个 `auth` 工具以 `UserInfo` 接收调用者身份；它需要的其它后端（缓存、对象存储、数据库、记忆）通过 `ToolContext` 送达。参见 [内置工具](/zh/tools/built-in) 与 [添加自定义工具](/zh/tools/adding-tools)。

## 健康 vendor

每个数据源是 `src/health/vendor/` 中的一个 `vendor::Vendor`，置于同一份 authorize / fetch / webhook 契约之后，并通过注册表按 id 解析。分桶如下：

| 分桶            | 路径          | 数据源                                                                                                |
| ------------- | ----------- | -------------------------------------------------------------------------------------------------- |
| **Platforms** | `platform/` | 15 个 B2B 聚合器 —— Terra、Validic、Human API、Junction、Metriport……                                       |
| **Phone**     | `phone/`    | Huawei                                                                                             |
| **Device**    | `device/`   | Fitbit、Garmin、Withings、Oura、Polar                                                                  |
| **EHR**       | `ehr/`      | SMART on FHIR —— 面向 ONC 认证 EHR（Epic、Oracle Health / Cerner、athenahealth）的一个通用客户端，通过 ONC Lantern 发现 |

仅端侧的存储（Apple Health、Samsung Health、Google Health Connect、Xiaomi）**没有服务端客户端** —— 由宿主应用在端侧读取并 POST FHIR `Observation`。要添加一个数据源，实现一个 `vendor::Vendor`；参见 [Provider 集成](/zh/development/provider-integration)。

## FHIR R4 与术语

`src/fhir/` 内嵌了一个 RESTful FHIR R4 端点（`/fhir/*`）。单位归一化为 **UCUM**。上传的文档会被解析成指标和数值。把指标映射到 **SNOMED CT / LOINC / RxNorm**，以及完整的文档→指标术语流水线，**部分仍在进行中** —— UCUM 已交付；更广的术语映射仍在落地。*(verify：以当前构建为准确认确切状态。)*

## 存储与基础设施

* **数据库** —— 在**构建期**通过 CMake `-DMIROBODY_DATABASE_BACKEND=` 选定：`SQLITE`（移动端默认）、`POSTGRESQL`（桌面端默认）、`MYSQL`、`DUCKDB` 或 `CLICKHOUSE`。SQL schema 位于 [`res/sql/`](https://github.com/thetahealth/mirobody/tree/main/res/sql)。
* **文件存储** —— S3 / S3 兼容（MinIO、R2）、阿里云 OSS、Azure Blob 或本地文件系统（默认），在运行时选定。
* **缓存** —— 默认是一个进程内的内存 KV 存储，或在设置了 `REDIS_HOST` 时使用 Redis。
* **配置** —— `config.yml`（源自 `config.example.yml`）；优先级为 环境变量 > `config.yml` > 远程配置 > `config.example.yml`。键名包含 `_KEY` / `_PASSWORD` / `_SECRET` / `_TOKEN`（及类似）的值会用 `CONFIG_ENCRYPTION_KEY` 自动加密（Fernet）。参见 [配置](/zh/configuration)。
* **认证** —— 多用户 JWT；一个带 OIDC discovery + PKCE 的 OAuth 2.0 授权服务器（以便 MCP 客户端为 `/mcp` 获取 token）；通过邮箱一次性验证码，以及 Google / Apple / WeChat / GitHub（Firebase）外加 Tanka QR 登录。
* **Web 客户端** —— `htdoc/` 中的一个静态 SPA，构建进 `res/htdoc`（`HTTP_ROOT`）并在 HTTP 根路径提供服务。

## 部署：一个核心，三种形态

同一个核心以三种方式交付：

1. **独立二进制** —— `./build.sh` → `build/mirobody`，在 `HTTP_HOST:HTTP_PORT`（默认 `0.0.0.0:8080`）上提供 HTTP + WebSocket 服务，并读取 `./config.yml`。
2. **Android** —— `libmirobody.so` 通过 **JNI** 加载进宿主应用（Gradle + NDK）。
3. **iOS** —— `libmirobody.a` / `mirobody.xcframework` 通过 `src/mirobody.h` 中的 **C API** 链接。

那个 `extern "C"` C API 还让 Java、Go、C#、Rust、Swift 或 Python 得以直接嵌入该核心。

### HTTP 路由

| 路由                      | 用途                                                               |
| ----------------------- | ---------------------------------------------------------------- |
| `/api/health`           | 健康检查                                                             |
| `/api/chat`             | 聊天 —— **POST** 流式返回 Server-Sent Events；**GET** 升级为 WebSocket（实时） |
| `/api/providers`        | 列出可用 provider                                                    |
| `/api/history`          | 对话历史                                                             |
| `/api/files`            | 文件上传 / 列表                                                        |
| `/fhir/*`               | 内嵌的 FHIR R4 端点                                                   |
| `/mcp`, `/mcp/{secret}` | MCP 端点（JSON-RPC 2.0）                                             |
| `/oauth/*`              | OAuth 2.0 授权服务器                                                  |

## 端到端请求流程

已登录用户在 Web UI 里发出\*"我最近睡得怎么样？"\*时，会发生什么：

```
1. Browser POSTs to /api/chat (Server-Sent Events).
2. JWT middleware resolves the caller → user_id.
3. The chat service seeds/uses a conversation and persists the user message.
4. The Base agent is created: it detects the response language, builds the
   system prompt, and resolves the LLM client for the requested provider
   (default gemini-2.5-flash).
5. The client streams the turn. When the model calls a tool:
   - OpenAI / Gemini → the engine runs it locally in-process as the user
     (e.g. family_health → recent FHIR Observations; render_chart → a chart
     event the frontend draws with ECharts).
   - MiroThinker → the tool runs provider-side over MCP_PUBLIC_URL.
6. Reply chunks stream back over SSE; the response is persisted.
7. summarize_conversation may set a short title for the chat-history list.
```

会话分享（无需登录的只读路径）见 [会话分享](/zh/api-reference/chat)。

## 下一步去哪

<CardGroup cols={2}>
  <Card title="Providers" icon="plug" href="/zh/concepts/providers">
    设备和 EHR 如何接入
  </Card>

  <Card title="数据流" icon="arrow-progress" href="/zh/concepts/data-flow">
    从厂商原始 payload 到归一化的 FHIR
  </Card>

  <Card title="文件处理" icon="file" href="/zh/concepts/file-processing">
    多格式文件的接入与解析
  </Card>

  <Card title="工具与 Agent" icon="wrench" href="/zh/tools/overview">
    跨 MCP 生态构建并暴露工具
  </Card>
</CardGroup>
