一、问题背景
技术团队面临的文档困境:
- API文档散落在多个系统(GitHub、Confluence、Swagger、内部Wiki)
- 新人重复问同样的问题(“这个接口鉴权怎么配?”“那个参数是什么意思?”)
- 技术负责人时间被频繁打断,回答重复性技术问题
- 文档有,但找不到;找到了,但版本不对
核心痛点: 文档存在,但信息获取效率极低。
二、整体架构设计
核心思路: 将散落的技术文档整合为统一知识库,通过RAG实现智能问答。
系统架构:
text
复制下载
┌─────────────────────────────────────────────┐
│ 数据源层 │
│ Swagger │ GitHub │ Confluence │ 内部Wiki │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 处理层 │
├─────────────────────────────────────────────┤
│ 文档爬取 │ 格式解析 │ 文档切分 │ 向量化 │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 存储层 │
│ 向量数据库 │ 原始文档库 │ 元数据索引 │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 检索服务层 │
├─────────────────────────────────────────────┤
│ 查询改写 │ 向量检索 │ 重排序 │ 上下文增强 │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 问答层 │
│ LLM生成 │ 来源溯源 │ 反馈收集 │
└─────────────────────────────────────────────┘
三、核心工程模块
模块一:多源文档爬取与解析
支持的数据源类型:
| 数据源 | 格式 | 解析方案 |
|---|---|---|
| Swagger/OpenAPI | JSON/YAML | OpenAPI解析器,提取接口、参数、响应 |
| GitHub Markdown | .md | Markdown解析器,保留标题层级 |
| Confluence | HTML | HTML解析,提取正文和元数据 |
| 内部Wiki | HTML/纯文本 | 自定义爬虫 |
文档版本管理:
sql
复制下载
-- 文档版本追踪表
CREATE TABLE doc_version (
id BIGINT PRIMARY KEY,
source_type VARCHAR(32), -- swagger/markdown/confluence
source_url VARCHAR(512),
version VARCHAR(32), -- v1.0.0 / main / release-2.x
fetched_at DATETIME,
content_hash VARCHAR(64), -- 内容去重
status VARCHAR(16) -- processing/done/failed
);
增量更新策略:
- 定时爬取(每日/每周)
- Webhook触发(文档更新时自动同步)
- 内容hash对比,避免重复处理
模块二:文档切分策略
技术文档的特殊性:代码块、表格、API定义需要特殊处理。
切分规则:
python
复制下载
def chunk_document(doc):
chunks = []
# 1. 按标题层级切分(保留结构)
sections = split_by_headers(doc)
for section in sections:
# 2. 代码块单独处理(保留语言标识)
if section.type == "code_block":
chunks.append({
"type": "code",
"language": section.language,
"content": section.content,
"metadata": {"api_endpoint": extract_api_endpoint(section)}
})
# 3. 表格单独处理(转换为文本描述)
elif section.type == "table":
chunks.append({
"type": "table",
"content": table_to_text(section),
"metadata": {"columns": section.columns}
})
# 4. 普通段落按语义切分
else:
chunks.extend(split_by_semantic(section.content, max_tokens=512))
return chunks
切分参数经验值:
| 文档类型 | 切分策略 | Chunk大小 | Overlap |
|---|---|---|---|
| API文档 | 按接口切分 | 256-512 | 50 |
| Markdown手册 | 按标题切分 | 512-1024 | 100 |
| 代码示例 | 完整保留 | 不切分 | - |
| 架构设计文档 | 按小节切分 | 1024 | 150 |
模块三:向量化与检索策略
Embedding模型选型:
| 场景 | 推荐模型 | 维度 | 说明 |
|---|---|---|---|
| 代码/API检索 | CodeBERT / UniXcoder | 768 | 代码语义理解强 |
| 中文技术文档 | BGE-large-zh / M3E | 1024 | 中文效果好 |
| 混合场景 | text-embedding-3-small | 1536 | 通用性强 |
检索策略优化:
在具体实现上,有企业采用 ZGI 作为RAG检索的编排平台,其多路召回、重排序、上下文增强能力覆盖了上述检索策略。
多路召回策略:
python
复制下载
def hybrid_search(query, top_k=10):
# 向量检索
vector_results = vector_db.search(query, top_k=20)
# 关键词检索(BM25)
keyword_results = bm25.search(query, top_k=20)
# RRF融合排序
fused_results = reciprocal_rank_fusion(
[vector_results, keyword_results],
weights=[0.6, 0.4]
)
return fused_results[:top_k]
重排序优化:
python
复制下载
def rerank(query, candidates):
# 使用CrossEncoder模型精排
scores = cross_encoder.predict([
[query, doc.content] for doc in candidates
])
# 按分数重新排序
reranked = sorted(zip(candidates, scores), key=lambda x: x[1], reverse=True)
return reranked[:5] # 取Top5
四、问答流程设计
完整问答流程:
text
复制下载
1. 用户提问 "如何调用用户信息接口?"
↓
2. 查询改写
- 识别意图:API调用指南
- 提取实体:用户信息接口
↓
3. 多路召回
- 向量检索:从向量库召回20个chunk
- 关键词检索:BM25召回20个chunk
↓
4. 重排序
- CrossEncoder精排,取Top5
↓
5. 上下文增强
- 补充接口完整定义
- 关联相关代码示例
- 附带版本信息(当前最新版v2.3.0)
↓
6. LLM生成
- Prompt注入系统角色和上下文
- 约束:仅基于知识库回答,附来源
↓
7. 输出答案 + 来源引用
Prompt模板:
text
复制下载
你是一个技术文档助手。请根据以下【技术文档内容】回答问题。
【技术文档内容】
{检索到的chunks列表,每个chunk包含内容和来源}
【用户问题】
{用户输入的问题}
约束:
1. 如果文档中有明确信息,基于文档回答
2. 如果文档中没有,明确说“文档中未找到”
3. 回答中附上信息来源(文档名称、章节、版本)
4. 涉及代码时,保持代码块格式
回答:
五、效果评估
评估指标体系:
| 指标 | 定义 | 目标值 |
|---|---|---|
| 检索召回率 | Top5包含正确答案的比例 | >90% |
| 答案准确率 | 生成的答案正确且完整 | >85% |
| 来源可信度 | 答案来源可追溯到正确文档 | >95% |
| 平均响应延迟 | 用户提问到收到答案 | <3秒 |
测试集构建:
- 收集200个真实的技术问答对
- 标注每个问题的期望答案和来源文档
- 定期跑测试集,跟踪指标变化
六、落地效果
某技术团队上线该系统后,3个月数据:
| 指标 | 上线前 | 上线后 |
|---|---|---|
| 技术问题平均解答时间 | 30-60分钟 | 2分钟 |
| 新人独立解决问题比例 | 40% | 85% |
| 技术负责人被中断次数/天 | 15-20次 | 5次以下 |
| 文档查找时间 | 10-20分钟 | 30秒以内 |
七、可复制的落地路径
第一阶段:MVP验证(1-2周)
- 选择1个核心文档源(如一个产品线的API文档)
- 搭建基础RAG流程(切分→向量化→检索→生成)
- 用20个真实问题测试效果
第二阶段:多源整合(2-4周)
- 接入更多文档源(Markdown、Confluence、Swagger)
- 优化切分策略和检索参数
- 建立版本管理机制
第三阶段:持续优化(长期)
- 收集bad case,定期优化
- 增加用户反馈机制(点赞/点踩)
- 扩展到更多技术场景(架构设计、故障排查)
八、总结
技术文档智能问答系统的核心价值:将“人找人”变成“人问系统” 。
关键技术要点:
- 文档切分:按文档类型差异化处理,代码/表格单独策略
- 多路召回:向量+关键词融合,RRF排序
- 重排序:CrossEncoder精排,提升Top5准确率
- 版本管理:文档版本追踪,答案附版本信息
本文基于技术文档知识库建设实践整理。