AS AgentScopeAPI 手册 / API Reference
MISSION 03 · Librarian · 180 XP

馆员Librarian

建立可引用的 RAG 索引Build a citation-first RAG index

类比Analog Notion AI / 企业知识库Notion AI / enterprise knowledge base 技能Skills 检索增强Retrieval & RAG生产意识Production readiness模型抽象Model abstraction

任务简报Brief

线上事故发生时,值班工程师需要从 runbook 中拿到精确段落,而不是一段“听起来对”的总结。每条答案必须带来源、标题和 chunk 序号,方便复核。

During an incident, the on-call engineer needs the exact runbook section, not a plausible summary. Every answer must carry source, heading and chunk index for verification.

RAG 不是“把文档丢进向量库”这么简单。切分决定召回粒度,嵌入决定相似度,阈值决定哪些结果该被丢掉,引用决定答案能否被审计。这一关用确定性哈希嵌入离线复现整条链路,并让你亲手验证 top-1 命中、阈值和引用字段。

RAG is not just “dump documents into a vector store.” Chunking sets recall granularity, embeddings set similarity, thresholds decide what to drop, and citations make answers auditable. This mission reproduces the whole chain offline with deterministic hash embeddings and lets you verify top-1 hits, thresholds and citation fields.

学习目标Learning goals

  • 按标题切分 runbook,并保留 heading / source / chunk index。

    Split the runbook by heading and preserve heading / source / chunk index.

  • 建立知识库并执行 top-k 检索,验证排序与命中。

    Build a knowledge base, run top-k retrieval and verify ordering and hits.

  • 理解 scoreThreshold 为什么会把结果全部过滤掉。

    Understand why scoreThreshold can filter every result.

  • 用 GenericRAGHook 把检索结果注入 Agent 的调用前阶段。

    Inject retrieved context into the agent's pre-call phase with GenericRAGHook.

核心概念Core concepts

KnowledgeBase / SimpleKnowledge

知识库门面:负责文档入库、向量化与检索。Python 用 KnowledgeBase,Java 用 SimpleKnowledge + rag-simple 扩展。

The knowledge facade for ingestion, embedding and retrieval. Python uses KnowledgeBase; Java uses SimpleKnowledge from the rag-simple extension.

Chunking

切分策略决定召回粒度;按标题切分保留语义边界,固定 token 切分更均匀。

Chunking sets recall granularity; heading splits preserve semantic boundaries, fixed-token splits are more uniform.

Embedding

把文本映射成向量;离线哈希嵌入保证可复现,生产嵌入模型决定语义质量。

Maps text to vectors; hash embeddings are reproducible offline, while production models determine semantic quality.

agentscope.embedding.EmbeddingModelio.agentscope.core.embedding.EmbeddingModel

RetrieveConfig

控制 top-k、分数阈值和过滤条件;默认阈值可能高于你的嵌入分数分布。

Controls top-k, score threshold and filters; the default threshold may exceed your embedding score distribution.

GenericRAGHook

在模型调用前注入检索上下文,不用把 RAG 逻辑硬编码进 Agent。

Injects retrieved context before the model call instead of hard-coding RAG into the agent.

双轨实现Build it twice

先完整跑通一条轨道,再切换重来。两条轨道写出同一种产物,方便直接对照行为。Run one track end to end, then switch and repeat. Both tracks write the same artifact so you can compare behavior directly.

当前轨道Current track
Python 2.0.11 轨道Track

本关使用 common/embedding.py 的确定性哈希嵌入和 common/vector_store.py 的本地向量库,完全离线。生产环境把这两个实现替换成真实 embedding 与向量数据库即可。

This mission uses the deterministic hash embedding in common/embedding.py and the local store in common/vector_store.py, fully offline. Swap in a real embedding model and vector database for production.

01

按标题切分并入库Split by heading and ingest

按 ## 标题切分,保留 heading 元数据;ApproxTokenChunker 再做 160/20 的近似 token 切分。

Split on ## headings and keep heading metadata; ApproxTokenChunker then applies 160/20 approximate token chunking.

lab/missions/m3_librarian/mission.py
from agentscope.rag import ApproxTokenChunker

sections = split_runbook()  # 每个 Section 带 heading 元数据
chunker = ApproxTokenChunker(
    ApproxTokenChunker.Parameters(chunk_size=160, overlap=20),
)
chunks = await chunker.chunk(sections)
await knowledge.insert_document(
    chunks, document_id="runbook-2026-10",
    document_metadata={"source": "lab/data/runbook.md"},
)
02

