用 AI 写规格、国内大模型做推理:一百块能否搭出生产级 RAG?
天涯轩 · 人人都是产品经理 · 2026-05-30 · 约 4600 字
基本信息
| 项目 | 内容 |
|---|---|
| 作者 | 天涯轩 |
| 发布平台 | 人人都是产品经理 |
| 发布日期 | 2026-05-30 |
| 字数 | 约 4600 字 |
| 主题 | RAG 生产级系统搭建实战 |
核心观点
-
100 元人民币搭出生产级 RAG 平台:Claude Code 生成方案与代码 + 通义千问提供推理与向量,全链路 API 花费约 100 元。包含多格式文档入库、Milvus 混合检索、LangGraph 十节点状态机、评测面板与企业级前端。成本参考意义在于 API 费用透明可预估,但需叠加人力调试与基础设施成本。
-
规格驱动 + AI 生成的两段式开发有效:先用 Claude Code 输出约 440 行的实现方案文档(hashed-gliding-metcalfe.md),再按方案逐模块生成 Monorepo 代码。规格驱动使 Monorepo 结构、LangGraph 节点与 API 边界在第一天就清晰,减少”写到哪算哪”的架构漂移。
-
真正的敌人是静默失败:14 个 Bug 中最耗时的不是 npm 404 或端口占用,而是检索 0 条、配置被忽略、维度 silently mismatch——它们共同特点是系统不报错。Bug 分布:SDK 参数不兼容 3 个、参数不匹配 3 个、配置/路径问题 3 个、逻辑 Bug 3 个、环境问题 2 个。
-
Embedding 模型输出维度必须与向量库 Schema 完全一致:通义千问 text-embedding-3-large 实际输出 1024 维,若 Schema 按 OpenAI 默认写成 3072 维,Milvus 可能仍能插入但检索静默返回 0 条——这是全文最隐蔽的故障。变更模型后必须重建集合。
-
不同 Embedding 模型的 COSINE 分数分布差异巨大,不能照搬海外模型阈值:通义 v3 直接 search Top5 分数仅 0.26–0.45,若参照 OpenAI 经验设定阈值 0.7 则全部被过滤。正确做法是默认阈值降至 0.2,或由 Rerank + Grade 节点承担质量控制,而非在 retrieve 阶段过早硬过滤。
-
LangChain 国内 API 接入必须用
configuration.baseURL而非baseUrl:@langchain/openai对两种写法处理不一致,baseUrl会被忽略导致请求打到 api.openai.com,表现为”日志显示成功、检索却无结果”。ChatOpenAI 与 OpenAIEmbeddings 均需使用configuration: { baseURL: '...' }。 -
生产 RAG 需要闭环:分类→HyDE→检索→Rerank→压缩→生成→评估→重写:LangGraph 十节点状态机实现查询分类(factual/comparative/general)→ 分解或改写 → HyDE 假设文档 → 混合检索 → Rerank → 压缩 → 生成 → 评估,评估不通过可回退重写形成可调优闭环,而非一次性黑盒。
-
故障排查四层策略(可复用):按层自下而上隔离——存储层(Milvus count / PostgreSQL 一致性)→ 向量层(sample vector length / 索引存在性)→ API 层(独立脚测 Base URL / 延迟 / 维度)→ 管道层(retrieve 条数与 score / 阈值与 Rerank)。对比测试用 A/B 两个最小脚本一锤定音。
实操内容保留
环境配置样例
LLM_BASE_URL: https://dashscope.aliyuncs.com/compatible-mode/v1
LLM_MODEL: qwen3.6-plus
EMBEDDING_MODEL: text-embedding-v3(百炼兼容接口)
EMBEDDING_DIMENSION: 1024
DATABASE_URL: PostgreSQL 连接串(Monorepo 根目录.env,非 packages/backend/.env)LangChain 正确配置 vs 错误配置
// ✅ 正确:configuration.baseURL
new OpenAIEmbeddings({
model: 'text-embedding-v3',
apiKey: 'sk-…',
configuration: { baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1' },
dimensions: 1024,
});
// ❌ 错误:baseUrl 会被忽略,请求打到 api.openai.com,超时或异常
new OpenAIEmbeddings({ baseUrl: 'https://dashscope.aliyuncs.com/…' });Milvus 集合字段样例
集合名: rag_chunks
主键 id: VarChar
document_id: VarChar(分区键)
dense_vector: FloatVector(dim = 1024,必须与 Embedding 实际输出一致)
sparse_vector: SparseFloatVector(BM25)
metadata: JSON(含 headerPath、section_title 等)Milvus 索引创建规则
index_type: IVF_FLAT
metric_type: COSINE
params: 必须传对象 { nlist: 1024 }
⚠️ 不能 JSON.stringify 给 extra_params,否则 Go 后端反序列化失败,索引静默未建LangGraph 十节点查询路由
classify(查询分类)
→ factual / comparative → decompose(子问题分解)→ retrieve
→ general / other → rewrite → 可选 HyDE(生成假设文档)→ retrieve
retrieve 后统一:
→ rerank → compress → generate → evaluate
evaluate 结果:
→ pass / ambiguous → format → END
→ fail 且未超重试次数 → rewrite → 回到检索链路
约束:节点名不得与 RAGState 字段同名(如 grade 节点需改名为 evaluate)对照自查清单(10 项)
- Embedding 维度:向量模型实际输出几维?Milvus Schema dim 必须一致,变更后支持重建集合
- API 兼容写法:LangChain 版本下国内 Base URL 怎么传?用
configuration.baseURL,独立脚本验证 - 相似度阈值:COSINE 分数在自家语料上的分布区间?可配置阈值,retrieve 勿过早硬过滤
- Milvus 索引:索引参数格式是否与 SDK 版本匹配?params 传对象,启动时检查索引是否存在
- 环境变量路径:Monorepo 子包从哪里读.env?显式 resolve 根目录路径,变量名与 Zod Schema 一致
- 入库幂等:上传一次写几条文档记录?路由创建 documentId,服务层只更新状态不重复 insert
- LangGraph 命名:节点名是否与 State 字段冲突?编译期可报错,命名规范 review
- 前端样式链:Tailwind 大版本升级插件是否注册?Vite 中 @tailwindcss/vite
- 开发代理:multipart 上传走不走 dev proxy?生产直连后端,开发期可用 curl/Postman 绕过
- 进程管理:热重载是否残留占用端口?重启前释放 3000 端口,或文档化 kill 命令
关键概念
- RAG 知识库:检索增强生成,系统核心架构
- LangGraph:十节点状态机 RAG 管道的编排框架
- Milvus:稠密+BM25 稀疏混合索引向量数据库
- 通义千问:对话模型 qwen3.6-plus + 向量模型 text-embedding-3-large
- Embedding 嵌入:向量维度一致性是生产 RAG 最隐蔽的故障源
- Claude Code:规格驱动开发中生成方案文档与代码的工具
- HyDE(Hypothetical Document Embeddings):假设文档嵌入,提升检索召回的技术
不同素材的关联
- 与 2026-05-27-通过codex解析Agent工作流程 的 RAG 三大核心问题(知识过时/记忆限制/幻觉)形成互补——Grace 的文章讲 RAG 是什么、为什么需要,本文讲 RAG 怎么搭、踩了哪些坑
- 与 2026-05-21-woshipm-ai-knowledge-base-product-design 的 AI 知识库产品设计形成”产品设计→工程实现”的递进关系
- 与 2026-05-28-woshipm-llm-wiki-qmd-architecture 的 qmd 四层架构形成”RAG 工程实践 vs 知识编译实践”的两种路径对比
- 与 2026-05-26-智能客服MVP三件事 的通义千问选型视角互补——嘻嘻李将通义千问用于 NLU 层,本文将其用于对话+向量全链路
原文精彩摘录
本次实验的目标因此很明确:不是做一个能跑通的 Demo,而是实测从零完成一套带评测与可观测性的 RAG 平台,究竟消耗多少 Token、会遇到哪些典型故障。开发方式采用「先写规格、再生成代码」:Claude Code 产出施工蓝图 hashed-gliding-metcalfe.md,再据此生成 Monorepo、Docker、前后端与 LangGraph 流水线;模型侧统一走阿里百炼 OpenAI 兼容接口。
若 Schema 按 OpenAI 默认写成 3072 维,而实际 API 返回 1024 维,Milvus 可能仍能插入但检索静默返回 0 条——这是本次实验中最耗时的隐蔽故障之一。
14 个 Bug 里,最耗时的不是 npm 404 或端口占用,而是检索 0 条、配置被忽略、维度 silently mismatch——它们共同特点是系统不报错。生产 RAG 的上限,往往由 Embedding 兼容性、向量库 Schema、阈值与评测闭环决定,而不是 Prompt 写得多漂亮。
不同 Embedding 模型的 COSINE 分数分布差异很大,不能照搬海外模型的阈值;上线前必须用独立脚本测自家模型的分数区间。