← blog 架构与系统 · 2026-04-21
enterprise RAG docs spec
规定企业知识库 RAG 系统 Markdown 源文档的文件位置、front-matter 字段、标题层级与分块规则。
本文档定义企业知识库 RAG 系统中 Markdown 源文档的格式、结构和编写规范。
文件位置
所有知识库文档放在仓库根目录下的 enterprise-kb/ 目录中,以模块名为文件名(不含特殊字符),后缀为 .md。
文档结构
每篇文档由两部分组成:YAML front-matter 和 Markdown 正文。
---
skill_points:
- 技能点A
- 技能点B
module: 模块名
score_points:
- "基础: 描述"
- "进阶: 描述"
- "高级: 描述"
---
# 标题
## 大章节 ← 上下文标题,不单独成块
### 子主题 ← 上下文前缀,每个 #### chunk 的内容前缀
#### 具体知识点A ← 最小分块单位
内容...
#### 具体知识点B ← 每个 #### 独立成一个 chunk
内容...
Front-matter 字段
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `skill_points` | list[string] | 是 | 文档关联的技能点列表,供 `/retrieve/by-skill` 检索用 |
| `module` | string | 是 | 所属模块名(唯一),供 `/retrieve/by-module` 检索用 |
| `score_points` | list[string] | 是 | 评分要点,按难度分级:基础 / 进阶 / 高级 |
正文标题层级规范
| 层级 | 类型 | 行为 |
|------|------|------|
| `#` | 一级标题 | 文档标题,跳过,不产生 chunk |
| `##` | 二级标题 | 父级上下文标记,不单独成块 |
| `###` | 三级标题 | 上下文前缀,每个 `####` chunk 的内容前缀 |
| `####` | 四级标题 | **最小分块单位**,每个 `####` 及其下内容合成一个 chunk |
代码块边界
代码块(```)是”粘性”的。当一个 #### chunk 内包含未关闭的代码块时,遇到下一个 #### 标题不会触发切块,以避免代码块被截断。
#### String
最基础类型...
```python
r.set('user:1001', ...)
``` ← 代码块正常关闭
#### Hash ← 可以安全切块
#### List
内容...
```python
r.lpush('key', 'val')
``` ← 代码块正常关闭
### 下一个主题 ← flush 后此 ### 成为下一个 chunk 的前缀
分块结果示例
对于如下正文:
## 功能规范
### 数据类型与适用场景
#### String
最基础类型,最大 512MB...
```python
r.set('user:1001', ...)
Hash
适合存储对象结构…
r.hset('product:2001', mapping={...})
List
有序列表…
将产生 **3 个 chunk**:
| chunk | heading_path | content 片段 |
|-------|-------------|-------------|
| 0 | `功能规范 > String` | `### 数据类型与适用场景\n#### String\n最基础类型...\n```python\nr.set...` |
| 1 | `功能规范 > Hash` | `### 数据类型与适用场景\n#### Hash\n适合存储对象结构...\n```python\nr.hset...` |
| 2 | `功能规范 > List` | `### 数据类型与适用场景\n#### List\n有序列表...\n```python\nr.lpush...` |
**heading_path 格式**:`## 父标题 > #### 当前标题`(两级,简化版)。
---
## skill_points 编写规范
- 每个文档至少 2 个技能点
- 技能点名称应具体、可用作检索关键词
- 命名惯例:使用中文名词短语,如「Redis数据类型」「缓存穿透」
- 避免过于宽泛的名称(如「Redis」应写「Redis数据类型」或「Redis缓存」)
## score_points 编写规范
- 必须包含「基础」「进阶」「高级」三个级别
- 每级 1-3 条,简洁描述评判标准
- 格式:`"级别: 描述"`(冒号前为级别,冒号后为具体要求)
---
## 示例
### Redis缓存模块
```markdown
---
skill_points:
- Redis数据类型
- 缓存穿透
- 缓存击穿
- 缓存雪崩
module: Redis缓存
score_points:
- "基础: 能否正确选择 String/Hash/List/Set 类型并说明适用场景"
- "进阶: 能否设计缓存穿透、击穿、雪崩的防御方案"
- "高级: 能否根据业务场景制定完整的缓存生命周期管理策略"
---
# Redis缓存模块
## 功能规范
### 数据类型与适用场景
#### String
最基础类型,最大 512MB。适用于简单的键值缓存,如用户 Token、配置项。
```python
r = redis.Redis(host='localhost', port=6379, db=0)
r.set('user:1001', json.dumps({'name': 'Alice'}), ex=3600)
Hash
适合存储对象结构,按字段访问。适用于用户画像、商品信息。
r.hset('product:2001', mapping={'name': 'Mouse', 'price': 99.9})
List
有序列表,支持两端插入删除。适用于最新消息流、任务队列。
r.lpush('recent:articles', 'article:1045')
r.lrange('recent:articles', 0, 9)
缓存问题与防御
缓存穿透
大量请求查询不存在的数据绕过缓存直接打满数据库。防御方案:布隆过滤器 + 空值缓存。
缓存击穿
热点键过期瞬间,大量并发请求同时穿透到数据库。防御方案:互斥锁 + 逻辑过期。
缓存雪崩
大量键同时过期或 Redis 宕机,导致数据库压力骤增。防御方案:过期时间随机偏移 + 主从哨兵高可用。
配置说明
关键配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
maxmemory | 0(不限制) | 最大内存,建议设为物理内存的 70% |
maxmemory-policy | noeviction | 内存满时的淘汰策略 |
评分要点
基础级
- 能说出 String、Hash、List、Set、ZSet 的特点和基本命令
- 能配置 Redis 基本连接和简单存取操作
进阶级
- 能根据业务场景选择合适的数据类型
- 能识别并防御缓存穿透、击穿、雪崩问题
高级
- 能设计完整的缓存生命周期管理策略
- 能规划 Redis 集群架构,处理故障转移
---
## 命名规则
| 要素 | 规则 |
|------|------|
| 文件名 | `enterprise-kb/{模块名}.md`,如 `Redis缓存.md` |
| `module` | 与文件名一致,不含后缀 |
| `skill_points` | 具体技能名称,中文为主 |
| `score_points` | 格式 `"级别: 描述"`,级别为「基础」「进阶」「高级」 |
---
## 提交流程
1. 在 `enterprise-kb/` 目录下创建/编辑 `.md` 文件
2. 确保 front-matter 三个字段齐全且格式正确
3. 运行索引构建:
```bash
uv run python scripts/build_index.py --source ./enterprise-kb/
- 提交 git 并推送,触发 post-commit hook 自动增量更新