检索并输出引用Retrieve and emit citations

检索结果必须带 source、heading、chunk_index 和分数。缺任何一个,答案都无法复核。

Every hit must carry source, heading, chunk_index and a score. Without them the answer cannot be audited.

lab/missions/m3_librarian/mission.py
hits = await knowledge.search(
    ["provider rejects request with context_length_exceeded"], top_k=2)
for hit in hits:
    print(hit.score,
          hit.chunk.source,
          (hit.chunk.metadata or {}).get("heading"),
          hit.chunk.chunk_index)
03

判题与产物Check and artifact

check 会验证文档数、chunk 数、top-1 标题、排序、tool storm 查询和嵌入确定性,并写出 citations.json。

The check validates document/chunk counts, top-1 heading, ordering, the tool-storm query and embedding determinism, then writes citations.json.

shell
python lab.py check m3
cat work/m3/citations.json

# 期望看到
# PASS CODE: AS-M3-B6NL
运行判题Run the check
python lab.py check m3

权限不影响检索;这一关的重点是数据链路。产物 lab/work/m3/citations.json 与 Java 轨道共用。

Permissions do not affect retrieval; the focus is the data pipeline. The artifact lab/work/m3/citations.json is shared with the Java track.

源码Source lab/missions/m3_librarian/mission.py

判题证明了什么What the check proves

  • 索引了 runbook 的多个 chunkIndexed multiple runbook chunks
  • top citation 命中 Context overflowTop citation hit Context overflow
  • 引用包含 source、heading 与 chunk_indexCitations include source, heading and chunk_index
  • 嵌入在多次调用间保持确定性Embeddings are deterministic across calls
Java 2.0.4 轨道Track

需要 agentscope-extensions-rag-simple。本关的 HashEmbeddingModel 使用 256 维特征哈希;InMemoryStore 用相同维度建索引。

Requires agentscope-extensions-rag-simple. The lab's HashEmbeddingModel uses 256-dimensional feature hashing; InMemoryStore is built with the same dimensions.

01

构建知识库Build the knowledge base

SimpleKnowledge 组合嵌入模型与向量存储;每个 Document 带 DocumentMetadata,payload 里放 heading/source/chunk_index。

SimpleKnowledge composes the embedding model and vector store; each Document carries DocumentMetadata with heading/source/chunk_index payload.

lab/java/src/main/java/lab/m3/M3Librarian.java
SimpleKnowledge knowledge = SimpleKnowledge.builder()
        .embeddingModel(new HashEmbeddingModel())
        .embeddingStore(InMemoryStore.builder().dimensions(256).build())
        .build();

Document doc = new Document(new DocumentMetadata(
        TextBlock.builder().text(section.text()).build(),
        "runbook-2026-10", "chunk-" + section.index(),
        Map.of("heading", section.heading(), "source", "runbook.md",
               "chunk_index", section.index())));
knowledge.addDocuments(List.of(doc)).block();
02

检索并注入 HookRetrieve and hook

RetrieveConfig 默认 scoreThreshold=0.5;哈希嵌入的余弦分数只有约 0.28,所以必须显式设为 0.0,否则结果为空。

RetrieveConfig defaults to scoreThreshold=0.5; hash cosine scores are around 0.28, so set it to 0.0 or every result is filtered out.

lab/java/src/main/java/lab/m3/M3Librarian.java
List<Document> hits = knowledge.retrieve(query,
        RetrieveConfig.builder().limit(3).scoreThreshold(0.0).build())
        .block();

ReActAgent agent = ReActAgent.builder()
        .name("librarian").model(model)
        .hook(new GenericRAGHook(knowledge,
                RetrieveConfig.builder().limit(3).scoreThreshold(0.0).build()))
        .build();
03

编译并判题Compile and check

检查会验证 top-1 标题、排序、引用字段、tool storm 查询、嵌入确定性,以及 Hook 是否真的把检索内容注入模型输入。

The check validates top-1 heading, ordering, citation fields, the tool-storm query, embedding determinism and whether the hook injected context into the model input.

shell
cd lab/java
mvn -q -o compile exec:java -Dexec.args="check m3"

# 期望看到
# PASS CODE: AS-M3-B6NL
运行判题Run the check
cd lab/java && mvn -q -o compile exec:java -Dexec.args="check m3"

Java 没有内置 ApproxTokenChunker;本关直接按标题切分。生产中可以自己实现 chunker 或使用扩展库。

