TeamMemory
Team experience database - let AI accumulate, retrieve and apply team knowledge across chats.
Open source Open in the app JSON README (API)
About
Team experience database - let AI accumulate, retrieve and apply team knowledge across chats.
Details
- Kind
- MCP servers
- Topic
- Databases
- Publisher
- ysydhc
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 0.1.2
- Stars
- 1
- Last push
- 2026-06-18T09:05:21Z
- Repository state
- ativo
- Language
- Python
- License
- MIT
- Added
- 2026-08-29 04:01:42
- Updated
- 2026-08-29 04:01:42
- Origin id
io.github.ysydhc/team-memory
README
# TeamMemory
mcp-name: io.github.ysydhc/team-memory
**让 AI 拥有团队记忆** — 跨会话积累经验,像资深成员一样理解你的项目。
> 这是我学 AI 时萌生的一个想法。市面上已有类似产品,但总觉得不太贴合自己的使用习惯。做这个项目,既想通过和 AI 一起写代码来加深对大模型的理解,也希望能按自己的工作流,打磨出真正顺手的功能。
**给 Agent / 贡献者**:[AGENTS.md](AGENTS.md) · [docs/README.md](docs/README.md) · MCP 实现 [src/team_memory/server.py](src/team_memory/server.py) · 分层约束见 `scripts/harness_import_check.py`(`LAYER_MAP`)
## 为什么需要 TeamMemory?
用 Cursor、Claude 等 AI 助手写代码时,往往会遇到三个问题:
| 盲区 | 现象 |
| ------------- | ------------------------------------------------- |
| **无记忆** | 上周刚帮你修过的 Bug,这周遇到类似的,它完全不记得 |
| **只见代码,不懂决策** | 能看懂「是什么」,却不知道「为什么这么写」「上次踩过什么坑」 |
| **静态知识不够用** | Rules、Skills 管得了规范,管不住每天冒出来的隐性经验(接口坑、故障根因、被否掉的方案) |
**TeamMemory 就是冲着这三个问题来的。** 通过 MCP 把语义可搜索的经验库接进 AI:遇到问题自动查历史方案,解决后自动提炼并存下来,下次谁遇到同类问题,直接就能命中。既适合 3–10 人的技术团队共享,也适合部署在本地个人使用,配合 Cursor / Claude Desktop。
## 快速开始(4 条命令 + 1 项配置)
**环境**:Docker Desktop、Python 3.11+、Make
```bash
# 1. 初始化(Docker + 依赖 + 数据库)
make setup
# 2. 设置 API Key(唯一必改项;与 Web 签发的原始密钥同为 64 位十六进制,见 docs/decision/auth-api-key-design.md)
export TEAM_MEMORY_API_KEY=$(openssl rand -hex 32)
echo "API Key: $TEAM_MEMORY_API_KEY"
# 3. 拉取 Embedding 模型(仅首次需要)
ollama pull qwen3-embedding:0.6b
# 4. 启动
make web
```
浏览器访问 [http://localhost:9111](http://localhost:9111) ,用上面的 API Key 登录即可。更完整的部署与用户流程见下文 [按角色导航](#按角色导航) 与 [快速开始](#快速开始)。
## CLI 工具 / CLI Tools
除 MCP 外,所有 `memory_*` 工具也可通过 `tm-cli` 命令行调用:
```bash
# 搜索团队知识 / Search team knowledge
tm-cli recall --query "如何配置"
# 保存经验 / Save experience
tm-cli save --title "Bug fix" --problem "连接超时" --solution "增加重试"
# 获取上下文 / Get context
tm-cli context --file-paths "src/server.py"
# 查看所有命令 / Show all commands
tm-cli --help
```
### 配置命令 / Configuration Commands
```bash
# 显示当前生效配置及值来源 / Show effective config with source annotations
tm-cli config show
# 交互式生成 ~/.config/tm/config.toml / Interactive config init
tm-cli config init
# 一键配置平台 Hook / One-command hook setup
tm-cli setup --platform claude-code
tm-cli setup --platform cursor
tm-cli setup --platform hermes
tm-cli setup --platform all
# 仅检查当前状态 / Check status only
tm-cli setup --platform all --check
```
前提:`make dev` 启动服务 + `TEAM_MEMORY_API_KEY` 环境变量已设置(或已在 `~/.config/tm/config.toml` 中配置)。
## MCP 接入(Cursor / Claude)
**本仓库(克隆源码)推荐**:不要把 API Key 写进 mcp.json。在仓库根维护 `**.env`**(从 [example/env.team-memory.example](example/env.team-memory.example) 复制),其中至少设置 `**TEAM_MEMORY_API_KEY**`;MCP 配置为 `**bash**` + `**scripts/run_mcp_with_dotenv.sh**` + `**cwd`= 仓库根**。详见 [docs/guide/mcp-server.md](docs/guide/mcp-server.md)。**Cursor** 一般用 `.cursor/mcp.json`,**Claude Code** 可用根目录 `.mcp.json`,两处内容建议保持一致。
**项目名零配置**:在项目根放置 `.tm.toml`(见 [配置说明](#配置说明-configuration)),或系统自动从 git 仓库名推断,无需传 `--project` 或设 `TEAM_MEMORY_PROJECT`。
**仅 `pip install team_memory`、无本地仓库目录**时,可在 `.cursor/mcp.json` 里用本机 Python 与环境变量(数据库与 Key 仍需提供):
```json
{
"mcpServers": {
"team_memory": {
"command": "python3",
"args": ["-m", "team_memory.server"],
"env": {
"TEAM_MEMORY_DB_URL": "postgresql+asyncpg://developer:devpass@localhost:5433/team_memory",
"TEAM_MEMORY_API_KEY": "你的 API Key"
}
}
}
}
```
也可使用客户端配置 `~/.config/tm/config.toml`(`tm-cli config init` 生成),避免在 JSON 中写入密钥。
(MCP 未注册 **Resources / Prompts**;`**memory_`* 七工具**:`memory_save`、`memory_recall`、`memory_context`、`memory_get_archive`、`memory_archive_upsert`、`memory_feedback`、`memory_submit_response`。详情见下文 [MCP 工具列表(当前)](#mcp-工具列表当前) 与 [docs/guide/mcp-server.md](docs/guide/mcp-server.md)。)
本机直连数据库时需要配 `TEAM_MEMORY_DB_URL`(或通过 config);从源码跑且项目里已有 config 的,可不单独设 DB_URL。
## 架构可视化(现状)
Web 内「架构」导航与 `/api/v1/architecture/`* **已移除**(实现见 `src/team_memory/web/static/js/pages.js`)。若需要代码库图谱,请在本机单独使用 **GitNexus**(CLI / Bridge 等),与当前 TM Web **无集成**。
---
## 按角色导航
| 角色 | 目标 | 入口 |
| --------- | ------------------- | --------------------------------------------- |
| **初次部署者** | 跑起 Web、拿到 API Key | [快速开始 → 一、初次部署者](#一初次部署者一键部署) |
| **初级使用者** | 在 Cursor/Claude 里接入 | [快速开始 → 二、初级使用者](#二初级使用者在-cursor--claude-里接入) |
| **贡献者** | 改代码、提 PR | [开发](#开发) |
## 目录
- [功能概览](#功能概览) · [快速开始](#快速开始) · [CLI 工具](#cli-工具) · [MCP 接入](#mcp-接入指南配置参考) · [Web 管理](#web-管理界面) · [配置](#配置说明) · [运维](#运维) · [FAQ](#faq) · [开发](#开发)
**安装与获取**
- **PyPI**:`pip install team_memory`(推荐用于部署或本地 MCP 客户端)。
- **MCP 官方注册表**:在 [MCP Registry](https://registry.modelcontextprotocol.io) 或 Cursor / Claude Desktop 的 MCP 市场中搜索「TeamMemory」或「team-memory」,可一键发现并安装(安装后仍需配置数据库连接与 API Key,见下文)。
## TeamMemory 在 AI 知识体系中的位置
AI 助手在项目中可用的知识分为三层,每一层解决不同的问题:
```
┌─────────────────────────────────────────────────────────┐
│ Rules / Skills(静态层) │
│ 已确定的规范和成熟的工作流,手动维护,变化频率低 │
│ 例:代码风格规范、部署流程、API 用法 │
├─────────────────────────────────────────────────────────┤
│ TeamMemory(动态层) ← 本项目 │
│ 从日常开发中自动积累的团队经验,语义可搜索,持续演化 │
│ 例:Bug 根因分析、架构决策背景、接口的隐藏坑 │
├─────────────────────────────────────────────────────────┤
│ 代码 + 文档(基础层) │
│ 项目源码和文档,AI 可直接读取 │
│ 例:函数定义、README、注释 │
└─────────────────────────────────────────────────────────┘
```
三层之间存在自然的知识生命周期:
```
日常开发会话
│
▼
AI 自动提取经验 ──→ TeamMemory(动态积累)
│ │
│ ▼ 模式稳定后
│ 固化为 Rules / Skills
│ │
└──── 新问题 / 新变化 ←─┘
```
**Rules/Skills 无法覆盖的知识,正是 TeamMemory 的价值所在**:那些太碎、太多、变化太快,不适合写成规则,但恰恰是团队"老手"和"新手"之间最大差距的经验。
## 术语表
| 术语 | 说明 |
| ------------- | ------------------------------------------------------------------- |
| **经验** | 单条问题-方案对,可被检索和复用 |
| **经验库** | 经验的集合 |
| **scope** | 作用域:global(全局)、team(团队)、personal(个人) |
| **Embedding** | 向量嵌入,用于语义搜索;配置项为 `embedding` |
| **MCP** | Model Context Protocol,让 AI 客户端调用 `memory_recall`、`memory_save` 等工具 |
## 功能概览
### 自动学习
AI 从对话和文档中自动提取结构化经验,无需手动录入:
- **对话提取**:通过 MCP `**memory_save(content=...)`** 走 LLM 解析,从长对话中识别问题、方案、标签并写入(含质量门控);**Web** 上亦支持粘贴文档或 URL 解析
- **文档解析**:上传文档或输入 URL,AI 自动解析为标题、问题描述、解决方案、标签
- **经验组**:保存时可选 `**group_key`**(MCP / HTTP)将相关经验归组;复杂编排可在 Web 完成
- **默认草稿模式**:AI 提取的内容默认为草稿,经人工审核后发布,保证质量
### 智能检索
多层检索管线,确保 AI 找到最相关的历史方案:
- **语义搜索**:基于向量嵌入(Ollama / OpenAI / 本地模型),理解查询意图
- **混合检索**:向量搜索 + 全文检索 + RRF 融合排序
- **查询优化**:同义词扩展(`config.tag_synonyms`)、短查询自动降低 min_similarity(0.45);FTS 使用 simple 分词器 + jieba 中文分词 + **hybrid AND/OR 策略**(前 2 词 AND 保证精度,其余 OR 提升召回)
- **Reranker**:支持服务端 LLM 精排,或客户端 AI 自行判断结果相关性
- **Token 预算控制**:自动裁剪输出长度,避免经验库增大后撑爆 AI 上下文
- **记忆压缩与摘要**:经验支持 `summary` 字段,LLM 可生成简短摘要;单条(POST `/experiences/{id}/summarize`)与批量(POST `/experiences/batch-summarize`)生成;MCP 搜索结果中每条经验可包含 `summary`,便于节省 Token
- **PageIndex-Lite**:长文档自动分块建立节点索引,支持节点级精准检索
- **个人扩写**:per-user tag_synonyms 在检索前生效(词表替换 + LLM 扩写),MCP 搜索返回后自动维护;Web 设置 → 个人扩写
- **个人记忆 / 用户画像**:按 `user_id` 隔离;**Lite** 下由 `**memory_save(..., content=...)`** 解析等路径可写入;`**memory_context**` 返回 `profile.static` / `profile.dynamic`(字符串列表)。Web **设置 → 用户画像** 可分组查看、过滤 **static/dynamic** 并 **删除** 错误条目(还可调 HTTP API `profile_kind`)。
- **文件位置绑定**:保存经验时可传 `file_locations`(路径 + 行范围,可选 snippet/file_mtime/file_content_hash);检索时可传 `current_file_locations`,与当前编辑位置匹配的经验会获得 location 加分,详见 [src/team_memory/server.py](src/team_memory/server.py) 工具参数与 [docs/guide/mcp-server.md](docs/guide/mcp-server.md)。
### 三层作用域
- **global**:全局共享知识
- **team**:团队/项目级经验
- **personal**:个人笔记与草稿
### 经验类型自动分类
保存时可根据内容自动推荐经验类型(general/feature/bugfix/tech_design/incident/best_practice/learning),减少手动选择。
### 经验质量打分系统
自动评估经验的活跃度和价值,让高质量经验脱颖而出:
- **阶梯衰减**:新经验 100 分起步,10 天保护期后未被引用每天 -1 分(低于 50 分后 -0.5/天)
- **引用加分**:每次被检索命中(含 `memory_recall` / Web 搜索管线)+2 分,获 4 星以上评价 +1 分
- **质量等级**:Gold (≥120) / Silver (≥60) / Bronze (≥20) / Outdated (≤0)
- **置顶免衰**:手动置顶的经验永不衰减(年度发布流程等长期有效经验)
- **Outdated 管理**:分值归零的经验仍可搜索到,但在管理面板提示处理(恢复/删除/置顶)
- **规则可配**:初始分值、衰减速率、加分幅度、等级阈值均可在设置页调整
### 结构化管理
不是随意堆放的笔记,而是有类型、有层级、有评分的经验体系:
- **7 种经验类型**:通用、需求、Bug、技术方案、故障、最佳实践、学习笔记,每种类型有专属结构化字段
- **父子层级存储**:支持将相关经验组织为经验组(如:一个需求从评审到上线的全过程)
- **完整度评分**:0-100 分自动评分,鼓励团队逐步完善经验
- **生命周期管理**:草稿 → 审核 → 发布 → 过期检测 → 去重合并
### 团队协作
多人共建共享的团队知识库:
- **RBAC 权限**:admin / editor / viewer 三级角色
- **反馈评分**:1-5 星评分影响搜索排序,低分经验自动降权
- **版本历史**:就地编辑 + 版本快照,支持回滚
- **去重检测**:保存前自动检测相似经验,避免重复录入
- **合并建议**:设置页标记建议合并的相似经验对,三栏 Git-Conflict 风格 diff 对比 + 合并预览
- **多项目隔离**:通过 `project` 参数隔离不同项目的经验,避免跨项目污染
### 无缝集成
原生 MCP 协议支持,AI 助手通过 stdio 接入:
- **MCP 工具(7 个)**:`memory_context`、`memory_recall`、`memory_get_archive`、`memory_archive_upsert`、`memory_save`、`memory_feedback`、`memory_submit_response`(见 [MCP 工具列表](#mcp-工具列表当前))
- **当前 MCP 未注册** Resources / Prompts;补齐体验以 Web、`/docs` HTTP API 为准
- **Web 管理界面**:浏览、搜索、审核、档案馆、配置等
旧文若仍写 `**tm_*`** MCP 或任务看板等已下线能力,以 **本文**、[AGENTS.md](AGENTS.md) 与 [src/team_memory/server.py](src/team_memory/server.py) 为准。
### TM Daemon(自动采集与精炼)
后台守护进程,自动从 Obsidian vault 和 Agent 对话中采集经验:
- **Obsidian Watcher**:监听 vault 文件变更,自动创建 draft(同文件去重,更新而非重复创建)
- **RefinementWorker**:每 30 秒扫描 pending draft,调用 LLM(GLM-5-Turbo)提取结构化字段(title/problem/solution/tags),自动发布
- **学习卡片跳过**:识别学习类内容(卡片-、主题-、Layer 等),直接发布不走 LLM 抽取
- **入口命令**:`tm-daemon`(即 `python -m team_memory.daemon`),`make daemon-start` / `make daemon-stop`(launchd 托管),日志 `/tmp/tm-daemon.log`
- **代码位置**:`src/team_memory/daemon/`(原 `scripts/daemon/`)
### Faithfulness 评估系统
基于 RAGAS 思路,用 LLM Judge 评估搜索结果是否被 Agent 真实使用:
- **自动捕获**:Daemon 的 after_response hook 自动缓存 (query, response, result_ids) 到 response_buffer
- **批量评估**:buffer 积累到阈值(默认 5 条)后自动触发 LLM Judge(glm-4-flash)
- **评估逻辑**:拆解 Agent 回复为 claims → 逐条检查是否能从检索结果推断 → 输出 faithfulness score
- **结果回流**:score ≥ 0.5 自动标记 search_log 为 was_used,影响 use_rate 统计
- **查看方式**:`make stats`(Faithfulness 面板)、`make faithfulness-eval --show 10`、`curl localhost:3901/status/faithfulness`
- **模型可配**:`--model glm-4-flash --base-url http://localhost:4000/v1`
### Wiki 编译与实体关系
从经验库自动编译知识 Wiki:
- **实体提取**:LLM 从经验中提取工具、概念、人物等实体(L2.5 层)
- **关系发现**:建立实体间的 uses/depends/conflicts 关系
- **主题发现**:自动聚类经验为主题,LLM 生成主题名
- **矛盾检测**:规则 + LLM 双重验证,发现相互矛盾的经验对
- **命令**:`make wiki-compile`、`make entity-backfill`、`make detect-contradictions`
### 一键部署
最小化上手成本:
- `make setup` 一键完成全部安装
- 最小配置模板只需改 2 项即可启动
- Docker Compose 自动拉取所需模型
- 统一端口 9111,健康检查一键诊断
## 快速开始
以下从**初次部署者**(把 TeamMemory 跑起来的人)和**初级使用者**(在 Cursor/Claude 里连上已有服务的人)两种角色,按最小步骤说明。
### 前提条件
| 依赖 | 确认方式 |
| -------------- | ------------------------------------------- |
| Docker Desktop | `docker --version` |
| Python 3.11+ | `python3 --version` |
| Make | `make --version`(macOS/Linux 一般自带) |
| Ollama | `ollama --version`(首次 `make web` 前拉取模型用,见下) |
### 一、初次部署者:一键部署
你是第一次在团队里部署,目标是:跑起 Web、拿到 API Key、并交给同事用。
**1. 一键初始化**
克隆仓库后,在项目根目录执行:
```bash
make setup
```
会完成:启动 Docker(PostgreSQL+pgvector、Ollama、Redis)、安装 Python 依赖、执行数据库迁移。成功时输出 `✔ Setup complete!`。常见失败原因:Docker 未启动、5432/11434 端口被占用、pip 安装失败。
**2. 改配置**
默认使用仓库根目录 `config.development.yaml`。确认 `database.url` 与本地 Postgres 一致;`auth.api_key` 建议用环境变量注入:
设置环境变量作为管理员引导密钥(首次部署必须;**勿提交 Git、勿明文写入配置文件**):
```bash
export TEAM_MEMORY_API_KEY=$(openssl rand -hex 32)
echo "你的管理员 API Key: $TEAM_MEMORY_API_KEY"
```
**首次登录**
- 打开 [http://localhost:9111](http://localhost:9111)
- 点击「使用 API Key 登录」
- 将上面的 TEAM_MEMORY_API_KEY 粘贴到输入框,点击「登录」
- 登录成功后即为 admin,右上角显示当前用户名
该 Key 仅在内存中生效(与 config 中的 auth.api_key 一样),重启服务后仍使用同一环境变量即可再次用该 Key 登录。若希望用「用户名 + 密码」登录并长期使用,见下文「可选:为自己创建持久 Admin 账户」。
### 方式二:配置文件
在 `config.development.yaml`(或 `TEAM_MEMORY_CONFIG_PATH` 指向的文件)中设置:
```
auth:
type: db_api_key
api_key: "${TEAM_MEMORY_API_KEY}" # 从环境变量读取
user: admin
```
或直接写明文(仅限本地/测试,勿提交到 Git;**生产环境禁止**):
```
auth:
type: db_api_key
api_key: "你的 API Key"
user: admin
```
启动服务后,用该 api_key 在 Web 登录页选择「使用 API Key 登录」即可获得 admin。
### 可选:为自己创建持久 Admin 账户
若希望用「用户名 + 密码」登录、且不依赖引导 Key:
1. 已用引导 Key 以 admin 身份登录 Web。
2. 进入 设置 → 用户管理,点击「添加用户」。
3. 填写:
- 用户名:如 admin 或你的英文名
- 角色:admin
- 初始密码:设置一个强密码(用于 Web 登录)
4. 点击「创建」。系统会生成并展示一条 API Key(用于 MCP 客户端),请复制保存。
5. 之后可:
- Web:用刚设置的用户名 + 密码登录。
- MCP:在 Cursor/Claude 的 mcp.json 中使用刚生成的 API Key 作为 TEAM_MEMORY_API_KEY。
引导 Key(环境变量或 config 中的 key)与数据库中的用户彼此独立:引导 Key 仅用于首次拿到 admin 权限;后续日常可使用数据库里的 admin 账号(用户名+密码 + 自己的 API Key)。
若使用默认 Docker 数据库,`database.url` 无需改;否则改为你的 PostgreSQL 连接串。
**3. 拉取 Embedding 模型(仅首次)**
`make setup` 会启动 Ollama 容器,首次 `make web` 前需执行:
```bash
ollama pull qwen3-embedding:0.6b
```
**4. 启动 Web**
```bash
make web
```
浏览器打开 **[http://localhost:9111](http://localhost:9111)**。
**首次登录**:切换到「使用 API Key 登录」,输入上一步的 `TEAM_MEMORY_API_KEY`,即以 admin 身份进入。
**多人使用**:
- 团队成员在登录页点击「注册」,填写用户名和密码
- Admin 在「设置 > 用户管理」中审批注册申请,系统自动生成 API Key
- Admin 将 API Key 分发给成员,用于 MCP 客户端(Cursor/Claude Desktop)接入
- 成员后续 Web 登录使用用户名 + 密码,MCP 使用 API Key
**5. 可选:健康检查**
```bash
make health
```
成功时输出 `PostgreSQL: OK`、`Ollama: OK`、`Web: healthy` 等。若 `database` 或 `ollama` 为 FAIL,按提示启动对应服务或执行迁移。
**首次访问 Web 时可能显示 0 条经验,属正常。** 可先添加一条测试经验验证流程。
日常再次启动只需:`make dev`(或先 `docker compose up -d` 再 `make web`)。更多命令见下方「运维」。
---
### 二、初级使用者:在 Cursor / Claude 里接入
你已经从部署者拿到 **API Key**,TeamMemory 的数据库(和 Web)已就绪。只需在本机配置 MCP 并验证。
**1. 安装(本机跑 MCP 时)**
```bash
pip install team_memory
```
若通过 Cursor/Claude 的「MCP 市场」安装 TeamMemory,按客户端说明即可,可能无需本机再装。
**2. 拿到 API Key 与数据库连接**
- 向部署者索取 **TEAM_MEMORY_API_KEY**。
- 若你**本机直连**团队 PostgreSQL(即 MCP 进程自己连库),还需 **TEAM_MEMORY_DB_URL**(如 `postgresql+asyncpg://用户:密码@主机:5432/team_memory`)。若你使用「从源码运行」且项目目录下已有正确配置,可不设 DB_URL,由 config 提供。
- 或运行 `tm-cli config init` 交互式生成 `~/.config/tm/config.toml`,后续无需再设环境变量。
**3. 配置 MCP**
在 **Cursor** 中编辑项目或用户下的 `.cursor/mcp.json`;在 **Claude Desktop** 中编辑 MCP Servers 对应配置。MCP 的当前用户由 **TEAM_MEMORY_API_KEY** 解析(与 Web 同账号即同一人);`TEAM_MEMORY_USER` 仅在不设 Key 或解析失败时作为回退,可选。
- **从源码运行本仓库**(推荐:`TEAM_MEMORY_`* 进 `.env`,密钥不进 JSON):将 [example/env.team-memory.example](example/env.team-memory.example) 复制为仓库根 `.env` 并填写;执行 `chmod +x scripts/run_mcp_with_dotenv.sh`;把 [example/cursor-mcp-team-memory.example.json](example/cursor-mcp-team-memory.example.json) 里的绝对路径换成你的目录后写入 `.cursor/mcp.json` / `.mcp.json`:
```json
{
"mcpServers": {
"team_memory": {
"command": "bash",
"args": ["/ABSOLUTE/PATH/TO/team_doc/scripts/run_mcp_with_dotenv.sh"],
"cwd": "/ABSOLUTE/PATH/TO/team_doc"
}
}
}
```
- **从 pip 安装、无项目目录**:用本机 Python + `env` 块(无需 `cwd`):
```json
{
"mcpServers": {
"team_memory": {
"command": "python3",
"args": ["-m", "team_memory.server"],
"env": {
"TEAM_MEMORY_DB_URL": "postgresql+asyncpg://用户:密码@主机:5432/team_memory",
"TEAM_MEMORY_API_KEY": "你的 API Key"
}
}
}
}
```
- **备选(不建议提交到 Git)**:仍可在 mcp.json 的 `env` 里写 `TEAM_MEMORY_API_KEY` / `TEAM_MEMORY_PROJECT`;多仓库时更易分叉泄露,优先用 `.env` + 包装脚本。
**4. 验证**
重启 Cursor 或 Claude Desktop,在对话里请 Agent 使用 `**memory_recall`**(或 `**memory_context**`)搜索与 Docker 相关的经验。若配置正确,会返回 JSON 结果。约定见 [mcp-lite-default.md](docs/decision/mcp-lite-default.md)。
---
### 其他安装方式
- **仅 Docker、不克隆源码**:若你只想跑 Web 不跑本地 MCP,可用 `docker compose up -d` 启动(含数据库迁移)。在 `.env` 中设置 `TEAM_MEMORY_API_KEY`(默认 `changeme` 请修改)。**生产环境必须修改默认 Key,禁止使用 changeme**。访问 [http://localhost:9111](http://localhost:9111) 。
- **从 PyPI 部署、无 Make**:`pip install team_memory` 后,需自备 PostgreSQL(pgvector)并在项目根目录执行 `alembic upgrade head`,再通过 `TEAM_MEMORY_CONFIG_PATH` 或 `TEAM_MEMORY_DB_URL` 启动 `team-memory-web` 或 `**team-memory`**(MCP)。入口命令:`team-memory-web`(Web)、`team-memory`(MCP)、`tm-cli`(CLI)、`tm-daemon`(Daemon)。
---
## MCP 接入指南(配置参考)
**克隆本仓库时**:优先 `**.env` + [scripts/run_mcp_with_dotenv.sh](scripts/run_mcp_with_dotenv.sh)**,`mcp.json` 不写密钥;完整步骤见 [docs/guide/mcp-server.md](docs/guide/mcp-server.md)。
**Cursor**(`.cursor/mcp.json`)— 从 pip 安装、无项目目录:
```json
{
"mcpServers": {
"team_memory": {
"command": "python3",
"args": ["-m", "team_memory.server"],
"env": {
"TEAM_MEMORY_DB_URL": "postgresql+asyncpg://用户:密码@主机:5432/team_memory",
"TEAM_MEMORY_API_KEY": "你的 API Key"
}
}
}
}
```
**从源码目录运行且不用包装脚本时**(备选):将 `command` 指向项目 `.venv/bin/python`,设 `"cwd"` 为仓库根,`env` 中提供 `TEAM_MEMORY_API_KEY` 等(数据库可由项目内 config 提供)。
**Claude Desktop**:在 MCP 设置中添加同名 `team_memory` 条目;源码场景推荐与上文相同的 `bash` + `run_mcp_with_dotenv.sh`,pip 场景与上一致即可。
| 变量 | 必填 | 说明 |
| ------------------------- | --------------- | ------------------------------------------------------------------------------- |
| `TEAM_MEMORY_DB_URL` | 是(或由 config 提供) | PostgreSQL 连接串,`postgresql+asyncpg://...`,库需启用 pgvector |
| `TEAM_MEMORY_API_KEY` | 推荐 | 与 Web 同账号的 API Key;MCP 据此解析为当前用户,与 Web 身份统一 |
| `TEAM_MEMORY_USER` | 否 | 项目级 mcp.json 中配置:写入经验的归属用户(你的 Web 账号),避免「不知谁写入」;不设 API Key 时也作回退,默认 `anonymous` |
| `TEAM_MEMORY_PROJECT` | 否 | 项目级 mcp.json 中配置:写入经验的归属项目名;不设则用服务端 default_project |
| `TEAM_MEMORY_CONFIG_PATH` | 否 | 配置文件路径,设置则优先从该文件加载 |
**MCP 身份与 Web 统一**:MCP 的当前用户(current_user)优先由 **TEAM_MEMORY_API_KEY** 经服务端 AuthProvider 解析得到,与 Web 使用同一套用户体系。配置与 Web 同账号的 API Key 后,在 Cursor 里写入的 personal 经验在同一 Cursor 会话内可被检索到,且 Web 用该账号登录后也能看到。推荐只配置 `TEAM_MEMORY_API_KEY`(与 Web 同账号的 Key),无需再设 `TEAM_MEMORY_USER`。
**项目级归属(用户 / 项目名)**:推荐使用 `**.tm.toml`** 声明项目名(见 [配置说明 / Project Config](#项目级配置--project-config)),系统也会自动从 git 仓库名推断——大多数情况下无需手动配置。若需显式指定,可在仓库根 `**.env**` 中设置 **TEAM_MEMORY_PROJECT**(及按需 **TEAM_MEMORY_USER**),与包装脚本一起使用。解析顺序:`.tm.toml` > `**TEAM_MEMORY_PROJECT`** > git 仓库名 > 目录名 > 配置 default。
**Docker/Helm**:若通过容器或编排部署,在配置中注入上述环境变量;生产环境禁止使用占位或默认 Key(如 `changeme`)。
**回滚说明**:MCP 身份解析逻辑无 DB 变更。若需回滚,仅还原 `src/team_memory/server.py` 中相关改动,并通知用户恢复依赖 `TEAM_MEMORY_USER` 的配置即可。
### 实际场景:AI 如何使用 TeamMemory
**场景 1:遇到问题,AI 先查团队经验**
```
你:这个 Docker 容器的网络一直不通,帮我看看
AI 的推荐行为:
1. 调用 memory_recall(problem="Docker 容器网络不通", framework="docker")
2. 命中团队经验:「上次是 bridge 网络 DNS 解析问题,需要指定 --dns」
3. 基于命中结果给出步骤,并在合适时 memory_save 沉淀新结论
```
**场景 2:问题解决后保存**
```
排查结束后,可由 AI 调用 memory_save(title=..., problem=..., solution=...)
或 memory_save(content="…长对话…") 走解析后写入(常为草稿,视服务配置而定)。
```
**场景 3:打开文件时带一点上下文**
```
AI 可调用 memory_recall(file_path="k8s/deployment.yaml", framework="kubernetes")
按路径/框架取相关经验(等价于旧文档中的「suggest」类用法)。
```
### MCP 工具列表(当前)
| 工具 | 功能 | 输入要点 |
| ------------------------ | -------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `memory_context` | 任务开始拉上下文 + 用户画像摘要 + 相关经验 | `file_paths` 等(以工具 schema 为准) |
| `memory_recall` | 统一检索:problem / query / file_path 等 | 至少提供其一;可选 `include_archives`、`include_user_profile` |
| `memory_get_archive` | 档案 L2 全文 | `archive_id`(通常在 recall 命中 `type=archive` 后调用) |
| `memory_archive_upsert` | 创建/更新档案馆(与 `POST /api/v1/archives` 一致) | `title`、`solution_doc` 等;大文件见 [mcp-server 档案馆流程](docs/guide/mcp-server.md)(HTTP / `tm-cli upload`) |
| `memory_save` | 保存或长文解析保存 | `title`+`problem` 或 `content`;**勿**使用已移除的 `scope=archive` |
| `memory_feedback` | 对结果评分 | `experience_id`、`rating` 等 |
| `memory_submit_response` | 提交回复用于 Faithfulness 评估 | `query`、`response`、`result_ids`(可选) |
更多管理员操作(审核、去重、配置)请用 **Web** 或 `**GET/POST /api/v1/...`**(见 `/docs`)。历史 `**tm_***` 已不在 MCP 中暴露。
## Web 管理界面
启动 Web 服务后访问 `http://localhost:9111`,提供经验的可视化管理:
| 页面 | 功能 |
| ------------ | ------------------------------------ |
| 经验列表(含仪表盘统计) | 经验总量、近期趋势、热门标签、类型分布;按类型/标签/项目/进度多维筛选 |
| 草稿箱 | 查看 AI 自动提取的待审核草稿 |
| 审核队列 | 审核团队成员提交的经验 |
| 去重检测 | 发现和合并相似经验 |
| 系统设置 | 检索参数、搜索配置等 |
档案馆、去重、个人记忆等以当前 Web 导航与 OpenAPI 为准。
创建经验支持三种模式:
- **手动填写**:逐字段填写标题、问题、方案
- **文档解析**:粘贴文档或 Markdown,AI 自动提取字段
- **URL 导入**:输入链接,AI 自动抓取并解析内容
API 参考(前缀 `/api/v1`):
- **Swagger UI**: `http://localhost:9111/docs`
- **ReDoc**: `http://localhost:9111/redoc`
## 配置说明 / Configuration
TeamMemory 的配置分为两层:**服务端配置**(部署者)和**客户端配置**(使用者),优先级从高到低为:
```
环境变量 > .env 文件 > config.toml > 代码默认值
env vars > .env file > config.toml > code defaults
```
### 客户端配置(使用者) / Client Config
统一配置文件:`**~/.config/tm/config.toml**`,CLI、MCP、Daemon、Hooks 所有客户端组件共用。
可通过 `tm-cli config init` 交互式生成,或手动创建:
```toml
# ~/.config/tm/config.toml — 统一客户端配置 / Unified client config
[server]
url = "http://localhost:9111" # TM Web 服务地址 / Web server URL
api_key = "" # 或由 TEAM_MEMORY_API_KEY 环境变量提供
[llm]
base_url = "http://localhost:4000/v1" # LLM API 地址(用于 Faithfulness 评估等)
model = "DeepSeek-V3" # LLM 模型名
api_key_env = "LITELLM_MASTER_KEY" # LLM API Key 的环境变量名(推荐)
timeout = 30 # 请求超时(秒)
[conversation]
db_path = "~/.cache/tm-pipeline/drafts.db" # 本地对话缓存路径
[wiki]
enabled = false
db_path = "~/.cache/tm-pipeline/wiki.db"
[daemon]
host = "127.0.0.1"
port = 3901
log_level = "INFO"
```
**优先级 / Priority**:`TM_SERVER_URL` 环境变量 > `.env` 文件 > `config.toml` > 代码默认值。
**查看当前生效配置 / Show effective config**:
```bash
tm-cli config show # 显示每个字段的值及其来源
```
### 项目级配置 / Project Config
在项目根目录放置 `**.tm.toml**`,声明项目名与别名:
```toml
# .tm.toml — 项目级配置 / Project-level config
[project]
name = "team_doc" # 项目名(优先于 git repo 名 / 目录名)
aliases = ["team_memory"] # 别名:历史项目名映射到当前名
```
**项目名推断优先级 / Project name inference**:
1. `.tm.toml` 中 `[project].name` — 显式声明
2. Git 仓库名(basename → snake_case)— 覆盖 80%+ 场景
3. 目录名(basename → snake_case)— 兜底
**零配置**:大多数项目无需 `.tm.toml`,系统自动从 git 仓库名推断。有了 `.tm.toml` 后不再需要传 `--project` 参数。
### 服务端配置(部署者) / Server Config
仅保留**两个**环境配置文件(二选一,再结合环境变量覆盖):
| 文件 | 用途 |
| ------------------------- | ----------------------------------------------------------------------- |
| `config.development.yaml` | 本地 / 默认(`TEAM_MEMORY_ENV` 未设或 `development` / `test` / `dev` / `local`) |
| `config.production.yaml` | 正式 / 预发(`TEAM_MEMORY_ENV=production` 或 `prod`) |
| `TEAM_MEMORY_CONFIG_PATH` | 可选:指向任意单文件,则不再按环境名解析上述两个文件 |
| 环境变量 `TEAM_MEMORY_`* | 最高优先级,覆盖 YAML 中的同名字段 |
### 多环境配置(服务端) / Multi-Environment (Server)
```bash
# 开发(默认)
unset TEAM_MEMORY_ENV # 或 TEAM_MEMORY_ENV=development
# 正式
TEAM_MEMORY_ENV=production
```
### 认证类型
`auth.type` 可选:`db_api_key`(多用户、推荐)、`api_key`(内存单 key)、`none`(无认证,仅测试)。
### RBAC 角色权限
| 角色 | 权限 |
| ------ | -------------------- |
| admin | 全部操作(用户管理、配置修改、审计日志) |
| editor | 创建、编辑、删除、审核经验 |
| viewer | 只读(搜索、浏览、反馈) |
管理员通过 Web UI 设置页面管理 API Key 和角色分配。
### Embedding 配置 / Embedding Config
```yaml
embedding:
provider: ollama # ollama / openai / local / generic
ollama:
model: qwen3-embedding:0.6b
dimension: 1024
```
支持 Ollama(默认,本地运行,无需 API Key)、OpenAI API、本地 sentence-transformers 模型、generic 自定义端点。当前默认使用 `qwen3-embedding:0.6b`(1024 维),中文支持优秀。切换模型后需执行 `make embedding-backfill` 重新生成向量。
**Embedding 自动恢复 / Auto-recovery**:当 Ollama 重启后,Web 服务的 embedding 缓存可能失效。`/health` 健康检查会自动重试 embedding 初始化:检测到失败后从配置重新创建 provider,成功即替换缓存。无需手动重启 Web 服务。
## 运维
### 常用命令
```bash
# 基础
make setup # 首次安装(Docker + 依赖 + 数据库)
make dev # 启动全部服务
make web # 仅启动 Web(9111)
make health # 一键健康检查
make backup # 备份数据库 (PG + SQLite)
make clean # 清理 Python 缓存
# 测试
make test # 运行全部单元测试
make test-acceptance # 管道验收测试 (21 tests, Tier 2+3)
make test-regression # 完整回归 (acceptance + e2e + pipeline)
make test-llm # 测试 LLM 连通性
make e2e-verify # 端到端链路验证 (模拟 AI 对话)
# 代码质量
make lint # Ruff 代码检查
make lint-fix # Ruff 自动修复
make verify # 标准验收:import + lint + 全量测试
make verify-web # Web 验收:lint + web 测试 + smoke
# 搜索与质量
make stats # 搜索质量报告
make search-eval # 搜索质量评估 (precision/recall)
make faithfulness-eval # Faithfulness 批量评估 (RAGAS)
make verify-pipeline # 人工验证数据链路 (15项检查)
make diagnose-pipeline # 诊断数据链路详细状态
# Wiki
make wiki-compile # Wiki 编译
make wiki-status # Wiki 编译状态
make entity-backfill # 实体提取回填
make entity-dedup # 实体去重合并
make detect-contradictions # 矛盾经验检测
# 数据维护
make migrate # 数据库迁移
make migrate-fts # 补齐 FTS 字段
make embedding-backfill # 重新生成 embedding
make solution-backfill # 补跑无 solution 的经验
# Daemon
make daemon-start # 启动 Daemon (launchd)
make daemon-stop # 停止 Daemon
make daemon-run # 前台运行 Daemon (调试用)
make daemon-reload # 代码变更自动重启
make daemon-install # 安装 launchd plist (开机自启)
make daemon-uninstall # 卸载 launchd plist
# Watchdog
make watchdog-start # 启动 Watchdog (launchd)
make watchdog-stop # 停止 Watchdog
make watchdog-status # Watchdog 运行状态
# 运维工具
make logs # 查看/过滤 daemon 日志
make metrics-push # 推送指标到飞书
make hooks-install # 安装 Git hooks
```
### Make 命令说明(等价手动命令)
便于问题定位和手动分步启动时参考:
| 命令 | 含义 | 等价手动步骤 |
| ------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `make help` | 列出所有 make 目标 | `grep -E '^[a-zA-Z_-]+:.*?## ' Makefile | awk ...` |
| `make release-9111` | 释放 9111 端口 | 停掉占用 9111 的 Docker 容器(如 `team-memory-web`)和本机进程: `docker compose stop team-memory-web` `docker ps -q --filter "publish=9111" | xargs docker stop` `lsof -i :9111 -t | xargs kill -9` |
| `make setup` | 首次安装 | `docker compose up -d` → 等 PG 就绪 → 建库(若无)→ 按需启动 Ollama 容器 → `pip install -e ".[dev]"` → `alembic upgrade head` |
| `make dev` | 启动全部服务 | 先执行 `make release-9111`(避免 9111 被占)→ `docker compose up -d postgres redis` → 若 11434 未被占用则 `docker compose --profile ollama up -d` → 前台运行 `python -m team_memory.web.app` |
| `make web` | 仅启动 Web | 先执行 `make release-9111` → 前台运行 `python -m team_memory.web.app`(默认 [http://0.0.0.0:9111)](http://0.0.0.0:9111)) |
| `make mcp` | 启动 MCP | `bash scripts/run_mcp_with_dotenv.sh`(需仓库根 `.env`;stdio,`**memory_*` 六工具**),配置见 [docs/guide/mcp-server.md](docs/guide/mcp-server.md) |
| `make mcp-verify` | 校验 MCP 工具注册 | 跑 `TestLiteToolRegistration` 中工具数量与名称(无需长驻 MCP 进程) |
| `make health` | 健康检查 | `./scripts/healthcheck.sh`(检测 DB、Web、Ollama 等) |
| `make migrate` | 数据库迁移 | `alembic upgrade head` |
| `make migrate-fts` | 补齐经验表 FTS 字段(存量迁移) | `python scripts/migrate_fts.py`;可用 `--dry-run` 预览待更新条数 |
**说明**:`make dev` 与 `make web` 会在启动前自动释放 9111 端口(停止占用该端口的 Docker 容器或本机进程),因此可重复执行而不会出现「address already in use」。
### 仪表盘报「加载仪表盘失败」时
1. **先看健康检查**:`make health` 或 `GET http://localhost:9111/health`。
- 若输出中有 `**dashboard_stats: FAIL`** 及后面的 `error` / `ops_hint`,按提示排查(常见原因:数据库未启动、未执行迁移、或 config 中 `database.url` 错误)。
- 若 **database 为 FAIL**:先启动数据库(如 `docker compose up -d postgres`),执行 `alembic upgrade head` 后再访问仪表盘。
2. **API 错误会返回 JSON**:若后端报 500,接口会返回 `detail`、`ops_error_id`、`ops_hint`。
- 前端会把这些信息拼进错误提示;
- 在服务端日志中按 `ops_error_id` 搜索可定位对应异常。
3. **本地快速诊断**:`python scripts/smoke/smoke_web_dashboard.py [--api-key KEY]` 会请求 `/health` 和 `/api/v1/stats` 并打印结果,便于确认是数据库、配置还是鉴权问题。
### 备份恢复
```bash
# 备份(输出到 backups/ 目录,命名格式 team_memory_YYYYMMDD_HHMMSS.sql.gz)
make backup
# 或: ./scripts/backup.sh [output_dir]
# 恢复(在项目根目录执行)
./scripts/restore.sh backups/team_memory_20260209_120000.sql.gz
```
### Docker 部署
```bash
# 自动等待 PG、运行迁移、拉取 Ollama 模型、生成 admin key
docker compose up -d
# 统一端口: 9111
```
**生产环境必须修改默认 Key,禁止使用 changeme。** 含密码的 `database.url` 等敏感配置勿提交 Git,建议使用环境变量。
### 监控
- 内置仪表盘: Web UI 首页
- 健康检查: `make health` 或 `GET /health`
- 就绪探针: `GET /ready`
### 可观测性 / 日志
- **I/O 日志**:启用 `TEAM_MEMORY_LOG_IO_ENABLED=1` 可记录 MCP 工具调用、检索管道、服务层等内部节点日志,便于排查与性能分析。粒度由 `LOG_IO_DETAIL`(mcp/service/pipeline/full)控制。
- **文件输出**:启用 `LOG_FILE_ENABLED` 或 `TEAM_MEMORY_LOGGING__FILE_ENABLED=1`,日志写入 `LOG_FILE_PATH`(默认 `logs/team_memory.log`),支持按大小轮转。
- **热加载**:运行时通过 `GET /api/v1/config/logging` 查询、`PUT /api/v1/config/logging` 更新日志配置(需认证),无需重启即可生效;持久化需写入当前使用的 YAML(如 `config.development.yaml`)。
日志 JSON 形态与脱敏逻辑见 `src/team_memory/bootstrap.py`(`_JsonFormatter`、`_SENSITIVE_KEYS`)及 `tests/test_logging_json.py`。
## 技术栈 / Tech Stack
| 层面 | 技术选型 |
| ------ | --------------------------------------------------------- |
| MCP | FastMCP |
| Web | FastAPI + Uvicorn |
| 数据库 | PostgreSQL + pgvector |
| ORM | SQLAlchemy 2.0 (async) |
| 嵌入 | qwen3-embedding:0.6b (Ollama) / OpenAI / 本地模型 |
| 搜索 | 向量 + 全文检索(jieba+hybrid AND/OR) + RRF 融合 + Reranker |
| 缓存 | 内存 LRU / Redis |
| 配置 | Pydantic Settings + YAML(服务端)/ TOML + ClientConfig(客户端) |
| 迁移 | Alembic |
| Daemon | TM Daemon (launchd) — Obsidian watcher + RefinementWorker |
| 评估 | Faithfulness (RAGAS LLM Judge) + search_eval |
### 入口点 / Entry Points
| 命令 | 模块 | 用途 |
| ----------------- | ---------------------------------- | ----------------- |
| `team-memory` | `team_memory.server:main` | MCP Server(stdio) |
| `team-memory-web` | `team_memory.web.app:main` | Web 服务 |
| `tm-cli` | `team_memory.cli:main` | CLI 兼容层 + 配置管理 |
| `tm-daemon` | `team_memory.daemon.__main__:main` | TM Daemon 守护进程 |
### 代码组织 / Code Organization
```
src/team_memory/ # Python 包(PYTHONPATH 只需 src/)
server.py # MCP Server(memory_* 工具)
cli.py # CLI(tm-cli)+ config/setup 子命令
client_config.py # ClientConfig — 统一客户端配置
project_resolver.py # 项目名零配置推断 + 别名注册
daemon/ # TM Daemon(原 scripts/daemon/)
hooks/ # 平台 Hook(原 scripts/hooks/)
web/ # Web 服务(FastAPI)
services/ # 业务逻辑层
storage/ # 数据访问层
...
```
旧路径 `scripts/daemon/` → `src/team_memory/daemon/`,`scripts/hooks/` → `src/team_memory/hooks/`。PYTHONPATH 不再需要 `scripts/`,只需 `src/`。
## FAQ
**Q: TeamMemory 和 Cursor Rules 有什么区别?**
A: Rules 是静态的、手动维护的规范文件,适合"已经确定的"知识(代码风格、架构约束)。TeamMemory 是动态的、AI 自动积累的经验库,适合"还在演化的"知识(Bug 根因、方案权衡、实际踩坑)。两者互补:经验在 TeamMemory 中积累,当某个模式足够稳定后,可以将其固化为 Rule。
**Q: 经验库越来越大,AI 上下文会不会爆?**
A: 不会。TeamMemory 有多层机制控制输出体量:语义搜索本身只返回最相关的 Top-N 结果;Token 预算控制会自动裁剪过长的输出;Reranker 会过滤低相关度结果;PageIndex-Lite 对长文档做节点级检索而非全文返回。经验库从 100 条增长到 10000 条,AI 每次实际读取的内容量不会显著增加。
**Q: 团队成员不想手动录入经验怎么办?**
A: 这正是 TeamMemory 的设计重点。让 AI 在适当时机调用 `**memory_save(content=...)`** 可把长对话交给服务端解析并写入(常为草稿,视配置而定);也可在 Web 中粘贴文档或 URL 生成经验后再审核发布。
**Q: 切换 Embedding 模型后需要做什么?**
A: 需要重新生成所有 embedding。步骤:1) 更新 `config.development.yaml` 中 `embedding.ollama.model` 和 `dimension`;2) 执行 `alembic upgrade head`(如有维度迁移);3) 执行 `make embedding-backfill` 重新生成向量。
**Q: 存量数据如何支持全文检索(FTS)?**
A: 若经验表存在 `fts` 为空的记录,可执行 `make migrate-fts` 或 `python scripts/migrate_fts.py` 回填;先用 `--dry-run` 可预览待更新条数。
**Q: 没有 Ollama 可以使用吗?**
A: 可以。将 `embedding.provider` 改为 `openai` 并配置 API Key,或使用 `local` 加载本地 sentence-transformers 模型。
**Q: 多个项目的经验会混在一起吗?**
A: 不会。项目名通过 `.tm.toml` > git 仓库名 > 目录名自动推断,无需手动配置。也可通过 `TEAM_MEMORY_PROJECT` 环境变量或工具入参 `project` 显式指定。每个项目的经验独立存储和检索,不会互相干扰。别名机制(`.tm.toml` 的 `aliases`)确保项目重命名后历史经验仍可检索。
## 开发
### 运行测试
```bash
# 全部测试
pytest -v
# 带覆盖率
pytest --cov=team_memory
```
### 代码检查
```bash
# 检查
ruff check src/
# 自动修复
ruff check src/ --fix
```
### CI/CD
推送至 `main` / `develop` 或向 `main` 提 PR 时,GitHub Actions 会执行 lint、测试与 Docker 构建。触发条件与各 job 说明见 [.github/workflows/ci.yml](.github/workflows/ci.yml)。
### 文档同步约定
- **功能或代码变更后**,须同步更新本 **README**;文档不同步不得视为任务完成。
## 文档结构
- **设计文档**:[docs/](docs/)(索引:[docs/README.md](docs/README.md))