ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,251 @@
|
||||
# Contextual Retrieval System / 上下文感知检索系统
|
||||
|
||||
> Companion material for *AI Agents in Depth*, Chapter 3 — **Experiment 3-10**: Anthropic-style contextual prefixes before indexing; offline BM25 recall@k compare.
|
||||
> 配套《深入理解 AI Agent》第 3 章 **实验 3-10**:索引前为分块生成上下文前缀;离线 BM25 recall@k 对比。
|
||||
|
||||
← [Chapter 3 index / 返回第 3 章目录](../README.md)
|
||||
|
||||
---
|
||||
|
||||
## English
|
||||
|
||||
### Canonical live campaign
|
||||
|
||||
`python campaign.py` regenerates every prefix live from the full source
|
||||
document plus its target chunk, then compares the same 15 labeled queries over
|
||||
plain/contextual BM25, dense Qwen3 embeddings, and RRF hybrid indexes. It records
|
||||
recall@1/3/5, MRR, model revision, index-time usage/cost assumptions, source
|
||||
hashes, and raw ARK receipts in `validation/runs/<run-id>/`; the canonical
|
||||
pointer is `validation/latest.json`. `compare_retrieval.py` remains the small
|
||||
offline demonstration and is not accepted as the canonical live result.
|
||||
|
||||
### Overview
|
||||
|
||||
Educational implementation of Anthropic’s Contextual Retrieval: prepend chunk-specific context before embedding/indexing to fix the “orphaned chunk” problem.
|
||||
|
||||
### Key insight
|
||||
|
||||
**Problem:** Traditional RAG loses context when chunking. “The company’s revenue grew by 3%” is meaningless without which company / which period.
|
||||
|
||||
**Solution:** Generate short explanatory context per chunk and prepend it before indexing so BM25 and embeddings keep identity signals.
|
||||
|
||||
### Core offline experiment (Experiment 3-10)
|
||||
|
||||
`compare_retrieval.py` quantifies the claim **fully offline**: same chunks indexed two ways—plain (raw text only) vs contextual (LLM-generated prefix + text)—then compares `recall@k` on `evaluation/retrieval_eval.json` (15 queries + human gold chunks). **No API or retrieval service** (BM25 + jieba).
|
||||
|
||||
```bash
|
||||
python compare_retrieval.py
|
||||
python compare_retrieval.py --per-query
|
||||
python compare_retrieval.py --query "国家主席有哪些职权?" --top-k 5
|
||||
python compare_retrieval.py --mode plain
|
||||
python compare_retrieval.py --output result.json
|
||||
python compare_retrieval.py --help # Chinese help
|
||||
```
|
||||
|
||||
Real run (22 Constitution / Prosecutor Law chunks, 15 queries, jieba):
|
||||
|
||||
```
|
||||
检索召回对比:无上下文分块 vs. 上下文感知检索(BM25)
|
||||
====================================================================
|
||||
方法 recall@1 recall@3 recall@5
|
||||
----------------------------------------------------
|
||||
无上下文 (plain) 60.0% 86.7% 93.3%
|
||||
有上下文 (ctx) 86.7% 86.7% 93.3%
|
||||
----------------------------------------------------
|
||||
提升 (Δpp) +26.7pp +0.0pp +0.0pp
|
||||
----------------------------------------------------
|
||||
失败率下降 67% 0% 0%
|
||||
```
|
||||
|
||||
Conclusion (matches the book): context prefixes lift top-1 recall (60% → 86.7%; failure rate 1−recall@1 down 67%). Gain is strongest at recall@1; `--query` shows how the prefix re-ranks the correct section first.
|
||||
|
||||
> `--method embedding` / `--method hybrid` need embedding APIs (not offline); the script falls back to BM25 offline results. Full dense + rerank lives in `contextual_tools.py`.
|
||||
> Same logic is also in `ContextualChunker.compare_retrieval_methods()`.
|
||||
|
||||
### Educational features
|
||||
|
||||
1. Watch LLM context generation per chunk
|
||||
2. Dual indexing (BM25 + embeddings) benefits from context
|
||||
3. Compare with `use_contextual=False`
|
||||
4. Metrics and token/cost awareness
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
Document → Basic Chunking → Context Generation (optional LLM)
|
||||
→ Enhanced chunks (context+text vs text only)
|
||||
→ Retrieval pipeline (sparse BM25 + dense embeddings)
|
||||
→ Hybrid search + reranking
|
||||
```
|
||||
|
||||
### Quick start
|
||||
|
||||
```bash
|
||||
# From the repository root: use the shared Chapter 3 environment
|
||||
uv sync --locked --python 3.12 --extra ch3
|
||||
|
||||
# Activate it before changing directories:
|
||||
# macOS/Linux:
|
||||
source .venv/bin/activate
|
||||
# Windows PowerShell: .venv\Scripts\Activate.ps1
|
||||
# Windows cmd: .venv\Scripts\activate.bat
|
||||
|
||||
# pip fallback when uv is not installed:
|
||||
# python -m pip install -e ".[ch3]"
|
||||
|
||||
cd chapter3/contextual-retrieval
|
||||
|
||||
# Single-project compatibility path, still supported during migration:
|
||||
# python -m pip install -r requirements.txt
|
||||
|
||||
cp env.example .env
|
||||
# MOONSHOT_API_KEY / ARK_API_KEY / OPENAI_API_KEY / etc.
|
||||
|
||||
# Separate terminal for full e2e with pipeline:
|
||||
cd ../retrieval-pipeline
|
||||
python main.py
|
||||
# http://localhost:4242
|
||||
|
||||
# Back in this project directory (or a second terminal):
|
||||
cd ../contextual-retrieval
|
||||
|
||||
# Index with contextual enhancement
|
||||
python index_local_laws_contextual.py
|
||||
python index_local_laws_contextual.py --no-contextual
|
||||
|
||||
# Queries
|
||||
python main.py
|
||||
python main.py --query "宪法第一条是什么" --mode agentic
|
||||
python main.py --query "宪法第一条是什么" --mode compare
|
||||
```
|
||||
|
||||
### Context generation process
|
||||
|
||||
1. Provide full document (or surrounding context) to the LLM
|
||||
2. Show the specific chunk
|
||||
3. Ask for 2–3 sentence situating context
|
||||
|
||||
Template sketch:
|
||||
|
||||
```
|
||||
<document>
|
||||
[Full document or surrounding context]
|
||||
</document>
|
||||
|
||||
Here is the chunk we want to situate:
|
||||
<chunk>
|
||||
[Specific chunk text]
|
||||
</chunk>
|
||||
|
||||
Please give a short, succinct context to situate this chunk within the overall document...
|
||||
```
|
||||
|
||||
### References / license
|
||||
|
||||
- [Anthropic Contextual Retrieval](https://www.anthropic.com/engineering/contextual-retrieval)
|
||||
- Educational project for learning purposes. Acknowledgments: Anthropic engineering research.
|
||||
|
||||
---
|
||||
|
||||
## 中文
|
||||
|
||||
### 概述
|
||||
|
||||
Anthropic 上下文感知检索的教学实现:在嵌入/建索引前为每个分块附加专属上下文,缓解「孤儿分块」问题。
|
||||
|
||||
### 核心洞察
|
||||
|
||||
**问题:** 传统 RAG 分块后丢失语境。「公司收入增长 3%」不知是哪家公司、哪个时期。
|
||||
**方案:** 为每块生成简短解释性上下文并前置,使 BM25 与向量都能保留身份信号。
|
||||
|
||||
### 核心实验:离线量化召回提升(实验 3-10)
|
||||
|
||||
`compare_retrieval.py` **完全离线**量化:同一批文本块分别以无上下文 / 有上下文前缀两种方式建 BM25 索引,在 `evaluation/retrieval_eval.json`(15 查询 + 人工 gold 块)上比较 `recall@k`。**无需 API 或检索服务**(BM25 + jieba)。
|
||||
|
||||
```bash
|
||||
python compare_retrieval.py
|
||||
python compare_retrieval.py --per-query
|
||||
python compare_retrieval.py --query "国家主席有哪些职权?" --top-k 5
|
||||
python compare_retrieval.py --mode plain
|
||||
python compare_retrieval.py --output result.json
|
||||
python compare_retrieval.py --help
|
||||
```
|
||||
|
||||
真实输出(22 个《宪法》《检察官法》文本块,15 查询):
|
||||
|
||||
```
|
||||
检索召回对比:无上下文分块 vs. 上下文感知检索(BM25)
|
||||
====================================================================
|
||||
方法 recall@1 recall@3 recall@5
|
||||
----------------------------------------------------
|
||||
无上下文 (plain) 60.0% 86.7% 93.3%
|
||||
有上下文 (ctx) 86.7% 86.7% 93.3%
|
||||
----------------------------------------------------
|
||||
提升 (Δpp) +26.7pp +0.0pp +0.0pp
|
||||
----------------------------------------------------
|
||||
失败率下降 67% 0% 0%
|
||||
```
|
||||
|
||||
结论与书中一致:上下文前缀显著提升 top-1 召回(60% → 86.7%,失败率下降 67%)。`--method embedding` / `hybrid` 需 embedding API,脚本会提示并回退 BM25 离线结果。完整稠密+重排见 `contextual_tools.py`。
|
||||
|
||||
### 教学特性
|
||||
|
||||
观察上下文生成、双索引策略、`use_contextual=False` 对照、指标与成本。
|
||||
|
||||
### 架构
|
||||
|
||||
文档 → 基础分块 → 可选 LLM 上下文生成 → 增强块 → 检索流水线(稀疏+稠密)→ 混合检索+重排。
|
||||
|
||||
### 快速开始
|
||||
|
||||
```bash
|
||||
# 在仓库根目录使用统一的第 3 章环境
|
||||
uv sync --locked --python 3.12 --extra ch3
|
||||
|
||||
# 切换目录前先激活环境:
|
||||
# macOS/Linux:
|
||||
source .venv/bin/activate
|
||||
# Windows PowerShell:.venv\Scripts\Activate.ps1
|
||||
# Windows cmd:.venv\Scripts\activate.bat
|
||||
|
||||
# 未安装 uv 时可用 pip 兜底:
|
||||
# python -m pip install -e ".[ch3]"
|
||||
|
||||
cd chapter3/contextual-retrieval
|
||||
|
||||
# 迁移期间仍支持单项目兼容路径:
|
||||
# python -m pip install -r requirements.txt
|
||||
|
||||
cp env.example .env
|
||||
|
||||
# 另开一个终端运行完整检索流水线:
|
||||
cd ../retrieval-pipeline
|
||||
python main.py
|
||||
# http://localhost:4242
|
||||
|
||||
# 回到本项目目录(或新开一个终端):
|
||||
cd ../contextual-retrieval
|
||||
|
||||
python index_local_laws_contextual.py
|
||||
python index_local_laws_contextual.py --no-contextual
|
||||
|
||||
python main.py
|
||||
python main.py --query "宪法第一条是什么" --mode agentic
|
||||
python main.py --query "宪法第一条是什么" --mode compare
|
||||
```
|
||||
|
||||
### 上下文生成流程
|
||||
|
||||
向 LLM 提供全文(或周边)+ 目标块,请求 2–3 句定位上下文。提示模板见 English 节。
|
||||
|
||||
### 参考与许可
|
||||
|
||||
[Anthropic 博客](https://www.anthropic.com/engineering/contextual-retrieval) · 教学项目。
|
||||
|
||||
---
|
||||
|
||||
## Notes / 说明
|
||||
|
||||
### OpenRouter 通用回退 / Universal OpenRouter fallback
|
||||
|
||||
Chat LLM falls back to OpenRouter when primary keys are missing and `OPENROUTER_API_KEY` is set. See `env.example`. Related: [`../contextual-retrieval-for-user-memory/`](../contextual-retrieval-for-user-memory/) (Exp. 3-11).
|
||||
Reference in New Issue
Block a user