docs: add CLAUDE.md for AI agent guidance
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## 项目概述
|
||||||
|
|
||||||
|
Markdown 文档向量数据库 — 将 .md 文件分块 → 嵌入 → 存入 ChromaDB,通过 FastAPI HTTP 或 CLI 提供语义检索。
|
||||||
|
|
||||||
|
## 常用命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv sync # 安装依赖
|
||||||
|
uv run pytest tests/ -v # 全部测试 (31 个)
|
||||||
|
uv run pytest tests/test_api.py -v # 单个测试模块
|
||||||
|
uv run pytest tests/ -v -k "test_search" # 按名称过滤
|
||||||
|
|
||||||
|
# CLI
|
||||||
|
uv run python -m src.cli.main ingest <file.md> # 入库单文件
|
||||||
|
uv run python -m src.cli.main ingest-dir ./md_docs/ # 批量入库
|
||||||
|
uv run python -m src.cli.main search "关键词" # 搜索
|
||||||
|
uv run python -m src.cli.main stats # 统计
|
||||||
|
uv run python -m src.cli.main serve --port 8000 # 启动 HTTP 服务
|
||||||
|
```
|
||||||
|
|
||||||
|
## 架构
|
||||||
|
|
||||||
|
```
|
||||||
|
core/ # 核心逻辑(不依赖 server/cli)
|
||||||
|
├── config.py # YAML → dataclass (AppConfig)
|
||||||
|
├── db.py # VectorDB: ChromaDB PersistentClient 封装
|
||||||
|
├── embedder.py # Embedder: 本地模型(BGE-small-zh) + API 双模
|
||||||
|
├── ingest.py # MarkdownSplitter(混合分块) + DocumentIngestor
|
||||||
|
└── search.py # Searcher: 语义检索 + 源文件管理
|
||||||
|
|
||||||
|
server/app.py # FastAPI HTTP 层,懒加载单例
|
||||||
|
cli/main.py # Typer CLI,5 个命令
|
||||||
|
```
|
||||||
|
|
||||||
|
**数据流**: MD 文件 → `MarkdownSplitter.split()` (标题→段落分块) → `Embedder.embed()` → `ChromaDB collection.add()` → `Searcher.search()` 查询
|
||||||
|
|
||||||
|
**依赖方向**: `config` ← `db` ← `embedder` ← `ingest`/`search` ← `server`/`cli`
|
||||||
|
|
||||||
|
## 关键实现细节
|
||||||
|
|
||||||
|
### 嵌入模型回退策略 (embedder.py)
|
||||||
|
|
||||||
|
本地模式优先从缓存加载(`local_files_only=True`);若模型未下载,自动切换到 `hf-mirror.com` 下载后恢复离线。模块级 `os.environ.setdefault("HF_HUB_OFFLINE", "1")` 避免 Windows SSL 证书问题。
|
||||||
|
|
||||||
|
### 混合分块策略 (ingest.py)
|
||||||
|
|
||||||
|
`MarkdownSplitter`: 先按 `#`/`##`/`###` 标题拆分 → 章节超 `max_size`(1000) 则按 `\n\n` 段落拆 → 单个段落仍超限则按句号/感叹号硬切,所有拆分保留 overlap。
|
||||||
|
|
||||||
|
### 配置加载 (config.py)
|
||||||
|
|
||||||
|
`load_config()` 从 YAML 读取 → 文件不存在返回全默认值 `AppConfig()`。`AppConfig.__init__(**kwargs)` 将字典递归分发到子 dataclass (`ChromaConfig`/`EmbedConfig`/`ChunkConfig`/`ServerConfig`)。
|
||||||
|
|
||||||
|
### 服务端单例 (server/app.py)
|
||||||
|
|
||||||
|
`VectorDB`、`Embedder`、`Searcher`、`DocumentIngestor` 使用模块级懒加载单例,避免 import 时就加载模型。通过 `MD_VECTOR_DB_DATA_DIR` 和 `MD_VECTOR_DB_COLLECTION` 环境变量覆盖配置。
|
||||||
|
|
||||||
|
### Windows 终端编码 (cli/main.py)
|
||||||
|
|
||||||
|
`sys.stdout` 强制重编码为 UTF-8(`io.TextIOWrapper`),避免 emoji 在 GBK 终端上报 `UnicodeEncodeError`。
|
||||||
|
|
||||||
|
## 配置
|
||||||
|
|
||||||
|
`config.yaml` 控制:
|
||||||
|
- `chroma.persist_dir` / `collection_name` — ChromaDB 存储
|
||||||
|
- `embed.mode` — `local`(BGE-small-zh-v1.5) 或 `api`(OpenAI 兼容)
|
||||||
|
- `chunk.max_size` / `overlap` — 分块参数
|
||||||
|
- `server.host` / `port` — HTTP 服务
|
||||||
|
|
||||||
|
## HTTP API
|
||||||
|
|
||||||
|
| 方法 | 路径 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| GET | `/` | 重定向到 /docs (Swagger) |
|
||||||
|
| GET | `/api/v1/health` | 健康检查 |
|
||||||
|
| GET | `/api/v1/collections` | 列出集合和源文件 |
|
||||||
|
| POST | `/api/v1/ingest` | 入库 (file_path 或 content+file_name) |
|
||||||
|
| POST | `/api/v1/search` | 语义检索 (query + top_k) |
|
||||||
|
| DELETE | `/api/v1/documents/{file_name}` | 按文件名删除 |
|
||||||
Reference in New Issue
Block a user