用大模型做一个简单「文档问答助手」
目录
2022 年开始,大模型 API 越来越好用,大家最直觉的一个想法就是:
能不能把项目文档「喂给」模型,然后直接用自然语言问问题?
这篇文章记录的是一个从 0 到 1 的小 Demo:用大模型 API + 向量检索,实现一个能回答「我们自己文档」问题的小助手。
1. 目标和约束
目标很简单:
- 把部分项目文档(接口说明、架构设计、规范)导入系统;
- 在一个聊天界面里,可以问:
- 「用户登录接口的必填参数有哪些?」
- 「私募投资人小程序的技术栈是什么?」
- 助手能基于文档给出相对准确的回答。
约束:
- 不追求「完美答案」;
- 优先做到:能指向正确文档,并给出简洁总结。
2. 总体架构
整体流程可以概括成:
- 文档导入 & 切分;
- 向量化(Embedding)并存入向量库;
- 用户提问 → 向量检索相关片段;
- 把相关片段 + 问题一起发给大模型 → 生成回答;
- 前端展示答案 + 引用片段。
用一张简图就是所谓的:RAG(检索增强生成)。
3. 文档预处理:从 Markdown 到「小段文本」
我们选用的文档源主要是:
- Git 仓库里的 Markdown(README、设计文档);
- 部分导出的接口文档(JSON/YAML 转文本)。
预处理步骤:
- 把 Markdown 转成纯文本(保留标题层级);
- 按一定策略切分成「小段文本」,比如每段 300–500 字;
- 每段附带元信息:文档名、段落标题、在文档中的位置。
简单示例:
{
"docId": "fund-investor-miniapp",
"title": "技术栈与整体架构",
"content": "前端采用 Vue3 + uni-app...",
"section": "2.1 技术栈",
"index": 5
}
切分策略的小经验:
- 不要按固定字数「硬切」,适当按段落/标题分;
- 避免单段太短(模型不够信息)或太长(提示超长)。
4. 向量化与存储
4.1 向量化(Embedding)
选择一个支持中文的 Embedding API,调用方式类似:
const res = await embeddingApi.embed({
input: chunk.content,
});
const vector = res.vector; // 一串浮点数
对每个文本块都做一次 Embedding,得到:
{
"docId": "fund-investor-miniapp",
"section": "2.1 技术栈",
"index": 5,
"content": "前端采用 Vue3 + uni-app...",
"vector": [0.12, -0.03, ...]
}
4.2 向量库
实验阶段可以简单一点:
- 用 SQLite / Postgres + 向量扩展;
- 或者用现成的向量数据库(Milvus、Pinecone 等);
- 甚至可以上一个简单的 in-memory 方案(样本量小时)。
需要支持的操作只有一个:
给定一个向量,查找余弦相似度最高的 Top K 条记录。
5. 问答流程:检索 + 生成
用户在前端输入问题:"投资人小程序支持哪些终端?"
5.1 把问题向量化
const qEmbedding = await embeddingApi.embed({ input: question });
5.2 从向量库检索相关段落
const topChunks = await vectorStore.search(qEmbedding, { topK: 5 });
结果类似:
[
{
"docId": "fund-investor-miniapp",
"section": "1. 概述",
"content": "信e募投资人小程序面向私募投资人... 支持微信小程序与 H5 双端访问",
"score": 0.91
},
...
]
5.3 构造大模型 Prompt
把问题 + 相关片段一起发给大模型:
你是项目文档助手,只能根据给定的文档内容回答问题。
【文档片段】
1. 信e募投资人小程序面向私募投资人... 支持微信小程序与 H5 双端访问
2. ...
【问题】
投资人小程序支持哪些终端?
请用简洁的方式回答,并在需要时指出是根据哪个文档片段得出的。
模型返回:
投资人小程序目前支持 微信小程序 和 H5 页面访问(见文档片段 1)。
5.4 前端展示
- 上方显示自然语言回答;
- 下方列出「参考文档」,跳转到具体文档位置。
6. 前端界面的小设计
界面结构:
- 左侧:文档问答区域(类似 Chat);
- 右侧:可选择切换当前知识库(如「私募项目」「运营中台」等)。
交互重点:
- 在回答里高亮「来源文档」;
- 对于显然答不上来的问题(向量检索分数都很低),直接说「文档里没有相关信息」;
- 提供一个「查看原文」按钮,避免用户只看总结。
7. 实验中的边界和坑
-
文档不规范 → 答案也不靠谱
- 文档内容过时或互相矛盾时,模型没有魔法,只能「合理胡说」;
- 这个系统本质上也在倒逼我们写更结构化、更新及时的文档。
-
长文档切分不好 → 检索命中不准
- 有时候关键信息被拆散,落在不同段;
- 需要平衡「切得足够细」和「上下文足够完整」。
-
权限问题
- 内部文档可能有权限划分;
- 需要在问答层面做权限控制,只在向量检索时检索用户有权限的文档。
-
延迟与成本
- Embedding + 检索 + 大模型推理,整体延迟要控制在可接受范围;
- 请求频率高时要考虑缓存热门问题/结果。
8. 小结:文档助手不替代文档,但能把文档「用起来」
这个小 Demo 做完之后的几个感受:
- 大模型 + 向量检索并没有想象中复杂,工程实现是完全可控的;
- 它不会替代文档本身,反而会暴露文档结构与质量问题;
- 在团队内部,它是一个很好的「知识入口」,新同学可以更自然地问问题。
未来可以继续演进:
- 接入更多数据源(接口日志、监控告警说明等);
- 支持在回答中「生成操作指南」;
- 为特定角色(测试、运营)定制不同视图。
但即便只停留在这个 V1 的程度,它已经是一个挺实用的内部工具了。