datawhale_agentbook_T1_打卡
Task 1 打卡(Chapter 2-3 · 上下文工程与用户记忆、检索)
完成时间 2026-09-19。
环境准备
环境是配 Task 0 时一起装好的,这次先做核实,没重装。venv 在 ai-agent-book/.venv,一共 204 个包,ch2 和 ch3 要用到的都在,torch 2.13.0+cpu、sentence-transformers、faiss、rank_bm25、jieba、chromadb、pandas 逐个导入验证过。中间有一次连着 import torch、sklearn、transformers 报了 MemoryError,分开单独跑就正常,是单进程内存峰值的问题。
两个老问题还在。dense-embedding 目录顶部硬 import annoy 和 hnswlib,这两个包 PyPI 上没有 Windows 的 wheel,本机也没有 MSVC,装不了。这次又复核了一遍,annoy 在 conda-forge 上干脆就没有这个包,hnswlib 倒是有 py312 的 win-64 构建,但缺了 annoy 一样过不去。jieba 还是上次手动复制进 venv 的那个 conda 包,分词正常。
实验过程
按 ch2 和 ch3 各自 README 里的 Starter 到 Maintainer 顺序挑着跑,一共跑了 8 个。
# ch2 上下文工程
# 2-10 上下文压缩,六种策略
cd chapter2/context-compression
LLM_PROVIDER=deepseek MODEL_NAME=deepseek-v4-flash python run_all_strategies.py --log-dir logs/t1_run
# 2-3 KV Cache
cd ../kv-cache
python main.py --no-interactive --mode correct --output runs/t1_correct.json
# 2-9 系统提示
cd ../system-hint
python main.py --mode single --provider kimi --model deepseek/deepseek-v4-flash --output runs/t1_single.json
# 2-5 提示注入攻防
cd ../prompt-injection
OPENAI_API_KEY=$OPENROUTER_API_KEY python demo.py -n 1 -m deepseek/deepseek-v4-flash \
--base-url https://openrouter.ai/api/v1 -o runs/t1_injection.json
# ch3 用户记忆与检索
# 3-5 BM25 稀疏检索
cd ../../chapter3/sparse-embedding
python cli.py --eval
# 3-8 Agentic RAG 对比
cd ../agentic-rag
python main.py --provider deepseek --model deepseek-v4-pro --kb-type offline \
--query "醉酒过失致人重伤且有盗窃前科如何量刑" --mode compare
# 3-1 / 3-2 用户记忆
cd ../user-memory
python main.py --provider openrouter --model deepseek/deepseek-v4-flash \
--mode demo --memory-mode enhanced_notes
# 3-1 / 6-3 用户记忆评估
cd ../user-memory-evaluation
python main.py --mode compare --metric keyword-recall
模型都换成了手头两个 Key 能驱动的。DeepSeek 走官方直连,OpenRouter 那边 OpenAI 和 Google 的模型在这台机器所在区域一律返回 403,只能挑区域可用的,所以统一用 deepseek-v4-flash,KV Cache 那组因为要测缓存命中,用了映射后的 moonshotai/kimi-k2.6。
中间踩了两个坑,都不是环境问题,是代码本身的。
一个是 system-hint 的 --provider。报错信息里写着支持 openrouter,但 agent.py 里只有 dashscope 和 kimi 两个分支,传 openrouter 会被拒。最后用 --provider kimi,让程序自己识别 OpenRouter 的 key 再自动路由,才跑通。
另一个是 kv-cache 的接口地址是 api.deepseek.com/v1,但默认模型是 deepseek-reasoner,这个别名在 2026-07-24 就下线了,得手动指定 deepseek-v4-pro 之类还在的模型名。
结果
ch2 跑了四个。
上下文压缩那组把六种策略并排放在一起,对比最直观。
| 策略 | 完成 | 耗时 | tokens | 压缩比 | 溢出次数 |
|---|---|---|---|---|---|
| no_compression | 否 | 31.2s | 202,313 | 134.2% | 1 |
| individual_summary | 是 | 191.5s | 2,377,944 | 72.2% | 16 |
| combined_summary | 是 | 196.3s | 1,892,075 | 86.1% | 10 |
| context_aware_summary | 是 | 195.3s | 2,061,457 | 94.0% | 11 |
| context_aware_with_citations | 是 | 179.2s | 1,772,548 | 73.8% | 12 |
| windowed_context | 是 | 311.2s | 1,245,041 | 135.8% | 2 |
不压缩那组是唯一失败的一路,最后一次请求 104,477 tokens,超过 128K 上限,直接报错退出。压缩比最低的是 individual_summary,72.2%。这个结果和仓库台账对得上,台账里写的正是「no-compression overflow 加五种完成」。
KV Cache 那组跑了 13 轮迭代、22 次工具调用。缓存命中 6 次、未命中 6 次,命中率 50%,命中 37,952 tokens,占提示词总量的 27.2%。首轮 TTFT 11.561 秒,之后平均 5.223 秒,降了 29.7%。总耗时 70 秒。
系统提示那组是个短任务,让 Agent 建一个 hello_t1.py 再运行一遍。3 轮迭代、2 次工具调用完成,文件内容 print("Hello Task1"),运行输出正确,最后自己汇总说任务做完了。
提示注入那组的结果有点出乎意料。3 种攻击乘 4 种防御,每格跑 1 次,成功率全是 0,连 D1 完全不设防那格也是 0。
ch3 也跑了四个。
稀疏检索(BM25)宏平均 recall@5 0.800、precision@5 0.700、MRR 0.800。有个查询是 cat,语料里对应的是猫科动物的描述,结果一条都没召回。稀疏检索认字不认意的短板,在这一个查询上暴露得很干净。
Agentic RAG 的对比最能说明问题。同一个问题「醉酒过失致人重伤且有盗窃前科如何量刑」,非 Agent 模式检索到的条款不够,直接说上下文里找不到依据、给不出结论。Agent 模式自己多搜了几轮,把过失致人重伤罪、醉酒条款、累犯除外条款都找齐了,答案里引了具体条文和 chunk 编号,还讲清楚盗窃前科因为属于过失犯罪、不构成累犯。
用户记忆那组,Agent 从对话里抽出 3 条结构化笔记,分别是身份、技术偏好、在做的项目,写完用一个新问题验证,能凭记忆答出 Python、VS Code、暗色主题这些细节。记忆落在 data/memories 目录的 json 文件里,会话之间是替换而不是追加,后面那轮请求里看不到原始对话历史。
用户记忆评估加载了 60 条用例,四套记忆系统同台对比。
| 记忆方案 | Layer1 | Layer2 | Layer3 | 总体 |
|---|---|---|---|---|
| full_context | 1.000 | 1.000 | 1.000 | 1.000 |
| json_cards | 1.000 | 1.000 | 1.000 | 1.000 |
| simple_notes | 0.417 | 0.333 | 0.125 | 0.323 |
| no_memory | 0.000 | 0.000 | 0.000 | 0.000 |
结构化卡片用很少的存储就做到了和全量上下文一样的召回,简单笔记只有 0.323。
其他实验为什么没做
ch2 这边,local_llm_serving 要本地跑 0.6B 模型,本机没装 Ollama 也没 GPU。agent-skills-ppt 要走 Claude Code 或者 Kimi Code CLI,没装。
attention_visualization 和 prompt-engineering 这两个我实际试过,都卡在本机资源上,留到 Task 2 最后补跑。
attention_visualization 要下 Qwen3-0.6B 的权重,总共 1.5 GB。hf-mirror 是通的,但实测平均速度只有 340 KB/s 左右,跑了几分钟只下到 2.1%,过程中反复报读取超时然后自动重试。机器 16.8 GB 内存,可用常年只有 2 到 5 GB,模型加载也不宽裕。下载已经停掉。
prompt-engineering 试跑了三次。τ-bench 内嵌在仓库里,airline 和 retail 两个环境的数据都在,依赖也基本齐了,requirements 里列的 google-generativeai 和 termcolor 没装,但全仓库没有任何地方 import 它们,不影响。单独导入 tau_bench 的环境是成功的,说明代码没问题,可一进消融流程就在 litellm 和 pydantic 生成 schema 的地方报 MemoryError,空闲内存 5.38 GB 的情况下依然复现。这是本机内存不足,不是环境没配好。
顺带记两条使用上的约束。prompt-engineering 的 --all 模式强制校验协议里冻结的 10 个任务 ID,不能只挑几个跑,单臂消融可以用 --tone-style、--randomize-wiki、--remove-tool-descriptions 单独指定。它支持的 provider 列表里没有 deepseek,得走 openrouter 加命名空间的模型名。
ch3 卡得更死一些。dense-embedding 要 annoy 和 hnswlib,前面说过装不了,这个比较可惜,因为 retrieval-pipeline 依赖它的 4240 端口服务,contextual-retrieval 和 structured-index 又依赖 retrieval-pipeline 的 4242 端口,一条链上的三个实验跟着一起做不了。log-sanitization 要本地 Ollama。mem0 和 memobase 要各自的云端 Key。structured-knowledge-extraction 要下 CAIL2018 数据集。agentic-rag-for-user-memory 有离线演示模式,这次没来得及跑。
心得
跑下来最大的感受是,ch2 讲上下文工程,最实在的证据都藏在数字里。压缩那组六条曲线摆在一起,不压缩撞墙、压缩后活下来,一次就能看明白为什么上下文管理是刚需。KV Cache 那个 50% 的命中率和 29.7% 的 TTFT 降幅,也给「稳定前缀」这件事补了个量化依据。
ch3 这边,Agentic RAG 的对比让我印象最深。同一套法条库、同一个问题,差别只在要不要多搜几轮,答案的可信程度差了一个档次。用户记忆的评估数字也直观,json_cards 用 1.000 的召回说明记忆不是存得越多越好,是结构对不对。
还有一件事值得记一下。提示注入那组全是 0,和仓库台账的记录完全对得上,台账里写明「所有观测到的攻击成功率都是 0%,包括基线,实验仍然算完成」。我本来以为换个便宜的模型会更容易被攻破,结果没有。另外 demo 最后打印的结论说随防御逐层加强、成功率显著下降,但数据里 D1 到 D4 本来就都是 0,看不出下降,这段结论和实际矩阵对不上。
Task 0 那会儿消融实验给我的感觉是「上下文缺一块会出事」,这次跑完 ch2 ch3,反过来看清了每个组件在正常工作时的价值。同一件事的两面。

浙公网安备 33010602011771号