目录

用大模型做一个简单「文档问答助手」

2022 年开始,大模型 API 越来越好用,大家最直觉的一个想法就是:

能不能把项目文档「喂给」模型,然后直接用自然语言问问题?

这篇文章记录的是一个从 0 到 1 的小 Demo:用大模型 API + 向量检索,实现一个能回答「我们自己文档」问题的小助手。


1. 目标和约束

目标很简单:

  • 把部分项目文档(接口说明、架构设计、规范)导入系统;
  • 在一个聊天界面里,可以问:
    • 「用户登录接口的必填参数有哪些?」
    • 「私募投资人小程序的技术栈是什么?」
  • 助手能基于文档给出相对准确的回答。

约束:

  • 不追求「完美答案」;
  • 优先做到:能指向正确文档,并给出简洁总结

2. 总体架构

整体流程可以概括成:

  1. 文档导入 & 切分;
  2. 向量化(Embedding)并存入向量库;
  3. 用户提问 → 向量检索相关片段;
  4. 把相关片段 + 问题一起发给大模型 → 生成回答;
  5. 前端展示答案 + 引用片段。

用一张简图就是所谓的:RAG(检索增强生成)


3. 文档预处理:从 Markdown 到「小段文本」

我们选用的文档源主要是:

  • Git 仓库里的 Markdown(README、设计文档);
  • 部分导出的接口文档(JSON/YAML 转文本)。

预处理步骤:

  1. 把 Markdown 转成纯文本(保留标题层级);
  2. 按一定策略切分成「小段文本」,比如每段 300–500 字;
  3. 每段附带元信息:文档名、段落标题、在文档中的位置。

简单示例:

{
  "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);
  • 右侧:可选择切换当前知识库(如「私募项目」「运营中台」等)。

交互重点:

  1. 在回答里高亮「来源文档」;
  2. 对于显然答不上来的问题(向量检索分数都很低),直接说「文档里没有相关信息」;
  3. 提供一个「查看原文」按钮,避免用户只看总结。

7. 实验中的边界和坑

  1. 文档不规范 → 答案也不靠谱

    • 文档内容过时或互相矛盾时,模型没有魔法,只能「合理胡说」;
    • 这个系统本质上也在倒逼我们写更结构化、更新及时的文档。
  2. 长文档切分不好 → 检索命中不准

    • 有时候关键信息被拆散,落在不同段;
    • 需要平衡「切得足够细」和「上下文足够完整」。
  3. 权限问题

    • 内部文档可能有权限划分;
    • 需要在问答层面做权限控制,只在向量检索时检索用户有权限的文档。
  4. 延迟与成本

    • Embedding + 检索 + 大模型推理,整体延迟要控制在可接受范围;
    • 请求频率高时要考虑缓存热门问题/结果。

8. 小结:文档助手不替代文档,但能把文档「用起来」

这个小 Demo 做完之后的几个感受:

  1. 大模型 + 向量检索并没有想象中复杂,工程实现是完全可控的
  2. 它不会替代文档本身,反而会暴露文档结构与质量问题;
  3. 在团队内部,它是一个很好的「知识入口」,新同学可以更自然地问问题。

未来可以继续演进:

  • 接入更多数据源(接口日志、监控告警说明等);
  • 支持在回答中「生成操作指南」;
  • 为特定角色(测试、运营)定制不同视图。

但即便只停留在这个 V1 的程度,它已经是一个挺实用的内部工具了。