从零开始做一个AI Agent(七)检索系统:关键词检索、向量检索、query rewrite 和 rerank
2026/6/25 22:15:07 网站建设 项目流程

从零开始做一个 AI Agent:以 Java Web RAG 学习助手为例

本文是一套面向技术博客专栏的完整教程。它不是只讲概念,而是以当前项目为真实案例,从一个最小后端 API 出发,逐步扩展到课程资料知识库、RAG 问答、轻量级 Agent Harness、工具注册表、执行 Trace、答案校验、学习记忆和前端工作台。

示例项目定位:

面向 Java Web 课程资料的 RAG Agent 学习助手

用户可以上传课程课件、实验指导书、代码文件和配置文件。系统会解析资料、切块、建立检索索引;用户提交学习任务后,Agent 会判断任务类型、规划步骤、调用工具、生成回答、校验引用,并把执行过程展示给前端。


专栏总目录

  1. 项目总览:从普通问答到课程学习 Agent
  2. 技术栈和工程结构:FastAPI、Vue、SQLite、RAG、Agent Harness
  3. 后端基础设施:配置、数据库、模型和 Schema
  4. 资料上传:文件存储、文档记录和重建索引
  5. 文档解析:PDF、Word、PPT、Markdown、代码文件如何进入系统
  6. 文本切块:chunk、metadata、语义类型和 embedding 状态
  7. 检索系统:关键词检索、向量检索、query rewrite 和 rerank
  8. LLM 与 Embedding Provider:stub、OpenAI-compatible API 和本地模型接入
  9. Chat 问答入口:兼容普通问答,同时接入 Agent 主链路
  10. Agent Harness:一次 Agent run 的生命周期
  11. Planner、Executor 与 Tool Registry:Agent 如何规划和调用工具
  12. Agent 校验、安全边界与资料不足处理
  13. Agent 记忆:短期上下文、长期学习画像和推荐下一步
  14. 前端工作台:资料管理、Agent 任务、Trace、历史和健康状态
  15. 测试、局限和演进:从教学项目走向生产级 Agent SaaS

第 7 篇:检索系统:关键词检索、向量检索、query rewrite 和 rerank

7.1 检索入口

文件:

backend/app/services/retrieval.py

核心函数:

defretrieve_chunks(question:str,top_k:int=5)->list[RetrievedChunk]:

整体流程:

question -> rewrite_retrieval_queries -> keyword scoring -> vector search -> merge ranked chunks -> rerank_chunks_with_llm -> top_k

7.2 RetrievedChunk

检索结果使用RetrievedChunk,包含:

chunk_id document_id content source_title source_path source_page language score retrieval_source

retrieval_source用于区分:

keyword vector

7.3 中文和代码友好的 tokenize

token 规则:

TOKEN_RE=re.compile(r"[A-Za-z0-9_]+|[\u4e00-\u9fff]+",re.UNICODE)

它能同时处理:

LoginServlet doPost web.xml Servlet 生命周期 登录流程

中文会拆成单字和 bigram,英文和代码标识符会转小写。

7.4 LLM query rewrite

rewrite_retrieval_queries会把原始问题改写为更适合检索的查询。

例如:

原问题:登录功能为什么跳转失败? 可能改写: 1. 登录 跳转 失败 2. LoginServlet doPost redirect 3. web.xml servlet mapping 4. session login error

如果 LLM 不可用,就返回原始问题作为 fallback。

7.5 关键词检索

关键词检索会对每个 chunk 计算 overlap:

query tokens vs content tokens + source_path tokens + metadata tokens

得分:

len(overlap) / sqrt(content_token_count)

这个公式避免长文本天然得分过高。

7.6 向量检索

文件:

backend/app/services/vector_store.py

向量检索流程:

问题 -> embedding -> 遍历已 embedded chunks -> cosine_similarity -> 按分数排序

当前向量存在 SQLite 的 JSON 字段里。按照路线B实现,这适合教学和小规模 MVP,不适合大规模生产。

路线 A:专用向量库(pgvector / Milvus / Chroma)
PostgreSQL + pgvector:专门加了 vector 类型字段,数据库原生支持向量相似度计算(余弦、欧氏距离),SQL 里直接 ORDER BY embedding <-> ‘[…]’ 做检索,数据库底层优化向量索引,适合百万级以上向量。向量 + 元数据统一持久化,数据库层内置向量索引与相似度计算。
路线 B:SQLite 存 JSON 向量,SQLite JSON 方案是全量拉取向量到 Python 内存,代码里手动算相似度;检索逻辑全在 Python 代码:全量 / 过滤后取出所有向量,loads 转数组,numpy 手动算余弦相似度;
路线 C:FAISS 向量检索库(内存索引,配套外部数据库存业务数据);代表:faiss(搭配 SQLite/PostgreSQL 做元数据存储);核心特点:只做高速向量计算,不负责持久化、不存业务元数据。

  • 小规模 demo:SQLite / Numpy
  • 中等 RAG 应用:Chroma
  • 大规模高性能向量检索:FAISS / Milvus / Qdrant

7.7 LLM rerank

混合检索后会把候选 chunk 交给 LLM rerank:

question candidates -> LLM 返回 chunk_ids 顺序

如果 LLM 不可用或返回无效 JSON,就使用原始排序。

7.8 为什么这个检索设计适合课程 Agent

课程资料同时包含自然语言和代码。纯向量检索可能漏掉精确类名,纯关键词检索又不理解语义。混合检索能同时照顾:

课程概念 实验步骤 代码文件 配置文件 报错信息 复习题线索

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询