给 Agent 加一个可靠的知识检索层从向量引擎到 RAG 工作流的实践笔记最近做 AI 应用时越来越容易遇到一个问题模型本身很强但一进入真实业务场景就开始“不知道”。它能解释代码也能写总结还能把一段接口文档改写成很自然的说明。但如果问它“这个接口现在还能不能用”“这条业务规则是不是最新版”“这个问题之前有没有处理过”“这个 Agent 调工具前应该先查哪些资料”模型往往不能直接回答。原因很简单模型并不知道项目里的内部文档、历史变更、业务规则、客户记录、代码仓库和团队约定。这也是很多 Agent 项目从 Demo 到落地时会卡住的地方。Demo 阶段只要模型能回答、能调用工具、能生成内容就已经很有演示效果。但落地阶段真正麻烦的是上下文。Agent 不是只会聊天它可能要读取资料、调用接口、生成报告、写代码、创建工单甚至执行多步骤任务。如果它在没有查资料的情况下直接行动就很容易出现“看起来很智能实际上很冒险”的情况。所以本文不讨论哪个模型更强也不讨论模型价格而是从工程角度梳理一个更基础的问题如何给 Agent 加一层可用的向量检索能力让它在回答和执行前先找到可靠上下文。这个问题看起来朴素但它是很多 AI 应用能不能稳定落地的关键。1. 为什么模型调用不是完整的 AI 应用很多 AI 应用的第一步都是从调用模型开始。一个最简单的请求大概是这样constresponseawaitclient.chat.completions.create({model:some-model,messages:[{role:system,content:你是一个技术助手},{role:user,content:解释一下 RAG 是什么}]})这段代码可以跑通也可以很快做出一个聊天页面。但问题是这只是模型调用不是完整的业务系统。如果用户问的是通用问题模型可以基于已有知识回答。但如果用户问的是内部业务问题模型就需要额外资料。比如“订单接口的 item_id 字段还能不能用”“新同事为什么进组后看不到项目”“客户投诉两次后是否需要升级处理”“这个服务上线前需要跑哪些测试”这些问题都不是模型凭通用知识就能稳定回答的。它需要知道内部文档、版本变化、权限规则、工单流程和历史记录。如果直接把问题丢给模型模型可能会生成一段很流畅的回答。但流畅不等于可靠。很多时候模型最危险的地方不是不会说而是把不确定的内容说得像真的。因此一个稍微严肃一点的 AI 应用不能只做“问题 - 模型 - 答案”这条链路。它至少还需要一层知识检索用户问题 - 检索相关资料 - 过滤与排序 - 模型基于资料回答 - 返回答案和来源。这就是 RAG 的基本思路。2. Agent 为什么更需要检索层普通问答系统答错了用户可能重新问一次。Agent 答错了可能会继续执行。这就是 Agent 与普通聊天机器人的区别。Agent 可能会读取文件。调用接口。生成代码。修改配置。创建工单。总结会议。生成客户回复。调用内部工具。执行多步骤流程。一旦 AI 从“回答”变成“行动”上下文的重要性就会上升。比如一个代码 Agent在修改某个模块前如果没有检索 README、设计文档、历史 PR 和测试规范就可能改掉一个兼容逻辑。比如一个客服 Agent在回复客户前如果没有查最新售后政策和历史工单就可能给出错误承诺。比如一个数据 Agent在生成分析报告前如果没有查指标口径就可能用错字段。这些问题不是靠一句“请谨慎回答”就能解决的。需要系统设计让 Agent 形成一套固定流程先判断是否需要资料。需要资料时调用检索工具。检索结果不足时继续查或提示不确定。资料存在冲突时不要强行下结论。涉及操作时先给出计划并等待确认。执行结果要可追踪。这套流程里向量引擎就是关键的一层。它不负责替模型思考但负责给模型提供可用上下文。3. 向量引擎在系统里做什么向量引擎的核心作用是把非结构化资料变成可以语义检索的知识片段。企业或项目里的资料通常很分散接口文档。产品说明。FAQ。Markdown 文档。PDF。代码注释。提交记录。历史 PR。客服工单。会议纪要。运营复盘。内部规范。这些内容如果只放在文件夹里模型是不会自动知道的。需要先把它们解析、切分、向量化再建立索引。当用户提问时系统把问题也转换成向量然后在向量引擎里查找语义相近的片段。比如文档里写的是“权限继承策略”用户问的是“为什么新同事看不到项目”关键词可能不完全一致但语义上是相关的。这就是向量检索相比普通关键词搜索的价值。不过只做向量召回还不够。因为“相似”不等于“正确”。一段旧文档可能和问题很相似但已经过期。一段会议纪要可能提到了某个规则但不是正式文档。一段内部资料可能很相关但当前用户没有权限查看。所以向量引擎往往要配合 metadata、权限过滤、版本控制、重排和引用来源一起使用。一个可用的检索层不只是返回相似文本而是返回“当前场景下可以使用的资料”。4. 文档切分不要只按字数很多 RAG 系统效果不好第一步就出在文档切分。最简单的切分方式是按固定长度比如每 800 字切一段。这种方式容易实现但不一定适合业务文档。比如一段接口文档## 创建订单接口 POST /api/orders ### 请求参数 - user_id用户 ID - sku_id商品 ID - count数量 ### 注意事项 旧字段 item_id 已不再推荐使用。新版本请使用 sku_id。如果切分时把“接口名”和“注意事项”切开用户问“item_id 还能不能用”时系统可能召回不到接口背景。更合理的方式是尽量保留语义结构。一个片段里最好包含当前标题。上级标题。正文内容。来源路径。更新时间。文档类型。这样模型拿到片段时不只是看到一句话还知道这句话属于哪份资料、哪个章节、哪个版本。对于代码文档还可以按函数、类、模块切分。对于 FAQ可以把问题和答案放在同一个片段里。对于规范文档可以按章节切分。对于会议纪要可以按议题切分。切分策略没有唯一标准关键是让召回结果保持完整语义。5. metadata 是知识片段的身份证如果只存文本和向量系统很快会遇到问题。比如用户问“退款规则”系统召回了一段三年前的旧政策因为语义很相似。用户问“接口字段”系统召回了一段废弃版本说明。用户问“客户处理流程”系统召回了一段当前用户无权查看的内部资料。这些问题都需要 metadata 参与处理。一个知识片段可以长这样{id:chunk_001,text:旧字段 item_id 已不再推荐使用。新版本请使用 sku_id。,metadata:{source:docs/api/order.md,title:创建订单接口,doc_type:api_doc,version:v3,updated_at:2026-05-12,status:active,permission:internal,owner:backend-team}}这些字段的作用很直接。source用于引用来源。doc_type用于限定资料类型。version用于判断版本。updated_at用于处理新旧资料。status用于过滤废弃文档。permission用于权限控制。owner用于后续追踪维护责任。metadata 不一定一开始就设计得很复杂但不能完全没有。没有 metadata 的知识库就像没有目录和标签的资料室。东西确实都在但很难保证每次拿出来的都是对的。6. 检索之后还需要过滤和重排很多 Demo 会这样写constresultsawaitvectorSearch(query,{topK:5})constanswerawaitllmGenerate(query,results)这能跑但在真实场景里不够稳。检索结果通常需要经过几层处理。第一层是权限过滤。当前用户没有权限看的内容不应该进入模型上下文。第二层是状态过滤。已经废弃或过期的内容不应该作为最终依据。第三层是去重。同一段内容可能在多个文档里重复出现需要合并或去掉重复片段。第四层是重排。向量相似度最高的片段不一定是最适合回答问题的片段。可以使用 rerank 或规则重新排序。第五层是置信度判断。如果召回结果都不够相关系统应该提示资料不足而不是强行回答。这些步骤看起来会增加复杂度但它们是生产系统必须考虑的。很多 RAG 系统答错不是因为没有搜到东西而是搜到了一堆相似但不能用的东西。7. 答案必须尽量带来源在个人使用 AI 时很多人只看答案是否顺眼。但在工程场景里来源非常重要。用户不仅想知道“答案是什么”还想知道“答案来自哪里”。例如旧字段 item_id 已不再推荐使用。当前建议使用 sku_id 作为商品标识。 来源 - docs/api/order.md - 章节创建订单接口 - 更新时间2026-05-12这样的回答更容易被信任也更容易排查问题。如果答案错了可以回查是文档错了是检索错了是重排错了还是模型理解错了如果答案没有来源排查会非常困难。所以在设计 RAG 系统时不要只追求回答自然也要考虑可追踪性。可追踪性是从 Demo 走向生产的重要标志。8. 一个最小可用流程下面是一个简化版流程适合用来理解整体结构。typeChunk{id:stringtext:stringmetadata:{source:stringtitle:stringupdatedAt:stringpermission:stringstatus:active|deprecated}}asyncfunctionretrieve(query:string,userRole:string){constrawResultsawaitvectorSearch(query,{topK:20})constfilteredrawResults.filter(itemitem.metadata.statusactive).filter(itemcanAccess(userRole,item.metadata.permission))constrerankedawaitrerank(query,filtered)returnreranked.slice(0,5)}asyncfunctionanswer(query:string,userRole:string){constchunksawaitretrieve(query,userRole)if(chunks.length0){return{answer:当前资料不足无法给出可靠结论。,sources:[]}}constcontextchunks.map((c,i)[${i1}]${c.text}\n来源${c.metadata.source}).join(\n\n)constprompt请只基于给定资料回答。 如果资料不足请明确说明不确定。 回答后列出来源。 用户问题${query}资料${context}returnllmGenerate(prompt)}这段代码只是示意真实项目里还会有更多细节比如查询改写、多路召回、缓存、日志、错误处理、用户反馈等。但核心思想不变先检索。再过滤。再生成。再引用。9. Agent 如何使用检索工具Agent 使用检索工具时不应该每次都无脑调用也不应该完全不调用。可以按照问题类型判断。如果用户只是让它改写一句话可能不需要检索。如果用户问业务规则、接口状态、历史处理、客户情况就应该检索。如果用户要求执行操作比如发送消息、修改状态、提交代码就应该先检索相关规则再给出操作计划。一个简化流程如下用户输入 ↓ 判断任务类型 ↓ 是否需要外部知识 ↓ 需要调用检索工具 ↓ 检查资料是否足够 ↓ 足够生成答案或计划 ↓ 不足继续检索或提示不确定 ↓ 涉及执行等待确认这样 Agent 的行为会更像一个谨慎的工程助手。它不是拿到任务就开始动手而是先查资料。这很朴素但很重要。10. 先用小场景验证不要一上来导入所有资料很多团队做知识库时一开始就想把所有文档都导进去。这通常不是好主意。资料越多问题越复杂。旧文档更多。重复内容更多。权限更乱。评估更困难。如果前期链路还没跑通大规模导入只会把问题放大。更稳的方式是先选一个小场景。比如接口文档问答。内部 FAQ 检索。项目 README 检索。售后政策问答。运营复盘查询。准备几十份低敏资料设计二十个真实问题先验证检索和引用是否稳定。如果需要一个在线环境做小范围复现实验可以使用这个地址https://178.nz/awa第一轮建议只验证三件事能否召回正确资料。能否引用来源。资料不足时是否会停止编造。如果这三件事不稳定就不要急着扩大数据量。11. 如何评估检索效果不要只靠感觉。“感觉答得不错”是最容易误导人的。可以准备一个小型评估集。例如问题item_id 字段还能不能用 理想来源docs/api/order.md 问题新同事为什么看不到项目 理想来源docs/auth/permission.md 问题客户投诉两次后是否需要升级 理想来源docs/support/escalation.md然后观察正确来源是否被召回。正确来源是否排在前面。答案是否真的基于来源。是否引用了过期文档。是否在资料不足时拒答。不同权限用户是否看到不同结果。这些指标比单纯看模型回答更有意义。因为 RAG 系统的问题可能出现在多个环节文档解析。文本切分。向量化。检索。过滤。重排。生成。引用。如果没有评估集就只能靠猜。今天改 topK明天改 chunk size后天换 embedding 模型最后到底有没有变好很难判断。工程系统不应该靠玄学调参。12. 长上下文不能完全替代向量引擎现在很多模型上下文越来越长于是有人会问既然模型能读很多内容还需要向量引擎吗需要。因为长上下文解决的是“能放多少”向量引擎解决的是“该放什么”。把所有资料都塞进模型不一定是好方法。不同用户权限不同。不同任务需要不同资料。旧文档和新文档需要区分。无关内容太多会干扰模型。长上下文也会带来成本和延迟。更合理的方式是先检索再阅读。向量引擎负责从大量资料里筛出最相关、最可信、最适合当前用户的片段。模型负责理解这些片段并生成答案。两者是配合关系不是替代关系。模型上下文越长前置筛选反而越重要。13. 多模态场景也需要知识检索向量引擎不只适合文本问答。多模态场景同样需要知识检索。比如图像生成。如果只是生成一张好看的图片模型能力很重要。但如果要生成符合业务要求的图片就需要上下文。品牌色是什么字体规范是什么产品卖点是什么哪些元素不能出现历史素材是什么风格投放平台有什么要求目标用户是谁这些信息如果不提供给模型生成结果可能看起来很好但业务上不能用。未来的多模态工作流很可能是先检索品牌资料。再检索历史素材。再读取产品说明。再生成图像方案。再根据反馈调整。这依然需要向量引擎参与。所以越是复杂的 AI 应用越不能只依赖模型本身。14. 模型接入层和知识层要分开很多系统会把模型接入和知识检索混在一起看。其实它们是两个层级。模型接入层解决的是怎么调用模型。怎么管理 key。怎么切换模型。怎么统计成本。怎么记录调用日志。知识检索层解决的是模型回答前应该看什么资料。哪些资料能被当前用户看到。哪些资料已经过期。答案来自哪里。检索结果是否足够可靠。这两个层级都重要但不能互相替代。有模型接入层不代表有知识能力。有向量引擎也不代表不需要模型调用。更合理的架构是模型层可以替换。知识层持续沉淀。今天使用这个模型明天换另一个模型但文档、索引、metadata、评估集和权限规则应该继续复用。这才是长期建设 AI 应用的方式。15. Agent 记忆不能等于聊天记录很多人做 Agent memory会把所有聊天记录都存下来。这不叫长期记忆。这叫日志。日志有用但不能直接当记忆。真正有价值的记忆是未来任务可复用的信息。比如用户偏好先看结论。某个接口已经废弃。某个模块修改后必须跑集成测试。某个客户需要特殊审批。某个指标口径在 2026 年调整过。某类问题需要人工确认。这些信息可以沉淀成长期记忆。但一次临时对话、一次中间推理、一次工具返回不一定都应该进入长期记忆。如果什么都记Agent 会越来越混乱。如果记错了错误会被长期放大。如果旧记忆不失效系统会一直引用过期经验。所以 Agent memory 也需要治理。什么该记谁能看什么时候用什么时候过期如何纠错这些问题都需要设计。向量引擎可以帮助存储和召回记忆但不能替代记忆策略。16. 普通开发者应该补哪些能力如果想做 AI 应用不建议只学 prompt。prompt 有用但它只是入口。更值得补的是这些工程能力文档解析。文本切分。向量检索。metadata 设计。权限过滤。答案引用。检索评估。Agent 工具调用。key 管理。日志审计。上下文压缩。长期记忆治理。这些能力看起来没有“神级提示词”那么吸引眼球但更接近真实项目。未来 AI 应用不只需要会用模型的人更需要能让模型稳定进入业务的人。会调用模型的人很多。会让模型基于正确资料回答的人少。会让 Agent 调工具的人很多。会让 Agent 调工具前先查资料的人少。机会往往就在这些不那么热闹的基础能力里。17. 一个可执行的学习路线如果从零开始可以按这个顺序练习第一步选一个小场景。比如接口文档问答。第二步准备资料。选 20 到 50 份低敏文档。第三步做切分。保留标题、来源、更新时间。第四步写入向量引擎。每个片段带 metadata。第五步实现检索。先做 topK再做过滤和重排。第六步接模型生成。要求只基于资料回答并附来源。第七步做评估集。准备 20 个真实问题标注理想来源。第八步引入 Agent。让 Agent 判断是否需要检索资料不足时停止回答。第九步加入权限。不同用户看到不同范围的资料。第十步加入更新机制。旧文档失效新文档生效。这条路线不复杂但很扎实。做完一遍后会比只看概念文章更理解 RAG 和 Agent 的真实问题。18. 常见问题总结第一个问题为什么检索到了内容答案还是错可能是召回内容相似但不适用也可能是旧文档没有过滤还可能是模型误解了上下文。第二个问题为什么文档越多效果反而越差可能是重复资料、过期资料、低质量资料太多。数据量增加前应该先建立评估和治理机制。第三个问题为什么模型上下文很长仍然需要检索因为上下文长度不等于资料选择能力。先筛选再阅读更稳定。第四个问题为什么答案必须有来源因为没有来源就很难排查也很难建立用户信任。第五个问题为什么 Agent 要先查资料因为 Agent 可能会行动。行动前没有依据风险比普通问答更高。19. 写在最后AI 应用正在从“模型调用”进入“上下文工程”。模型越来越强Agent 越来越能干多模态能力也越来越成熟。但越是这样越不能忽视底层问题模型根据什么回答Agent 根据什么行动答案来自哪里资料是否最新用户是否有权限系统能否评估和追踪向量引擎的价值就在这些问题里。它不是为了让架构看起来复杂而是为了让 AI 应用更可控。一个可用的 AI 系统不应该只是模型直连。它应该能检索资料能过滤权限能引用来源能处理旧文档能在资料不足时停止编造能让 Agent 行动前先查清楚。模型负责生成。Agent 负责执行。向量引擎负责提供可靠上下文。当 AI 从聊天框走向真实工作流这层上下文底座会越来越重要。AI 应用的下半场拼的不是谁的 prompt 更长而是谁的上下文更可靠。
给 Agent 加一个可靠的知识检索层:从向量引擎到 RAG 工作流的实践笔记
发布时间:2026/5/20 10:57:25
给 Agent 加一个可靠的知识检索层从向量引擎到 RAG 工作流的实践笔记最近做 AI 应用时越来越容易遇到一个问题模型本身很强但一进入真实业务场景就开始“不知道”。它能解释代码也能写总结还能把一段接口文档改写成很自然的说明。但如果问它“这个接口现在还能不能用”“这条业务规则是不是最新版”“这个问题之前有没有处理过”“这个 Agent 调工具前应该先查哪些资料”模型往往不能直接回答。原因很简单模型并不知道项目里的内部文档、历史变更、业务规则、客户记录、代码仓库和团队约定。这也是很多 Agent 项目从 Demo 到落地时会卡住的地方。Demo 阶段只要模型能回答、能调用工具、能生成内容就已经很有演示效果。但落地阶段真正麻烦的是上下文。Agent 不是只会聊天它可能要读取资料、调用接口、生成报告、写代码、创建工单甚至执行多步骤任务。如果它在没有查资料的情况下直接行动就很容易出现“看起来很智能实际上很冒险”的情况。所以本文不讨论哪个模型更强也不讨论模型价格而是从工程角度梳理一个更基础的问题如何给 Agent 加一层可用的向量检索能力让它在回答和执行前先找到可靠上下文。这个问题看起来朴素但它是很多 AI 应用能不能稳定落地的关键。1. 为什么模型调用不是完整的 AI 应用很多 AI 应用的第一步都是从调用模型开始。一个最简单的请求大概是这样constresponseawaitclient.chat.completions.create({model:some-model,messages:[{role:system,content:你是一个技术助手},{role:user,content:解释一下 RAG 是什么}]})这段代码可以跑通也可以很快做出一个聊天页面。但问题是这只是模型调用不是完整的业务系统。如果用户问的是通用问题模型可以基于已有知识回答。但如果用户问的是内部业务问题模型就需要额外资料。比如“订单接口的 item_id 字段还能不能用”“新同事为什么进组后看不到项目”“客户投诉两次后是否需要升级处理”“这个服务上线前需要跑哪些测试”这些问题都不是模型凭通用知识就能稳定回答的。它需要知道内部文档、版本变化、权限规则、工单流程和历史记录。如果直接把问题丢给模型模型可能会生成一段很流畅的回答。但流畅不等于可靠。很多时候模型最危险的地方不是不会说而是把不确定的内容说得像真的。因此一个稍微严肃一点的 AI 应用不能只做“问题 - 模型 - 答案”这条链路。它至少还需要一层知识检索用户问题 - 检索相关资料 - 过滤与排序 - 模型基于资料回答 - 返回答案和来源。这就是 RAG 的基本思路。2. Agent 为什么更需要检索层普通问答系统答错了用户可能重新问一次。Agent 答错了可能会继续执行。这就是 Agent 与普通聊天机器人的区别。Agent 可能会读取文件。调用接口。生成代码。修改配置。创建工单。总结会议。生成客户回复。调用内部工具。执行多步骤流程。一旦 AI 从“回答”变成“行动”上下文的重要性就会上升。比如一个代码 Agent在修改某个模块前如果没有检索 README、设计文档、历史 PR 和测试规范就可能改掉一个兼容逻辑。比如一个客服 Agent在回复客户前如果没有查最新售后政策和历史工单就可能给出错误承诺。比如一个数据 Agent在生成分析报告前如果没有查指标口径就可能用错字段。这些问题不是靠一句“请谨慎回答”就能解决的。需要系统设计让 Agent 形成一套固定流程先判断是否需要资料。需要资料时调用检索工具。检索结果不足时继续查或提示不确定。资料存在冲突时不要强行下结论。涉及操作时先给出计划并等待确认。执行结果要可追踪。这套流程里向量引擎就是关键的一层。它不负责替模型思考但负责给模型提供可用上下文。3. 向量引擎在系统里做什么向量引擎的核心作用是把非结构化资料变成可以语义检索的知识片段。企业或项目里的资料通常很分散接口文档。产品说明。FAQ。Markdown 文档。PDF。代码注释。提交记录。历史 PR。客服工单。会议纪要。运营复盘。内部规范。这些内容如果只放在文件夹里模型是不会自动知道的。需要先把它们解析、切分、向量化再建立索引。当用户提问时系统把问题也转换成向量然后在向量引擎里查找语义相近的片段。比如文档里写的是“权限继承策略”用户问的是“为什么新同事看不到项目”关键词可能不完全一致但语义上是相关的。这就是向量检索相比普通关键词搜索的价值。不过只做向量召回还不够。因为“相似”不等于“正确”。一段旧文档可能和问题很相似但已经过期。一段会议纪要可能提到了某个规则但不是正式文档。一段内部资料可能很相关但当前用户没有权限查看。所以向量引擎往往要配合 metadata、权限过滤、版本控制、重排和引用来源一起使用。一个可用的检索层不只是返回相似文本而是返回“当前场景下可以使用的资料”。4. 文档切分不要只按字数很多 RAG 系统效果不好第一步就出在文档切分。最简单的切分方式是按固定长度比如每 800 字切一段。这种方式容易实现但不一定适合业务文档。比如一段接口文档## 创建订单接口 POST /api/orders ### 请求参数 - user_id用户 ID - sku_id商品 ID - count数量 ### 注意事项 旧字段 item_id 已不再推荐使用。新版本请使用 sku_id。如果切分时把“接口名”和“注意事项”切开用户问“item_id 还能不能用”时系统可能召回不到接口背景。更合理的方式是尽量保留语义结构。一个片段里最好包含当前标题。上级标题。正文内容。来源路径。更新时间。文档类型。这样模型拿到片段时不只是看到一句话还知道这句话属于哪份资料、哪个章节、哪个版本。对于代码文档还可以按函数、类、模块切分。对于 FAQ可以把问题和答案放在同一个片段里。对于规范文档可以按章节切分。对于会议纪要可以按议题切分。切分策略没有唯一标准关键是让召回结果保持完整语义。5. metadata 是知识片段的身份证如果只存文本和向量系统很快会遇到问题。比如用户问“退款规则”系统召回了一段三年前的旧政策因为语义很相似。用户问“接口字段”系统召回了一段废弃版本说明。用户问“客户处理流程”系统召回了一段当前用户无权查看的内部资料。这些问题都需要 metadata 参与处理。一个知识片段可以长这样{id:chunk_001,text:旧字段 item_id 已不再推荐使用。新版本请使用 sku_id。,metadata:{source:docs/api/order.md,title:创建订单接口,doc_type:api_doc,version:v3,updated_at:2026-05-12,status:active,permission:internal,owner:backend-team}}这些字段的作用很直接。source用于引用来源。doc_type用于限定资料类型。version用于判断版本。updated_at用于处理新旧资料。status用于过滤废弃文档。permission用于权限控制。owner用于后续追踪维护责任。metadata 不一定一开始就设计得很复杂但不能完全没有。没有 metadata 的知识库就像没有目录和标签的资料室。东西确实都在但很难保证每次拿出来的都是对的。6. 检索之后还需要过滤和重排很多 Demo 会这样写constresultsawaitvectorSearch(query,{topK:5})constanswerawaitllmGenerate(query,results)这能跑但在真实场景里不够稳。检索结果通常需要经过几层处理。第一层是权限过滤。当前用户没有权限看的内容不应该进入模型上下文。第二层是状态过滤。已经废弃或过期的内容不应该作为最终依据。第三层是去重。同一段内容可能在多个文档里重复出现需要合并或去掉重复片段。第四层是重排。向量相似度最高的片段不一定是最适合回答问题的片段。可以使用 rerank 或规则重新排序。第五层是置信度判断。如果召回结果都不够相关系统应该提示资料不足而不是强行回答。这些步骤看起来会增加复杂度但它们是生产系统必须考虑的。很多 RAG 系统答错不是因为没有搜到东西而是搜到了一堆相似但不能用的东西。7. 答案必须尽量带来源在个人使用 AI 时很多人只看答案是否顺眼。但在工程场景里来源非常重要。用户不仅想知道“答案是什么”还想知道“答案来自哪里”。例如旧字段 item_id 已不再推荐使用。当前建议使用 sku_id 作为商品标识。 来源 - docs/api/order.md - 章节创建订单接口 - 更新时间2026-05-12这样的回答更容易被信任也更容易排查问题。如果答案错了可以回查是文档错了是检索错了是重排错了还是模型理解错了如果答案没有来源排查会非常困难。所以在设计 RAG 系统时不要只追求回答自然也要考虑可追踪性。可追踪性是从 Demo 走向生产的重要标志。8. 一个最小可用流程下面是一个简化版流程适合用来理解整体结构。typeChunk{id:stringtext:stringmetadata:{source:stringtitle:stringupdatedAt:stringpermission:stringstatus:active|deprecated}}asyncfunctionretrieve(query:string,userRole:string){constrawResultsawaitvectorSearch(query,{topK:20})constfilteredrawResults.filter(itemitem.metadata.statusactive).filter(itemcanAccess(userRole,item.metadata.permission))constrerankedawaitrerank(query,filtered)returnreranked.slice(0,5)}asyncfunctionanswer(query:string,userRole:string){constchunksawaitretrieve(query,userRole)if(chunks.length0){return{answer:当前资料不足无法给出可靠结论。,sources:[]}}constcontextchunks.map((c,i)[${i1}]${c.text}\n来源${c.metadata.source}).join(\n\n)constprompt请只基于给定资料回答。 如果资料不足请明确说明不确定。 回答后列出来源。 用户问题${query}资料${context}returnllmGenerate(prompt)}这段代码只是示意真实项目里还会有更多细节比如查询改写、多路召回、缓存、日志、错误处理、用户反馈等。但核心思想不变先检索。再过滤。再生成。再引用。9. Agent 如何使用检索工具Agent 使用检索工具时不应该每次都无脑调用也不应该完全不调用。可以按照问题类型判断。如果用户只是让它改写一句话可能不需要检索。如果用户问业务规则、接口状态、历史处理、客户情况就应该检索。如果用户要求执行操作比如发送消息、修改状态、提交代码就应该先检索相关规则再给出操作计划。一个简化流程如下用户输入 ↓ 判断任务类型 ↓ 是否需要外部知识 ↓ 需要调用检索工具 ↓ 检查资料是否足够 ↓ 足够生成答案或计划 ↓ 不足继续检索或提示不确定 ↓ 涉及执行等待确认这样 Agent 的行为会更像一个谨慎的工程助手。它不是拿到任务就开始动手而是先查资料。这很朴素但很重要。10. 先用小场景验证不要一上来导入所有资料很多团队做知识库时一开始就想把所有文档都导进去。这通常不是好主意。资料越多问题越复杂。旧文档更多。重复内容更多。权限更乱。评估更困难。如果前期链路还没跑通大规模导入只会把问题放大。更稳的方式是先选一个小场景。比如接口文档问答。内部 FAQ 检索。项目 README 检索。售后政策问答。运营复盘查询。准备几十份低敏资料设计二十个真实问题先验证检索和引用是否稳定。如果需要一个在线环境做小范围复现实验可以使用这个地址https://178.nz/awa第一轮建议只验证三件事能否召回正确资料。能否引用来源。资料不足时是否会停止编造。如果这三件事不稳定就不要急着扩大数据量。11. 如何评估检索效果不要只靠感觉。“感觉答得不错”是最容易误导人的。可以准备一个小型评估集。例如问题item_id 字段还能不能用 理想来源docs/api/order.md 问题新同事为什么看不到项目 理想来源docs/auth/permission.md 问题客户投诉两次后是否需要升级 理想来源docs/support/escalation.md然后观察正确来源是否被召回。正确来源是否排在前面。答案是否真的基于来源。是否引用了过期文档。是否在资料不足时拒答。不同权限用户是否看到不同结果。这些指标比单纯看模型回答更有意义。因为 RAG 系统的问题可能出现在多个环节文档解析。文本切分。向量化。检索。过滤。重排。生成。引用。如果没有评估集就只能靠猜。今天改 topK明天改 chunk size后天换 embedding 模型最后到底有没有变好很难判断。工程系统不应该靠玄学调参。12. 长上下文不能完全替代向量引擎现在很多模型上下文越来越长于是有人会问既然模型能读很多内容还需要向量引擎吗需要。因为长上下文解决的是“能放多少”向量引擎解决的是“该放什么”。把所有资料都塞进模型不一定是好方法。不同用户权限不同。不同任务需要不同资料。旧文档和新文档需要区分。无关内容太多会干扰模型。长上下文也会带来成本和延迟。更合理的方式是先检索再阅读。向量引擎负责从大量资料里筛出最相关、最可信、最适合当前用户的片段。模型负责理解这些片段并生成答案。两者是配合关系不是替代关系。模型上下文越长前置筛选反而越重要。13. 多模态场景也需要知识检索向量引擎不只适合文本问答。多模态场景同样需要知识检索。比如图像生成。如果只是生成一张好看的图片模型能力很重要。但如果要生成符合业务要求的图片就需要上下文。品牌色是什么字体规范是什么产品卖点是什么哪些元素不能出现历史素材是什么风格投放平台有什么要求目标用户是谁这些信息如果不提供给模型生成结果可能看起来很好但业务上不能用。未来的多模态工作流很可能是先检索品牌资料。再检索历史素材。再读取产品说明。再生成图像方案。再根据反馈调整。这依然需要向量引擎参与。所以越是复杂的 AI 应用越不能只依赖模型本身。14. 模型接入层和知识层要分开很多系统会把模型接入和知识检索混在一起看。其实它们是两个层级。模型接入层解决的是怎么调用模型。怎么管理 key。怎么切换模型。怎么统计成本。怎么记录调用日志。知识检索层解决的是模型回答前应该看什么资料。哪些资料能被当前用户看到。哪些资料已经过期。答案来自哪里。检索结果是否足够可靠。这两个层级都重要但不能互相替代。有模型接入层不代表有知识能力。有向量引擎也不代表不需要模型调用。更合理的架构是模型层可以替换。知识层持续沉淀。今天使用这个模型明天换另一个模型但文档、索引、metadata、评估集和权限规则应该继续复用。这才是长期建设 AI 应用的方式。15. Agent 记忆不能等于聊天记录很多人做 Agent memory会把所有聊天记录都存下来。这不叫长期记忆。这叫日志。日志有用但不能直接当记忆。真正有价值的记忆是未来任务可复用的信息。比如用户偏好先看结论。某个接口已经废弃。某个模块修改后必须跑集成测试。某个客户需要特殊审批。某个指标口径在 2026 年调整过。某类问题需要人工确认。这些信息可以沉淀成长期记忆。但一次临时对话、一次中间推理、一次工具返回不一定都应该进入长期记忆。如果什么都记Agent 会越来越混乱。如果记错了错误会被长期放大。如果旧记忆不失效系统会一直引用过期经验。所以 Agent memory 也需要治理。什么该记谁能看什么时候用什么时候过期如何纠错这些问题都需要设计。向量引擎可以帮助存储和召回记忆但不能替代记忆策略。16. 普通开发者应该补哪些能力如果想做 AI 应用不建议只学 prompt。prompt 有用但它只是入口。更值得补的是这些工程能力文档解析。文本切分。向量检索。metadata 设计。权限过滤。答案引用。检索评估。Agent 工具调用。key 管理。日志审计。上下文压缩。长期记忆治理。这些能力看起来没有“神级提示词”那么吸引眼球但更接近真实项目。未来 AI 应用不只需要会用模型的人更需要能让模型稳定进入业务的人。会调用模型的人很多。会让模型基于正确资料回答的人少。会让 Agent 调工具的人很多。会让 Agent 调工具前先查资料的人少。机会往往就在这些不那么热闹的基础能力里。17. 一个可执行的学习路线如果从零开始可以按这个顺序练习第一步选一个小场景。比如接口文档问答。第二步准备资料。选 20 到 50 份低敏文档。第三步做切分。保留标题、来源、更新时间。第四步写入向量引擎。每个片段带 metadata。第五步实现检索。先做 topK再做过滤和重排。第六步接模型生成。要求只基于资料回答并附来源。第七步做评估集。准备 20 个真实问题标注理想来源。第八步引入 Agent。让 Agent 判断是否需要检索资料不足时停止回答。第九步加入权限。不同用户看到不同范围的资料。第十步加入更新机制。旧文档失效新文档生效。这条路线不复杂但很扎实。做完一遍后会比只看概念文章更理解 RAG 和 Agent 的真实问题。18. 常见问题总结第一个问题为什么检索到了内容答案还是错可能是召回内容相似但不适用也可能是旧文档没有过滤还可能是模型误解了上下文。第二个问题为什么文档越多效果反而越差可能是重复资料、过期资料、低质量资料太多。数据量增加前应该先建立评估和治理机制。第三个问题为什么模型上下文很长仍然需要检索因为上下文长度不等于资料选择能力。先筛选再阅读更稳定。第四个问题为什么答案必须有来源因为没有来源就很难排查也很难建立用户信任。第五个问题为什么 Agent 要先查资料因为 Agent 可能会行动。行动前没有依据风险比普通问答更高。19. 写在最后AI 应用正在从“模型调用”进入“上下文工程”。模型越来越强Agent 越来越能干多模态能力也越来越成熟。但越是这样越不能忽视底层问题模型根据什么回答Agent 根据什么行动答案来自哪里资料是否最新用户是否有权限系统能否评估和追踪向量引擎的价值就在这些问题里。它不是为了让架构看起来复杂而是为了让 AI 应用更可控。一个可用的 AI 系统不应该只是模型直连。它应该能检索资料能过滤权限能引用来源能处理旧文档能在资料不足时停止编造能让 Agent 行动前先查清楚。模型负责生成。Agent 负责执行。向量引擎负责提供可靠上下文。当 AI 从聊天框走向真实工作流这层上下文底座会越来越重要。AI 应用的下半场拼的不是谁的 prompt 更长而是谁的上下文更可靠。