在前几章,我们已经打造了一个强大的 RAG 引擎(Ingest -> Index -> Retrieve)。但如果它只是一个独立的 Python 脚本,那它对 Claude Code (CC) 来说依然是“外人”。
本章的核心任务是“器官移植”:我们要定义一套标准化的输入/输出契约(I/O Contract),让 CC 感觉这个 RAG 不是一个外部工具,而是它与生俱来的“海马体”(长期记忆)或“图书馆”。
当集成本章内容后,你将看到如下的魔法时刻:
AuthService 报错说 token 过期?”search_tool 查询 AuthService 定义和错误码处理逻辑。src/auth/service.ts 第 45 行的逻辑,token 过期时间硬编码为 1 小时,建议修改配置。”本章学习目标:
CC 本质上是一个运行在终端里的 ReAct (Reasoning + Acting) Agent。根据你的介入程度,RAG 可以通过三种方式挂载。
| 特性 | A. 工具化 (Tool/Function Call) | B. 命令化 (Slash Command) | C. 隐式钩子 (Implicit Hook) |
|---|---|---|---|
| 触发机制 | CC 自主决定。基于意图识别。 | 人类手动触发。如 /rag query。 |
事件触发。如“启动时”、“报错时”。 |
| 交互心流 | 流畅,无感。Agent 自行“思考->检索->回答”。 | 打断。人类介入控制检索词。 | 预加载。将知识“推”给 CC。 |
| 实现难度 | 高。需要精心设计 Description 和 Schema。 | 中。只需暴露简单的 CLI 接口。 | 低。简单的脚本注入。 |
| 适用场景 | 复杂问题解决、代码理解、未知领域探索。 | 强制纠偏、精准定位特定文档。 | 项目初始化(加载规范)、错误自动诊断。 |
| 推荐指数 | ⭐⭐⭐⭐⭐ (最符合 Agent 原生体验) | ⭐⭐⭐ (作为兜底手段) | ⭐⭐ (仅用于特定场景) |
这是最复杂的模式,也是效果最好的。我们需理解其中的四次握手:
User Input: "怎么修复 UserTable 的死锁问题?"
|
v
+------------+
| Claude Code| <-- 1. 思考 (Reasoning):
| (Brain) | "我不清楚 UserTable 的锁机制,
+------------+ 我需要调用 'search_codebase' 工具。"
|
| 2. 工具调用请求 (Tool Call Request)
| { "tool": "search", "args": { "query": "UserTable deadlock locking mechanism", "file_pattern": "*.sql" } }
v
+------------+
| Integration| <-- 3. 拦截与转发 (Adapter Layer)
| Layer | 解析 JSON -> 调用你的 RAG API -> 获取 Top-K Chunks
+------------+
|
| 4. 结果返回 (Tool Output)
| <search_results>...</search_results> (XML 格式文本)
v
+------------+
| Claude Code| <-- 5. 综合生成 (Generation)
| (Brain) | 阅读 XML -> 结合上下文 -> 生成带引用的回答
+------------+
让 CC 用好工具的关,在于让它准确理解工具的能力边界。这完全依赖于你提供的 name、description 和 input_schema。
不要只写“搜索代码”。要写得像给新员工的操作指南。
差的描述:
“Search the codebase.”
好的描述 (推荐):
“Semantic search engine for the current project. Use this tool when you need to understand specific implementation details, find function definitions, look up error codes, or understand architectural patterns that are not in the current context. Preferred over generic knowledge for project-specific questions.” (语义搜索引擎。当你需要理解具体实现、查找函数定义、错误码或架构模式时必须使用。对于项目特定问题,优先使用此工具而非通用知识。)
一个成熟的 RAG 工具接口设计如下:
{
"name": "search_codebase",
"description": "Search for code snippets, documentation, and issues within the project repository.",
"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Natural language query focusing on the 'what' and 'why'. E.g., 'How is authentication handled?' or 'User class definition'."
},
"keywords": {
"type": "array",
"items": { "type": "string" },
"description": "Specific symbols, class names, or error codes to boost ranking (e.g., ['AuthService', 'ERROR_503'])."
},
"file_pattern": {
"type": "string",
"description": "Glob pattern to filter files. Critical for reducing noise. E.g., 'src/**/*.ts' for TypeScript code, or 'docs/*.md' for documentation."
},
"requires_exact_match": {
"type": "boolean",
"description": "If true, strictly filters results containing the keywords. Use for looking up specific variable/function names."
}
},
"required": ["query"]
}
}
Rule of Thumb (经验法则):
query负责语义召回(向量检索)。keywords/file_pattern负责过滤(元数据过滤)。- 不要让 CC 传
top_k或embedding,这些是服务端参数,Agent 难以把控。
当你的 RAG 检索到 5 个 Chunk 后,不能把它们简单拼成字符串扔回去。CC 对 XML 结构有着极强的解析能力。
这种格式既能被机器解析,又具有人类可读性(方便调试)。
<search_results>
<!-- 元数据摘要,帮助 CC 快速判断结果质量 -->
<meta>
<total_hits>12</total_hits>
<returned_hits>3</returned_hits>
<latency_ms>45</latency_ms>
<search_strategy>hybrid (semantic + keyword)</search_strategy>
</meta>
<!-- 结果 1:高置信度代码 -->
<result id="doc_8823" score="0.92">
<source_file>src/backend/auth_service.py</source_file>
<lines>45-68</lines>
<language>python</language>
<last_modified>2023-10-25</last_modified>
<snippet>
class AuthService:
def validate_token(self, token):
# TODO: Fix the hardcoded timeout
timeout = 3600
if time.now() - token.timestamp > timeout:
raise TokenExpiredError("Token is too old")
...
</snippet>
</result>
<!-- 结果 2:相关文档 -->
<result id="doc_102" score="0.85">
<source_file>docs/api_spec.md</source_file>
<lines>12-15</lines>
<language>markdown</language>
<snippet>
## Authentication
All endpoints require a Bearer token. Tokens are valid for 1 hour by default.
</snippet>
</result>
<!-- 兜底提示:如果没找到 -->
<!-- <message>No high-confidence results found for '...'. Try broadening your search.</message> -->
</search_results>
<lines> (行号):至关重要。
sed 命令或补丁。<source_file> (路径):
<last_modified> (时效性):
<snippet> (内容):
// ... (content truncated) 标记。仅仅定义工具是不够的,你需要在 CC 的 System Prompt(或自定义指令配置)中注入 RAG 使用规范。
## Tool Use Guidelines: RAG & Search
You have access to a tool named `search_codebase`. You MUST use this tool in the following scenarios:
1. When asked about specific files, classes, or functions not visible in the current conversation history.
2. When planning complex refactoring tasks to understand dependencies.
3. When debugging errors to find where specific error messages are generated.
## Citation & Evidence Rules (STRICT)
When answering based on `search_codebase` results:
1. **Evidence First**: Do not make up code or logic. If the search results are empty or irrelevant, state: "I could not find relevant information in the codebase."
2. **Inline Citation**: When you reference a specific logic, append the source like this:
"The timeout is set to 3600s [[src/auth.py:48]]."
3. **Context Check**: Before suggesting a file edit, ensure you have the correct file path from the search result.
## Handling "No Results"
If a search yields no results, do NOT halllucinate. Instead:
- Ask the user for clarification.
- Suggest searching for a different keyword.
- Or propose listing the directory structure to get oriented.
用户通常比较懒,他们会说:“为什么在这个文件里报错了?” 如果直接把这句话传给 RAG,效果会很差。
策略: 在中间层(Adapter)或 Prompt 中,要求 CC 将查询重写为“独立、完整”的句子。
query="implementation details of the login function in authentication module"向量检索可能会返回 3 个 chunk,它们来自同一个文件的相邻段落(Chunk 1: lines 1-20, Chunk 2: lines 15-35)。
策略: 在集成层做一步后处理: 如果多个结果来自同一文件且行号重叠或相邻,合并它们为一个大的 Block。这能显著提升 CC 阅读代码的连续性。
query 中包含引号或特殊字符,导致 JSON 解析失败。<, >, &)被转义。MAX_TOTAL_TOKENS = 8000。User 类。本章完成了 RAG 系统的“最后一公里”。我们没有写任何检索算法而是专注于通信。
下一章,我们将汇总所有知识,通过一个Reference Implementation(参考实现),从零搭建一个最小可用的外挂 RAG 系统。