内容
# AI 操作系统 (AI-OS)
AI-OS 是一个生产级别的多智能体系统,它将零碎的信息——项目笔记、团队信号、候选人简介、会议准备——综合成结构化、证据基础的输出。
四个工作流领域共享一个共同的架构:一个路由层,负责分类传入的请求并将它们分派到正确的领域图;一个检索层,从本地 Markdown 文件或语义向量存储中提取相关证据;一个综合层,生成具有强制源引用的结构化输出;一个验证层,在任何响应到达 API 之前强制接地。
---
**招聘者/招聘经理演练:** [SHOWCASE.md](SHOWCASE.md) - 用例、领域演练和实时 curl 示例,以及系统背后的工程决策。
---
## 为什么这很重要
生产 AI 部署以可预测的方式失败:幻觉内容没有引用轨迹,模型路径在 LLM 不可用时静默中断,无法衡量系统演化过程中合成质量是否下降,观察性需要代码更改才能打开或关闭。AI-OS 被设计为在架构层面解决所有四个问题——不是作为事后补充,而是作为不变式。
证据基础在模式级别通过强制工具使用强制执行:每个输出项必须携带 `source` 文件名和 `line_number`。系统没有路径可以生成未引用的响应。确定性回退始终可用——如果模型综合失败或没有 API 密钥,系统会生成基于关键词提取的接地输出,而不会出现静默降级。评估套件在每个 PR 上运行 22 个用例,涵盖三个检索路径。观察性通过环境变量选择加入:设置 `LANGSMITH_TRACING=true` 会在所有四个领域图上发出节点级跟踪信息,而无需更改代码。
---
## 领域
| 领域 | 综合内容 |
|---|---|
| **Director OS** | 项目笔记 → 胜利、风险、下一步行动,用于每周领导力更新 |
| **Brand OS** | 技术工作笔记 → 内容帖大纲、播客角度、存储库改进 |
| **Interview OS** | 招聘笔记 → 候选人简介,包含关键问题、谈话要点、红旗 |
| **One-on-One OS** | 直接报告笔记 → 会议简介,包含行动项、阻碍因素、赞扬 |
---
## 本项目展示的内容
| 能力 | 实现方式 |
|---|---|
| 多领域 LLM 编排 | 首席助手路由器 + 4 个领域 LangGraph 图 |
| 进程内 MCP 工具循环 | `packages/shared/mcp/filesystem_server.py` + `orchestrator_integration.py` |
| 独立 MCP 服务器 | `apps/mcp/server.py` - 所有 4 个领域作为 MCP 工具 |
| 模式强制证据基础 | 强制工具使用,必填 `source` + `line_number` 字段 |
| 提供者抽象 | `base.py` 接口;`claude.py` / `ollama.py` / `grounding.py` 实现 |
| 可插拔检索后端 | 关键词 (`local_files.py`) 或语义 (`chroma.py`) 通过环境变量 |
| 多智能体管道 | `ResearcherAgent → WriterAgent` 具有结构化交接契约 |
| LLM 评估框架 | 22 个用例,3 个检索路径,提交结果,CI 门控 |
| 节点级可观察性 | LangSmith `@traceable` 在所有 4 个领域图上 - 无配置时静默无操作 |
| 提示缓存 + 成本可见性 | `cache_read_input_tokens` / `cache_creation_input_tokens` 在每个 `WorkflowTrace` 中 |
架构设计为可适应。提供者层、进程内文件系统工具循环和独立 MCP 服务器都可以更换——为企业 AI 工作所需的环境定制而设计。
---
## 架构
系统具有三个独立可配置的层:路由、检索和综合。更换任何层——路由模型、检索后端、综合提供者——只需要更改一个字段,而不需要重写工作流。
**路由** - 首席助手路由器使用本地 LLM 和紧凑的单令牌分类提示(`director_os`、`brand_os`、`interview_os`、`one_on_one_os`)对每个请求进行分类。当本地模型无法访问时,它会自动回退到关键词规则。路由决策不需要推理深度——它们需要快速、免费和零数据外流。分类任务的云 LLM 调用返回一个单词是浪费的。
**检索** - 两个后端共享一个公共接口。关键词后端 (`local_files.py`) 使用 BM25 风格的评分,无需外部依赖——它在 CI 中运行,无需服务。语义后端 (`chroma.py`) 使用 ChromaDB 和 `nomic-embed-text` 嵌入,通过 Ollama 实现更丰富的召回。后端选择器从环境中读取 `RETRIEVAL_BACKEND` 并自动切换。如果 Chroma 索引不存在,它将回退到关键词检索。
**综合** - 每个领域都作为编译后的 LangGraph `StateGraph` 运行,具有类型状态。节点:`retrieve_evidence → build_draft → assemble_response → validate_response`。在 `build_response` 之后,条件边路由到 `deterministic_fallback`,当模型综合失败且 `fallback_to_deterministic=True` 时。提供者抽象意味着切换综合提供者是请求上的单个字段——无需更改工作流逻辑。
```mermaid
flowchart TB
In([OrchestratorRequest]) --> MCP{"use_mcp?"}
MCP -->|true| MCPLoop["MCP Tool Loop\nLLM reads files via tool calls"]
MCP -->|false| CoS["Chief of Staff\nLocal LLM classification\n+ keyword fallback"]
MCPLoop --> CoS
CoS -->|director_os| Dir["Director OS\nretrieve_evidence"]
CoS -->|brand_os| Brand["Brand OS\nretrieve_evidence"]
CoS -->|interview_os| Interview["Interview OS\nretrieve_evidence"]
CoS -->|one_on_one_os| OneOnOne["One-on-One OS\nretrieve_evidence"]
Dir --> DModel{"use_model?"}
DModel -->|"provider: claude"| DC["Claude\ntool use + prompt cache"]
DModel -->|"provider: ollama"| DO["Ollama\nlocal inference"]
DModel -->|false| DDet["Deterministic\nkeyword extraction"]
DC --> DVal["validate_response\nevidence grounding"]
DO --> DVal
DDet --> DVal
Brand --> BModel{"use_model?"}
BModel -->|true| BC["Claude\ntool use"]
BModel -->|false| BDet["Deterministic\nsection formatter"]
Interview --> IModel{"use_model?"}
IModel -->|true| IC["Claude\ntool use"]
IModel -->|false| IDet["Deterministic\ngrounded extraction"]
OneOnOne --> OModel{"use_model?"}
OModel -->|true| OC["Claude\ntool use"]
OModel -->|false| ODet["Deterministic\ngrounded extraction"]
DVal --> TA{"target_audience?"}
BC --> TA
BDet --> TA
IC --> TA
IDet --> TA
OC --> TA
ODet --> TA
TA -->|set| Researcher["ResearcherAgent\nstructured synthesis"]
Researcher --> Writer["WriterAgent\naudience formatting"]
Writer --> RespA(["OrchestratorResponse\nformatted_content + agent_calls + trace"])
TA -->|not set| RespB(["OrchestratorResponse\nWorkflowTrace + cache metrics"])
style DC fill:#e8f5e9,stroke:#388e3c
style BC fill:#e8f5e9,stroke:#388e3c
style IC fill:#e8f5e9,stroke:#388e3c
style OC fill:#e8f5e9,stroke:#388e3c
style Researcher fill:#e8f5e9,stroke:#388e3c
style Writer fill:#e8f5e9,stroke:#388e3c
style DO fill:#fff3e0,stroke:#f57c00
style MCPLoop fill:#e3f2fd,stroke:#1565c0
```
---
## 关键设计决策
**强制工具使用而非提示指令。** 地基不变式通过 LLM 工具使用 API 的 JSON 模式强制执行,而不是系统提示指令。提示指令可以实现约 95% 的正确引用。通过必填模式字段(每个输出项的 `source` + `line_number`)可以结构性地实现 100% 正确引用:API 调用要么生成完全引用的响应,要么引发解析错误,从而触发确定性回退。没有“近似引用”的中间状态。
**模式作为单一真相来源。** 相同的 Pydantic `BaseModel` 定义驱动 FastAPI 请求验证、LangGraph 状态形状、从磁盘上的 JSON 反序列化为评估用例,以及 LangSmith 数据集同步。单一模式更改会传播到整个堆栈,而无需手动连接。
**评估测试失败模式,而不仅仅是成功路径。** 每个领域的评估套件都包括基准测试基础、跨多个文件的检索、提供者失败(`_FailingProvider`)、弱输出/空章节(`_WeakProvider`)和不支持的主张,这些主张会引用错误证据(`_UnsupportedClaimProvider`)。所有三个检索路径都在合并前通过 CI 门控。
**通过信息缩小实现多智能体管道。** `ResearcherAgent → WriterAgent` 管道不是两个模型之间的聊天。研究人员通过工具使用生成结构化的 `ResearchSynthesis` 对象。编写者仅接收该对象——不是原始证据。编写者可以重新措辞和重新格式化,但不能引入研究人员未提取的信息。幻觉表面仅限于重新格式化步骤。
**证据块上的提示缓存。** 证据块在每次综合调用时都标记为 `cache_control: {"type": "ephemeral"}`。在针对相同文档集的重复查询中(正常使用模式),LLM 会重用缓存的 KV 表示。在每个 `WorkflowTrace` 中,通过 `cache_read_input_tokens` 和 `cache_creation_input_tokens` 显示节省。
---
## 快速入门
要求:Python 3.11+
```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env
uvicorn apps.api.main:app --reload --env-file .env
```
系统在没有任何 API 密钥的情况下可以完全运行。模型综合通过请求上的 `use_model=True` 是可选的。在 `http://127.0.0.1:8000/` 打开操作员控制台。
```bash
# 运行所有本地评估 - 不需要 API 密钥
python scripts/run_director_os_evals.py
python scripts/run_brand_os_evals.py
python scripts/run_interview_os_evals.py
python scripts/run_one_on_one_os_evals.py
# 运行测试
pytest tests/ -v
```
---
## 与 Claude 合作
在 `.env` 中设置 `ANTHROPIC_API_KEY`。Claude 提供者在激活后会自动运行,无需代码更改。
```bash
# Director OS - 使用 Claude 的每周更新
curl -X POST http://127.0.0.1:8000/director-os/weekly-update \
-H "Content-Type: application/json" \
-d '{
"data_path": "data/local_only/projects",
"focus": "leadership update",
"use_model": true,
"provider": "claude"
}'
```
每个响应都包含一个 `trace` 对象,显示调用了哪些工具、检索了哪些数据以及包括缓存命中在内的令牌计数:
```json
{
"result": "...",
"trace": {
"mcp_tool_calls": [
{
"tool": "read_file",
"input": {"path": "projects/weekly-notes.md"},
"success": true,
"result_preview": "# Week of June 2026..."
}
],
"total_input_tokens": 842,
"cache_read_input_tokens": 680,
"total_output_tokens": 312
}
}
```
当密钥不存在时,自动回退到 Ollama / 确定性路径。
---
## MCP 入口点
两种 MCP 集成模式:
**进程内工具循环** - 当 `/orchestrate` 上的 `use_mcp=True` 时,LLM 会自主调用 `list_files`、`read_file` 和 `search_content` 工具。协调器执行每个调用,将结果附加到消息历史记录,并继续直到模型生成最终响应。无需预选证据 - 模型决定读取哪些内容。
**独立 MCP 服务器** - `apps/mcp/server.py` 将所有四个领域的工作流导出为 MCP 工具(`director_os.weekly_update`、`brand_os.content_draft`、`interview_os.brief`、`one_on_one_os.brief`),适用于 Claude Desktop 或 Claude Code。通过 `claude_desktop_config.json` 连接,所有四个工作流都作为工具调用提供,无需触摸 HTTP API。
| 工具 | 描述 |
|---|---|
| `list_files(path, pattern)` | 发现可用的项目笔记和文档 |
| `read_file(path)` | 检索综合使用的完整文件内容 |
| `search_content(path, query)` | 查找提及特定主题或风险的文档 |
---
## 评估结果
所有 22 个评估用例在本地(关键词)和语义(ChromaDB)检索路径上均通过所有四个领域。结果已提交 - 如果任何用例回归,CI 将失败。
| 领域 | 本地(关键词) | Chroma(语义) | Claude(实时) |
|---|---|---|---|
| Director OS | 7/7 | 7/7 | 4/4 |
| Brand OS | 7/7 | 7/7 | 7/7 |
| Interview OS | 4/4 | 4/4 | 4/4 |
| One-on-One OS | 4/4 | 4/4 | 4/4 |
| **总计** | **22/22** | **22/22** | **19/19** |
运行 ChromaDB 语义评估(需要本地 Ollama + `nomic-embed-text`):
```bash
python -m scripts.run_director_os_evals_chroma
python -m scripts.run_brand_os_evals_chroma
python -m scripts.run_interview_os_evals_chroma
python -m scripts.run_one_on_one_os_evals_chroma
```
运行 LangSmith 云备份评估(需要 `LANGSMITH_API_KEY`):
```bash
python scripts/run_director_os_evals.py --langsmith
```
---
## LangSmith 可观察性
当设置 `LANGSMITH_TRACING=true` 和 `LANGSMITH_API_KEY` 时,所有四个领域图都会将节点级跟踪信息发出到 LangSmith。每个 `graph.invoke()` 调用都使用 `get_langsmith_tracing_context()` 包装,并且每个图节点都带有 `@traceable` 装饰器 - 在每个步骤上具有完整的输入/输出可见性,无需额外的仪表代码。

