源文件:chapter3/agentic-rag-for-user-memory/README.md 面向用户记忆评估的 Agentic RAG 一个教学项目,把检索增强生成(RAG)与用户记忆评估结合,展示 AI Agent 如何高效地管理与查询长期对话历史。 🎯 学习目标 本项目教你: 如何把长对话分块为可索引的可管理片段 如何对接外部检索流水线做混合搜索 如何用工具调用与 ReAct 模式实现 Agentic RAG 如何用自动化的 LLM 评分评估记忆系统 如何针对基于对话的查询优化检索 如何整合不同项目的评估框架 🏗️ 架构概览 📚 关键概念 对话分块 长对话历史被切成约 20 轮(user-assistant 交换)一块。
源文件:chapter3/agentic-rag-for-user-memory/README.md
一个教学项目,把检索增强生成(RAG)与用户记忆评估结合,展示 AI Agent 如何高效地管理与查询长期对话历史。
本项目教你:
┌─────────────────────────────────────────┐ │ User Memory Test Cases │ │ (60 test cases, 3 difficulty layers) │ └────────────────┬────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Conversation Chunker │ │ (Splits into 20-round segments with │ │ overlap and contextual enrichment) │ └────────────────┬────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ External Retrieval Pipeline │ │ (Port 4242 - Hybrid Search) │ │ ┌─────────────┐ ┌──────────────────┐ │ │ │Dense Search │ │ Sparse Search │ │ │ │ (Embeddings)│ │ (BM25) │ │ │ └─────────────┘ └──────────────────┘ │ └────────────────┬────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Agentic RAG Agent │ │ (ReAct pattern with memory tools) │ │ │ │ Tools: │ │ • search_memory │ │ • get_conversation_context │ │ • get_full_conversation │ └────────────────┬────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ LLM Evaluation System │ │ (Automatic scoring and reasoning) │ │ • Reward score (0.0-1.0) │ │ • Pass/Fail determination │ │ • Detailed reasoning │ └─────────────────────────────────────────┘
长对话历史被切成约 20 轮(user-assistant 交换)一块。这样让它们:
系统与一个外部检索流水线服务集成,提供:
Agent 遵循 ReAct(Reasoning + Acting)模式:
系统与 week2/user-memory-evaluation 集成,提供:
文本块会被增强:
retrieval_backend="auto":若外部流水线可达就用它,否则透明回退到--mode batch/interactive/demo)。--mode offline-demo)既不需要 API Key,也不需要 4242 端口的服务。# Enter the project cd chapter3/agentic-rag-for-user-memory # Install dependencies pip install -r requirements.txt # Setup environment variables cp env.example .env # Edit .env with your API keys
检索后端可通过 --backend(或 IndexConfig.retrieval_backend)选择:
| 取值 | 行为 |
|---|---|
auto |
默认 — 若 4242 端口流水线可达就用它,否则用本地 BM25 |
local |
始终使用内置离线 BM25 索引(无外部服务) |
pipeline |
始终使用 4242 端口上的外部检索流水线 |
若要用外部流水线(做稠密/混合嵌入 + 重排序),请先启动它:
# In a separate terminal (OPTIONAL) cd ../retrieval-pipeline python api_server.py # serves http://localhost:4242
# Offline comparison demo — NO API key, NO port 4242 needed. # Shows agentic multi-hop memory retrieval beating naive single-query recall, # on the multi-session layer2_01_multiple_vehicles case, with a metric table. python main.py --mode offline-demo python offline_demo.py # equivalent, standalone entry point python offline_demo.py --output results/offline_demo.json # also dump JSON # Test the system setup python test_pipeline.py # Run interactive mode python main.py # Quick demo with a simple test case (needs an LLM API key) python main.py --mode demo # Batch evaluation of a category (needs an LLM API key; --backend local stays offline) python main.py --mode batch --category layer1 --backend local
在 layer2_01_multiple_vehicles(用户拥有一辆已预约 Firestone 保养的 Honda Accord
和一辆未预约的 Tesla Model 3,相关信息分散在两次独立通话中)上运行python offline_demo.py,基于真实 BM25 检索的结果如下:
| 指标 | 朴素单查询 | agentic 多跳 |
|---|---|---|
| 发起的检索查询数 | 1 | 5 |
| 检索到的记忆块数 | 3 | 5 |
| 关键证据召回率 | 50% | 100% |
| 能否完全消歧并作答 | 否 | 是 |
朴素查询被 "schedule service" 关键词主导,漏掉了 Honda 预约确认块
(FS-447291)。Agentic 策略从首轮结果中发现第二辆车,针对每辆车发起聚焦的后续查询,
找回了缺失的证据。召回数字由实际检索计算得出,不是写死的。
main.py)--mode {interactive,batch,demo,offline-demo}、--category、--test-id、--query、--provider、--model、--index-mode {dense,sparse,hybrid}、--backend {auto,local,pipeline}、--top-k、--rounds-per-chunk、--store-path、--test-cases-dir、--output、--config。运行 python main.py --help 查看
(中文)说明。
交互界面提供以下选项:
# 1. Initialize the evaluator from config import Config from evaluator import UserMemoryEvaluator config = Config.from_env() evaluator = UserMemoryEvaluator(config) # 2. Load test cases test_cases = evaluator.load_test_cases(category="layer1") # 3. Evaluate a test case result = evaluator.evaluate_test_case("layer1_01_bank_account") # 4. Generate report report = evaluator.generate_report("results/evaluation_report.txt")
config.py 中的关键配置项:
# Chunking settings config.chunking.rounds_per_chunk = 20 # Rounds per chunk config.chunking.overlap_rounds = 2 # Overlapping rounds # Index settings config.index.mode = "hybrid" # dense, sparse, or hybrid config.index.enable_contextual = True # Add contextual enrichment # Agent settings config.agent.max_search_results = 5 # Results per search config.evaluation.max_iterations = 10 # Max ReAct iterations
测试用例遵循 user-memory-evaluation 框架的格式:
test_id:唯一标识category:难度层(layer1、layer2、layer3)title:描述性标题conversation_histories:要索引的历史对话user_question:要回答的问题evaluation_criteria:评估响应的标准expected_behavior:可选的预期 Agent 行为chunker.py)indexer.py)tools.py)search_memory:主搜索接口,带完整内容检索get_conversation_context:检索周围的块get_full_conversation:获取完整对话历史agent.py)evaluator.py)系统跟踪全面的指标:
问题:无论 top_k 设为多少都只得到 10 条结果
解决:检索流水线使用两个参数:
top_k:初始检索数(候选)rerank_top_k:最终结果数(你实际拿到的)系统现在会同时正确设置这两个参数,以尊重你请求的结果数。
问题:Agent 响应后没有自动评估
解决:确保你有:
问题:无法连接检索流水线
解决:这不再是致命错误——在 --backend auto(默认)下系统会记录一条
警告并回退到内置的本地 BM25 后端。如果你确实想用外部流水线:
cd ../retrieval-pipeline && python api_server.pyhttp://localhost:4242 上运行--backend local 显式强制离线模式本项目是 AI Agent 训练课程的一部分,用于教学目的。
week2/user-memory:基础用户记忆系统week2/user-memory-evaluation:评估框架week3/agentic-rag:原始 Agentic RAG 实现week3/contextual-retrieval:进阶检索技术本实验现已为其对话 LLM 支持通用 OpenRouter 回退。
MOONSHOT_API_KEY / KIMI_API_KEY / OPENAI_API_KEY / DOUBAO_API_KEY …)存在,行为不变。OPENROUTER_API_KEY,对话 LLM 会自动经 OpenRouter 路由(https://openrouter.ai/api/v1)。模型名会自动映射:gpt-*/o1-* → openai/…,claude-* → anthropic/claude-opus-4.8,kimi-* → moonshotai/kimi-k2.6,已含 / 的 id 保持原样,其他提供方原生 id(如 doubao-*)回退为 openai/gpt-5.6-luna。设置 OPENROUTER_MODEL 可强制指定 OpenRouter 模型 id。在 .env 中加入 OPENROUTER_API_KEY=... 即可启用(见 env.example)。