乐于分享
好东西不私藏

如何用 AI 编程工具,手搓一个本地 RAG

如何用 AI 编程工具,手搓一个本地 RAG
没有大厂背景,没有算法团队。一台 M1 电脑,一个周末加五个晚上,从零到完整可用的 RAG 系统。这篇文章不是教程,是我把每一步踩过的坑原样讲出来。
起因:朋友的一句话

「你们那个食堂管理系统,能不能接 AI?让管理员用自然语言查法规。」

当时我的技术栈:Docker、PostgreSQL、Express。数据库设计、API开发、前端页面,这些我熟。但 AI 是什么、怎么接入,我完全没概念。

「试试吧。」我说。

这一试,就是六天。

第一天:搭环境,三连坑

要做 AI 问答,需要三样东西:

  • 向量数据库
    ——存文档的地方
  • 嵌入模型
    ——把文字变成数字的地方
  • 大模型——生成回答的地方

我选了PostgreSQL+ pgvector(因为本来就有PG,加个插件就行)、bge-small-zh(中文专用,25MB)、qwen2.5 7B(本地跑,数据不出服务器)。

听起来很顺?接下来三天,每个选择都付出代价。

坑一:被墙。ollama pull拉模型,直接超时。最后的解法很土:翻墙用浏览器下载 GGUF 文件,再ollama create手动导入。4.7GB的模型文件,下载的时候我盯着进度条祈祷别断。

坑二:嵌入模型选错了。一开始用 nomic-embed-text——网上都说它好。结果搜「留样温度」出来的结果驴唇不对马嘴。查了才知道:nomic 是英文优化的,中文语义匹配差。换成 bge-small-zh,立刻准了。从 768 维降到 512 维,反而更好。

坑三:Python子进程最初架构是 Node.js spawn Python 脚本调嵌入模型,动不动超时。后来一咬牙把 Python 全砍了——所有 AI 模型统一走 Ollama HTTPAPI(localhost:11434)。一个端口搞定所有,稳定多了。

这一天的教训:选型不是看评测榜,是看你的数据是什么语言的。

第二天:把文档喂进去

28 篇食安法规,不能整篇扔给模型——7B 模型消化不了,塞多了反而找不到重点。

我的切片策略很简单:按段落边界拆,不是硬切。用双换行符把文档拆成自然段落,逐段往后拼,拼到 500 字切一刀,留 50 字重叠——防止关键信息刚好卡在切缝里。

数据库用两张表:kbarticles存原文,kbchunks存切片和向量。搜索扫切片表,命中后 JOIN 回父文档拿标题。

检索用双路混合:向量路(语义匹配)+ 关键词路(2-gram 模糊匹配),并行跑,结果交替合并去重。

为什么双路?纯向量对编号、人名不敏感;纯关键词对「高温消毒 → 热力杀菌」这种同义词对不上。两路互补,才不漏。

这一天的教训:文档切分不是技术题,是语文题——别把句子腰斩。

第三天:提示词,8 版迭代

7B 模型判断力弱。第一版提示词就一句话:「你是食安助手,请根据资料回答问题。」

结果模型动不动「我不知道」,甚至编假法规。

我迭代了 8 版,发现了三个反直觉的规律:

1. system/prompt 分离。qwen2.5 对 system 字段优先级更高。规则放 system,资料放 prompt——规则才不会被长资料淹没。

2. 思维链有用。加一句「先在脑中列出每条资料的关键信息,确认无遗漏后再组织回答」——遗漏率立刻降了。

3. 否定式强调 > 温和指令「不准少」比「请检查所有资料」有效得多。7B 模型对否定句更敏感。

最终 15个测试场景全部通过。这一天的教训:调 7B 模型,就是在跟一个不太聪明但很听话的实习生打交道——指令要短、要硬、要放在显眼位置。

第四天:太慢了,改造

跑通了,但用户问完一个问题要等 20 多秒。体验直接判死刑。

做了三件事:

1. 真流式 SSE。Ollama 设stream: true,返回 NDJSON——每行一个JSON,逐 token 推送。前端 ReadableStream 接收,一个字一个字往外蹦。用户至少知道它活着。

2.并行检索。向量搜索和关键词搜索从串行改并行。首 token 从 2 秒降到 700ms。

3. Redis 缓存。相同问题 1 小时内秒回。20 多秒变 80毫秒,300 倍加速。但带上下文的追问不缓存——「那温度呢」单独看没意义。

前端也做了过渡动画:检索完到 AI 吐字中间有 6 秒空档,用摘要打字机效果 + 闪烁光标填满。用户全程看到东西在动,就不焦虑。

这一天的教训:AI 产品的等待体验,比 AI 本身更决定生死。

第五天:怎么证明它「好」?

能跑了,但「好不好」没数。面试官问起来总不能说「我觉得挺好的」。

我搭了一条评估管线:

  • 30 题评估集
    :按知识库 6 大分类出题,每题标注期望命中的文档
  • Recall@5 = 96.7%
    :29/30 题在返回的前 5 篇里找到了答案
  • LLM-as-Judge
    :用 DeepSeekAPI当裁判,给 AI 回答打 1-5 分 + 扣分原因,平均 4.2 分
  • 回归测试:以后每次改提示词、换模型、调阈值,跑一遍评估集——软件工程的回归测试搬到 AI 上

这一天的教训:AI 系统最大的问题不是难做,是难证明。评估管线是给系统装仪表盘。

最后:它变成了一整套东西

六天后,这套系统有了名字和全链路:

Code

用户提问 → 双路检索(向量+关键词)→ pgvector → qwen2.5 生成 → SSE 流式 → 来源引用

再后来,我又给它加了 Redis 缓存层、封装成MCP工具让 Claude 直接调用、写了自动化评估脚本。

现在食堂管理员问「留样温度标准是多少」,系统 1 秒内开始流式回答,答案底部挂着法规来源。

产品经理的自我怀疑

写这篇文章之前,我犹豫了很久。

作为产品经理,我懂业务、懂流程、懂用户。但 AI 领域,网上全是「三个月转行大模型」「提示词工程师年薪百万」的喧嚣,我不确定自己算不算入门。

现在回头看这六天,我确定了两件事:

第一,AI 没那么玄。它是一套新的工具链,跟当年从 Excel 换到数据库、从瀑布流换到敏捷一样,是工程问题,不是玄学。

第二,产品经理做 AI 有天然优势。我踩的每一个坑——选型、切片、提示词、评估——本质都是产品决策:数据是什么语言?文档怎么切才不伤语义?模型答错了怎么兜底?这些问题,写十年PRD的人比纯技术背景的人更敏感。

我不是要证明「产品经理也能写代码」。我想说的是:当 AI 工具把工程门槛拉到普通人的射程内,懂业务的人反而成了最稀缺的变量。

下一个系统,已经开工了。

11 年 B 端产品经理,正在转型 AI 全栈交付。公众号记录转型过程,欢迎交流。