Java has no built-in ApproxTokenChunker; this lab splits by heading. Implement a chunker or use an extension library in production.

源码Source lab/java/src/main/java/lab/m3/M3Librarian.java

判题证明了什么What the check proves

  • 索引了 runbook 的多个 chunkIndexed multiple runbook chunks
  • top citation 命中 Context overflow(score ~0.281)Top citation hit Context overflow (score ~0.281)
  • 引用包含 source、heading 与 chunk_indexCitations include source, heading and chunk_index
  • GenericRAGHook 在 PreCall 阶段注入了检索上下文GenericRAGHook injected retrieved context in PreCall

Python ↔ Java 差异Python ↔ Java differences

  • Python 有 KnowledgeBase + ApproxTokenChunker;Java 用 SimpleKnowledge + InMemoryStore,本关自己按标题切分。

    Python has KnowledgeBase + ApproxTokenChunker; Java uses SimpleKnowledge + InMemoryStore and splits by heading in the lab.

  • Java 的 RetrieveConfig 默认阈值 0.5 会过滤掉哈希嵌入;必须显式设 0.0。Python 本关的自定义检索没有这个默认值。

    Java's RetrieveConfig defaults to 0.5, which filters hash embeddings; set 0.0 explicitly. Python's custom retrieval has no such default.

  • Python 通过 knowledge.search 直接拿 hits;Java 通过 knowledge.retrieve 返回 List<Document>,引用字段从 payload 读取。

    Python gets hits from knowledge.search; Java calls knowledge.retrieve, returning List<Document> with citation fields in the payload.

常见坑Pitfalls

  1. 阈值高于分数分布:所有结果被静默过滤,表现为“检索没有内容”。先打印分数分布,再定阈值。

    A threshold above the score distribution silently filters everything, looking like “no retrieval.” Print the score distribution before choosing a threshold.

  2. 维度不一致:嵌入模型输出 256 维,向量库却按 1536 维建索引,入库或检索直接报错。

    Dimension mismatch: a 256-dimensional embedding against a 1536-dimensional store fails on insert or retrieval.

  3. 引用只有文本:没有 source/heading/chunk_index,事故复盘时无法定位原始段落,也无法判断答案是否过期。

    Citations with text only: without source/heading/chunk_index, incident review cannot locate the original section or detect stale answers.

  4. 切分粒度失衡:块太大导致召回不准,块太小导致上下文缺失。按语义标题切分通常比固定长度更稳。

    Poor chunk granularity: too large hurts precision, too small loses context. Semantic heading splits are usually more stable than fixed length.

领取通行码Claim your pass code

先运行当前轨道的 check。CLI 会打印 PASS CODE、XP 与徽章。粘贴到这里;同一关在每条轨道可各领取一次。Run the check for the current track. The CLI prints PASS CODE plus the exact XP and badge. Paste it here; the same mission can be claimed once on each track.

记录到轨道Record on track

费曼复述Feynman recall

合上教程,用自己的话讲清机制。关键点覆盖 65%、篇幅 20%、结构 15%;60 分通过并一次性获得 20 XP。Explain the mechanism without looking. Coverage 65%, length 20%, structure 15%; 60 passes and earns +20 XP once.

RAG 的检索质量由哪些环节决定?为什么引用必须带 source、heading 和 chunk_index?

Which stages determine RAG retrieval quality? Why must citations include source, heading and chunk_index?

0 chars

查看参考答案Show the model answer

检索质量由切分、嵌入、索引、查询和阈值共同决定:切分决定召回粒度,嵌入决定语义相似度,索引决定候选集合,阈值决定哪些结果被保留。引用必须带 source、heading 和 chunk_index,才能在事故复盘时定位原文、判断版本,并验证答案不是模型编造的。

Retrieval quality is determined by chunking, embedding, indexing, querying and thresholds: chunking sets granularity, embeddings set semantic similarity, the index defines candidates, and thresholds decide what survives. Citations must include source, heading and chunk_index so incident review can locate the original text, check its version and verify the answer was not invented.

间隔复习Spaced review

首次领取后会在明天安排复习。按真实感受评分,下一次间隔会自适应。After the first claim a review is scheduled for tomorrow. Rate how it felt; the next interval adapts.

领取通行码后会自动安排第一次复习。Claim the pass code to schedule your first review.
基于官方固定版本源码静态生成Generated from pinned official sources · Python 2.0.11 · Java 2.0.4
签名与文档为静态抽取;如有疑问请以源码为准。Signatures and docs are extracted statically; verify against the source when in doubt.