AI图鉴

AI图鉴首页 › AI 资讯 › 从零搭出能回答"自己文档"的 RAG:179 行代码,成本不到 1 毛

从零搭出能回答"自己文档"的 RAG:179 行代码,成本不到 1 毛

来源:掘金 · 发布时间:10-24 · 由 AI图鉴每小时自动聚合

从零搭出能回答"自己文档"的 RAG:179 行代码,成本不到 1 毛 为什么做这个项目 我是研一学生,目标是 2027 年暑期实习。一直想做点"能真正回答问题"的 AI 项目,而不是 demo 级的

从零搭出能回答"自己文档"的 RAG:179 行代码,成本不到 1 毛

为什么做这个项目

我是研一学生,目标是 2027 年暑期实习。一直想做点"能真正回答问题"的 AI 项目,而不是 demo 级的调用示例。VisionRAG 的设想是做一个图文混合的检索问答系统:企业里有大量图文混排文档,传统关键词检索找不到图,纯文本 RAG 又丢图像信息——最终产品要让每个答案都能溯源到具体图片和段落。

这个目标太远,所以第一周我只做一件事:先让 RAG 跑起来(纯文本版 v0)。这篇文章记录这 5 天(实际用了 3 天)的过程、代码和踩过的坑。

什么是 RAG

RAG(Retrieval-Augmented Generation,检索增强生成)解决大模型的一个老毛病:知识停在训练时点,新资料它不知道,还会瞎编。做法是:先把资料切块、转成向量存起来(建索引);用户提问时,把问题也转成向量,找出最相关的几个片段;再把片段和问题一起交给大模型,让它"看着资料"回答。

五步链路:加载 → 分块 → 嵌入 → 检索 → 生成。

5 天过程

- D1:uv 装环境、git 建仓、配 .env、第一次调通 DeepSeek API

- D2:把项目拆成 config.py / llm.py / main.py 三层,首次跑通对话

- D3:流式输出、温度参数、API 成本计费、防崩兜底、多轮记忆——还抓出一个"每句话调两次 API"的烧钱 bug

- D4:写最小 RAG——4 篇短文分块嵌入建索引,余弦相似度检索,3 个测试问题 top-1 全部命中

- D5:把检索片段拼进提示词生成答案,v0 端到端跑通——问"今天天气"它会老实说不知道

- D6:整理结构、写 README、补 .env.example(还修了一个 gitignore 的坑)

技术核心:三段加起来不到 40 行

嵌入(embedding)就是把文字变成一串数字(向量),我管它叫"语义身份证":意思相近的句子,向量方向也接近。检索 = 拿问题的身份证,跟所有候选比方向像不像。

余弦相似度衡量两个向量方向有多像,公式就三行:

def cos_sim(a: list[float], b: list[float]) -> float:

dot = sum(x * y for x, y in zip(a, b))

na = math.sqrt(sum(x * x for x in a))

nb = math.sqrt(sum(y * y for y in b))

return dot / (na * nb)

生成环节的核心是提示词组装——把检索到的片段拼进模板,再让模型回答:

prompt = f"""请基于以下资料回答用户问题。如果资料里没有答案,请直接说不知道。

资料:

{context}

问题:{question}"""

最后那句话是关键:"没有答案就说不知道"。实测问"今天上海天气怎么样",模型回答"不知道。资料中没有上海天气的信息。"——RAG 系统最重要的品行不是"能答",而是"不乱编"。

踩过的坑(全是真金白银)

1. 每句话被调了两次 API(最烧钱):给聊天加防崩代码时,旧的调用没删,导致一句话被调两次 API——回答出现两份,花费 double。排查套路:现象(两次回答)→ 假设(两次调用)→ 读代码证实(run() 里有两个 stream_chat)。

2. 把 >>> 敲进了 PowerShell:终端和 Python 解释器是两回事。PS> 开头是操作系统命令;先输入 python 进入解释器,出现 >>> 才能敲 Python 代码。看起来弱智,但第一天真踩了。

3. .env.example 被 gitignore 吞了:.env(真密钥,不能上传)和 .env.example(空模板,应该上传)长得太像,规则 .env.* 把模板也误杀了。加一行 !.env.example(感叹号 = 例外)救回来。教训:"文件存在" ≠ "文件会被提交",改完 .gitignore 必查 git status。

4. 零宽空格(U+200B):一个看不见的字符:从网页复制代码时会带进一个不可见字符,导致 if __name__ == "__main__": 永远为 False。踩了两次才学会排查:len('__main__') 应该是 8,多 1 就是有脏字符。现在关键代码一律手敲。

数据说话

- 代码量:179 行(8 个文件),完整跑通一个 RAG 问答

- git 提交:11 次,每次提交都是一天的边界

- 欠债清单:21 条——遇到不懂的先记下来,S2 阶段集中清偿。这是我学到的工程习惯:不装懂

- 检索质量:3 个测试问题 top-1 全部命中(相似度 0.66 / 0.77 / 0.73)

- API 成本:不到 1 毛(约 0.02~0.05 元,口径:按未命中缓存计费估算)

下一步

- v1:检索质量优化——混合检索(关键词 + 向量)、Rerank、加评测(Recall@k、Faithfulness)

- v2:多模态——图像索引 + VLM 问答

- v3:服务化——FastAPI + Docker + 追踪

结尾

代码在 GitHub:github.com/huruxia/vis… 踩坑全集(DEBT.md):github.com/huruxia/vis…

感谢看完。有任何问题欢迎交流,尤其是分块策略和检索评测——那是 RAG 里最值得实验的部分。

本文由 AI图鉴自动抓取并翻译,版权归原作者所有;如需查看原文请点下方链接。

相关 AI 工具

相关免费羊毛

同源资讯

阅读原文(juejin.cn)

标题、摘要与正文均来自该信源的公开页面,版权归原作者所有;本站自动聚合与翻译,仅作出处跳转。

← 返回 AI 资讯列表AI工具图鉴首页

返回 AI图鉴首页 · 提交工具 · 商务合作 · 关于本站 · 590 款 AI 工具分类导航 · 每日 AI 热门项目与动态