当环境变量不存在时,跟踪是静默的无操作。零代码路径分支取决于是否启用跟踪。
```bash
# .env
LANGSMITH_TRACING=true
LANGSMITH_API_KEY=<your key>
```
---
## 模型提供者策略
| 层 | 模型 | 工作负载 |
|---|---|---|
| 本地推理 | Ollama (`llama3.2`) | 路由、分类、低风险总结 - 免费、设备上、无 API 密钥 |
| 云综合 | Claude Haiku | 通过工具使用、MCP 协调的结构化输出 - 经济高效 |
| 高级综合 | Claude Sonnet / Opus | 复杂或高风险运行 - 按需 |
所有提供者都实现相同的接口。切换提供者是请求上的单个字段更改 - 不需要更改工作流逻辑。
```bash
# Ollama - 不需要 API 密钥
curl -X POST http://127.0.0.1:8000/director-os/weekly-update \
-H "Content-Type: application/json" \
-d '{
"data_path": "data/local_only/projects",
"use_model": true,
"provider": "ollama",
"ollama_model": "llama3.2"
}'
```
---
## 技术栈
| 层 | 工具 |
|---|---|
| 语言 | Python 3.11+ |
| API | FastAPI + Pydantic |
| 工作流编排 | LangGraph |
| LLM 综合(云) | Claude - 工具使用、提示缓存 |
| LLM 推理(本地) | Ollama (`llama3.2`, `nomic-embed-text`) |
| 进程内 MCP 循环 | `packages/shared/mcp/` |
| 独立 MCP 服务器 | `apps/mcp/server.py` |
| 语义检索 | ChromaDB + `nomic-embed-text` 嵌入 |
| 可观察性 | LangSmith - `@traceable` 在所有 4 个领域图上,节点级跟踪 |
| 评估 | 每个领域的测试套件 - 关键词、语义和云路径;结果已提交 |
| CI/CD | GitHub Actions - 每个 PR 上的 lint、测试、评估;无需 API 密钥 |
参见 [SHOWCASE.md](SHOWCASE.md) 以获取每个工具的使用方式、功能和集成位置的完整映射。
---
## 为什么存在
技术领导者跨多个碎片化系统运营 - 笔记、路线图文档、会议准备、招聘渠道 - 并且每周花费大量时间将这些信息综合成结构化的输出,供利益相关者使用。AI-OS 自动化了这种综合,同时保持每个输出可追溯到源头。
它也是一个设计产物:生产 AI 属于企业工作流的参考实现。提供者抽象在模型交换时仍然存在。MCP 工具集成采用两种模式。评估框架测试失败模式,而不仅仅是成功路径。可观察性随系统一起提供。部署模式在面对现实 InfoSec 要求时仍然存在。架构设计为可适应 - 每个层都可以独立更换,以适应企业 AI 部署所需的环境定制。