【AgentScope Java新手村系列】(16)从RAG到多路检索

第十六章 从 RAG 到多路检索:subagent 查文件,向量工具查语义

1.x 的 SimpleRAGKnowledgeBgeRAGKnowledgeEmbeddingRAGKnowledge 等 RAG 实现类在 RC2 中已被移除(它们是 1.x 特有的 API,2.0 中不存在)。

原因:传统 RAG 抽象把"文档分块 + 嵌入 + 检索"做成黑盒。2.0 改为"subagent + 文件检索 + Skill 仓库 ":业务方把文档放 ./docs 目录里,subagent 用 grep_files 按关键词搜文件、用 read_file 读原文内容,不切片、不嵌入。LLM 自己决定搜什么词、读哪段,比硬编码检索管道灵活得多。

本章先给出 1.x 旧 API 的最小示例(仅供维护老项目参考),再讲 2.0 推荐的新做法。

16.1 1.x RAG 旧 API 回顾

java 复制代码
import io.agentscope.core.rag.SimpleRAGKnowledge;
import io.agentscope.core.rag.Knowledge;
import io.agentscope.core.rag.loader.LocalFileLoader;
import io.agentscope.core.ReActAgent;
import io.agentscope.core.model.DashScopeChatModel;

public class Chapter16_LegacyRag {

    public static void main(String[] args) {
        // 1. 准备知识库
        Knowledge knowledge = new SimpleRAGKnowledge(
                new LocalFileLoader("./docs"),
                new DashScopeEmbeddingModel());

        // 2. agent 装上 knowledge
        ReActAgent agent = ReActAgent.builder()
                .name("doc_qa")
                .sysPrompt("你是文档问答助手。")
                .model(DashScopeChatModel.builder()
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .modelName("qwen-plus")
                        .build())
                .knowledge(knowledge)            // 1.x
                .build();

        // 3. 调用时 agent 内部会先 retrieve 再回答
    }
}

2.0 仍可编译ReActAgent.knowledge(...) 在 RC2 中标记为 @Deprecated(forRemoval = true),编译通过但会告警。新项目请不要使用。

16.2 2.0 推荐的"subagent + 文件检索"

为什么不用 1.x 的 RAG 了?

1.x 的 RAG 是一条固定管道

css 复制代码
文档 → 切片 → 嵌入(向量化) → 存向量库
                                    ↓
用户提问 → 同样嵌入 → 余弦相似度搜索 → 取 top-k 切片 → 拼进 prompt → LLM 回答

这条管道有三个问题:

问题 影响
黑盒检索 向量相似度 ≠ 语义相关。搜出来的切片可能"看起来像但内容不相关",你没地方 debug
管道路径固定 先切片、再嵌入、再搜索。LLM 全程不参与检索决策,搜什么、怎么搜全由管道定
依赖外部组件 需要 embedding 模型(DashScope/Qwen Embedding)+ 向量库(Milvus/Pinecone),多两个微服务

2.0 怎么做?

把检索权交给 LLM 。agent 自带 grep_files(关键词搜索)和 read_file(读文件),LLM 自己决定搜什么关键词、读哪个文件、读多少内容。不切片、不嵌入、不向量库。

perl 复制代码
2.0 工作流:
用户提问 → LLM 自己决定用什么关键词 grep → 自己读相关文件 → 自己综合答案

对比一下:

1.x RAG 2.0 subagent + 文件检索
检索决策者 管道(程序) LLM(agent)
检索方式 向量相似度 grep_files 关键词 + read_file 精读
外部依赖 embedding 模型 + 向量库 无,全是 agent 内置工具
可调试性 差(你不知道为啥搜到这个切片) 好(agent 日志里能看到 grep 了什么、读了什么)
灵活性 固定管道 LLM 可以分步检索:先 grep 找文件名 → 再 read 读内容 → 不够再 grep 扩大范围

核心思想 :与其让程序猜"哪段和用户问题最像",不如让 LLM 自己想"我应该搜什么词、读哪个文件"。HarnessAgent 自带 read_file / grep_files / glob_files 三个内置工具,subagent 可以直接用它们:

typescript 复制代码
import io.agentscope.harness.agent.subagent.SubagentDeclaration;
import io.agentscope.harness.HarnessAgent;

public class Chapter16_NewRag {

    public static void main(String[] args) {
        // 文档检索 subagent:用 grep_files + read_file 代替传统向量检索
        SubagentDeclaration docReader = SubagentDeclaration.builder()
                .name("doc_reader")
                .description("""
                        文档检索 subagent。
                        拿到问题后:
                        1. 先用 grep_files 在 ./docs 找关键词
                        2. 用 read_file 读最相关的 1-2 个文件
                        3. 综合内容回答
                        """)                                        // LLM 根据 description 决定何时 spawn 它
                .inlineAgentsBody("你是一个文档检索员," +
                        "只用 read_file / grep_files 找答案。")       // subagent 自己的系统提示词
                .build();

        HarnessAgent host = HarnessAgent.builder()
                .name("qa")
                .sysPrompt("你是问答助理,需要查文档时 spawn doc_reader。")
                .model(model())
                .workspace(Path.of("./workspace"))
                .subagent(docReader)                                // 注册 subagent
                .build();
    }
}

host.call(...) 时,LLM 看到用户的问题含"文档",会主动 spawn doc_reader,后者用 grep + read 自己决定查什么。

16.3 进阶:用 Skill 仓库做"结构化 RAG"

如果文档量很大、希望"按主题切分",可以直接把每份文档做成一个 Skill(详见第 18 章):

objectivec 复制代码
workspace/
└── skills/
    ├── product-faq/
    │   └── SKILL.md
    ├── engineering-handbook/
    │   └── SKILL.md
    └── legal-policies/
        └── SKILL.md

每份 SKILL.md 描述"这个 skill 解决什么问题":

makefile 复制代码
# product-faq/SKILL.md
name: product-faq
description: |
  产品 FAQ:当用户问"如何退款 / 如何开发票 / 如何修改地址"时优先用。
allowed-tools: [read_file, grep_files]

主 agent 在 prompt 里被告知"先看 SKILL.md 决定用哪个 skill"。LLM 按 description 路由到对应 skill,再读 SKILL.md手动维护的文档链接

这种方式优势:

  • 路由可读 :产品经理也能改 SKILL.md 调整路由
  • token 省:一次只载入相关 skill 的元信息,不一次性塞进 prompt
  • 可管理:文档更新时只改对应 skill 的内容

16.4 何时仍用真正的"嵌入 + 向量检索"

如果你的检索需求满足下面任一条件,仍可保留传统 RAG:

  • 文档量 > 10 万条,subagent 用 grep_files 检索太慢
  • 检索要求"语义相似"(用户写"心情不好"要找到"沮丧"段)
  • 需要 hybrid search(同时跑 BM25 和向量搜索,把两边的结果按权重凑成一份最终排名)

此时推荐在 2.0 中手写 一个 Tool

less 复制代码
@Tool(name = "vector_search", description = "向量检索")
public String vectorSearch(
        @ToolParam(name = "query") String query,
        @ToolParam(name = "topK", required = false) Integer topK) {

    // 调你自己的向量库(Milvus / Elasticsearch / PGVector)
    return vectorStore.search(query, topK == null ? 5 : topK);
}

把工具注册到 agent / subagent 即可。这就是 2.0 推荐的"该用什么工具就用什么工具",不必拘泥于 RAGKnowledge 抽象。

16.5 最小迁移清单(1.x RAG → 2.0)

1.x 你做了什么 2.0 怎么做
RAGKnowledge.retrieve(...) 自动检索 subagent 用内置 grep_files + read_file 检索
SimpleRAGKnowledge 等内置分块+嵌入 框架已去掉内置管道。如需嵌入,自己写 @Tool 调向量库
配置分块策略、嵌入模型 在自定义 @Tool 里自由实现,框架不再限制
agent.knowledge(knowledge) .subagent(retriever).toolkit(toolkit)
agent.call(..., retriever=knowledge) 拆成 subagent + 工具,LLM 自主决定何时检索

核心变化 :1.x 的 RAG 是框架内置管道(你只管配参数)。2.0 框架不再内置分块/嵌入/向量搜索,但你可以用 @Tool 自由实现任意检索逻辑。检索决策从管道转移到 LLM。

16.6 完整可运行示例

这个例子在演示什么?

一个 QA agent 配了两种检索方式,LLM 根据问题类型自己决定用哪个:

  • doc_reader subagent :用内置 grep_files + read_file./docs 目录做文件级关键词检索。适合"退货政策是什么""怎么开发票"这类事实性问题,零外部依赖。
  • vector_search 工具:调 Milvus/ES 做语义级向量检索。适合用户写"心情不好"要找"沮丧相关文档"这类模糊匹配。

这不是冗余,是互补:subagent 查文件快但只能精确匹配,向量检索慢但能理解语义。LLM 看到问题类型后自己选路:事实问题 spawn subagent,模糊问题调 vector_search。两个可以共存于同一个 agent。

typescript 复制代码
public class Chapter16_Full {

    public static void main(String[] args) {
        // 文件检索 subagent:用内置工具,不额外写 Java 代码
        SubagentDeclaration docReader = SubagentDeclaration.builder()
                .name("doc_reader")
                .description("文档检索;输入问题,输出从 ./docs 找出的相关段落")
                .inlineAgentsBody("""
                        你是一个文档检索员。
                        1. 用 grep_files 在 ./docs 下找关键词
                        2. 用 read_file 读最相关 2 份文件
                        3. 把内容整理成 200 字以内回答
                        """)
                .build();

        // 语义检索工具:业务方自己接向量库(可选)
        Toolkit toolkit = new Toolkit();
        toolkit.registerTool(new VectorSearchTool("http://localhost:19530"));

        HarnessAgent host = HarnessAgent.builder()
                .name("qa")
                .sysPrompt("""
                        你是问答助理。
                        优先 spawn doc_reader 查本地文档;如果用户问模糊的语义类问题,调 vector_search 工具。
                        """)
                .model(model())
                .workspace(Path.of("./workspace"))
                .subagent(docReader)                // 文件检索(关键词)
                .toolkit(toolkit)                   // 向量检索(语义)
                .build();

        // 事实性问题 → LLM 会 spawn doc_reader
        host.call(
                List.of(new UserMessage("user", "退款政策是什么?")),
                RuntimeContext.empty())
                .block();

        // 模糊问题 → LLM 会调 vector_search
        host.call(
                List.of(new UserMessage("user", "有哪些和用户不满意相关的政策?")),
                RuntimeContext.empty())
                .block();
    }
}

16.7 本章小结

  • 1.x RAGKnowledge 在 2.0 中被标记为弃用,未来会移除。
  • 2.0 推荐"subagent + 文件检索"或"业务方手写向量检索 @Tool"。
  • 大量结构化文档可以做成 Skill 仓库,用 description 做路由。
  • 真正需要嵌入 + 向量库时,业务方用 @Tool 自由实现即可。
相关推荐
咩咩啃树皮3 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
鱟鲥鳚4 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
大模型码小白5 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司6 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地7 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
wuqingshun3141597 小时前
TCP超时重传机制是为了解决什么问题?
java
莫逸风10 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
隔窗听雨眠10 小时前
Spring Boot在云原生时代的编程范式革新研究
spring boot·后端·云原生
z1234567898610 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
yaoxin52112311 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python