当前位置: 首页 > news >正文

SubAgent 进阶:LLM 策略、工具借用与 Skill 嵌套

标签JavaSubAgentLLM策略llmFactoryallowedToolsSkill嵌套j-langchain
前置阅读:SubAgent 基础:拥有自主工具的子代理
适合人群:已掌握 SubAgent 基础用法,希望灵活控制模型选择、工具权限与多层嵌套的 Java 开发者


一、四个进阶场景

上一篇介绍了 SubAgent 的三种基础用法(独立运行、注册到 Master、代码构造)。本篇聚焦四个进阶场景:

场景解决的问题
model=inheritSubAgent 直接复用主 Agent 的 LLM,无需重复配置
llmFactorySubAgent 在配置文件里声明模型名,运行时按名构建,LLM 实例由主 Agent 统一管理
allowedToolsSubAgent 从主 Agent 借用部分工具,遵循最小权限原则
SKILL 内嵌 SubAgentSkill 的agents/目录放置轻量 SubAgent,形成两层嵌套

二、LLM 三级解析优先链

理解这四个场景之前,先明确 SubAgent 的 LLM 解析规则。每次invoke()时,SubAgent 按以下优先级确定使用哪个 LLM:

优先级 场景 配置方式 ────────────────────────────────────────────────────────── 1 显式注入(开发者指定) SubAgent.Builder.llm(llm) 2 inherit(继承主 Agent) AGENT.md: model: inherit 主 Agent build() 时自动调用 injectLlm(masterLlm) 3 模型工厂(按名构建) AGENT.md: model: qwen-plus 主 Agent build() 时调用 injectLlmFactory(factory) 首次 invoke() 前 factory.apply("qwen-plus") 执行

三个优先级覆盖了所有实际部署场景:测试环境显式注入同类任务共享主 LLM差异化模型按名管理


三、model=inherit:SubAgent 继承主 Agent 的 LLM

最简单的 LLM 复用方式:SubAgent 不自己配置 LLM,直接用主 Agent 的。

配置文件agents/weather-checker/AGENT.md):

--- name: weather_checker description: 天气查询专员。专注查询城市天气信息,当需要了解目的地天气时使用。 model: inherit tools: - get_weather max-iterations: 5 --- 你是天气查询专员,专注于查询城市当前天气状况。 收到城市名称后,调用 get_weather 工具,返回简洁的天气报告。

model: inherit加上tools: [get_weather](借用父 Agent 的get_weather工具)。

代码

varmasterLlm=ChatAliyun.builder().model("qwen-plus").temperature(0f).build();SubAgentConfigconfig=ClasspathSubAgentConfigLoader.fromClasspath("agents/weather-checker");// model=inherit → 不在 builder 里调用 .llm(),由主 Agent build() 时自动注入SubAgentweatherAgent=SubAgent.from(config,chainActor).tools(buildTool("get_weather","查询城市天气","city: String",tools::getWeather)).onToolCall(tc->System.out.println("[weather_checker] ToolCall: "+tc)).onObservation(obs->System.out.println("[weather_checker] Observation: "+obs)).build();McpAgentExecutormaster=McpAgentExecutor.builder(chainActor).llm(masterLlm)// 这个 llm 会被自动注入到 model=inherit 的 SubAgent.subAgent(weatherAgent).systemPrompt("你是旅行助手,天气查询任务请使用 weather_checker。").build();Stringresult=master.invoke("成都现在天气怎么样?").getText();

主 Agentbuild()内部逻辑:

for(SubAgentsubAgent:subAgents){if(subAgent.isInheritModel()){subAgent.injectLlm(masterLlm);// 直接注入主 Agent 的 LLM 实例}...}

适用场景:子任务与主任务性质相同,不需要差异化模型,想减少配置重复。


四、llmFactory:按模型名动态构建 LLM

当不同 SubAgent 需要使用不同模型时,llmFactory提供了统一的 LLM 管理入口:SubAgent 在配置里声明模型名,主 Agent 提供一个"按名构建"的工厂函数。

// SubAgent 配置:声明模型名,不传 llmSubAgentConfigconfig=SubAgentConfig.builder().name("flight_checker").description("机票价格查询专员。当需要查询机票信息时使用。").model("qwen-turbo")// 由主 Agent 的 llmFactory 解析.systemPrompt("你是机票查询专员,收到城市名后调用 get_flight_price,返回机票价格。").build();SubAgentflightAgent=SubAgent.from(config,chainActor)// 不调用 .llm(),由 llmFactory 在 master build() 时解析.tools(buildTool("get_flight_price","查询机票价格","city: String",tools::getFlightPrice)).build();McpAgentExecutormaster=McpAgentExecutor.builder(chainActor).llm(ChatAliyun.builder().model("qwen-plus").temperature(0f).build()).llmFactory(modelName->ChatAliyun.builder().model(modelName).temperature(0f).build()).subAgent(flightAgent).systemPrompt("你是旅行助手,机票查询任务请使用 flight_checker。").build();Stringresult=master.invoke("帮我查一下上海到西安的机票").getText();

主 Agentbuild()内部逻辑:

}elseif(llmFactory!=null){subAgent.injectLlmFactory(llmFactory);// 注入工厂,子代理按 model 名构建}

resolveLlm()在首次invoke()时执行factory.apply("qwen-turbo"),LLM 实例延迟创建。

llmFactory 的价值

  • llmFactory是集中的 LLM 注册表入口——新增模型只改工厂函数,所有 SubAgent 受益
  • SubAgentConfig里的model字段是字符串,可以来自配置文件或数据库,部署时无需改代码
主 Agent llmFactory: modelName → ChatAliyun(modelName) ↓ flight_checker (model=qwen-turbo) → ChatAliyun("qwen-turbo") analyst (model=qwen-max) → ChatAliyun("qwen-max") summarizer (model=qwen-turbo) → ChatAliyun("qwen-turbo")

五、allowedTools:从主 Agent 借用部分工具

SubAgent 不一定要自带所有工具。当工具已经在主 Agent 注册,SubAgent 只需声明allowedTools白名单,主 Agent 在build()时自动过滤并注入。

ToolweatherTool=buildTool("get_weather","查询城市天气","city: String",tools::getWeather);ToolflightTool=buildTool("get_flight_price","查询机票价格","city: String",tools::getFlightPrice);ToolhotelTool=buildTool("get_hotel_price","查询酒店均价","city: String",tools::getHotelPrice);// SubAgent 声明只借 get_weather 和 get_hotel_price,不需要 get_flight_priceSubAgentConfigconfig=SubAgentConfig.builder().name("accommodation_advisor").description("住宿建议专员。查询天气和酒店价格,给出住宿建议。当需要住宿信息时使用。").allowedTools(List.of("get_weather","get_hotel_price")).systemPrompt(""" 你是住宿建议专员。 收到城市名后,依次调用 get_weather 和 get_hotel_price, 结合天气和酒店价格给出住宿选择建议。 """).build();// SubAgent 自己没有 tools,全部来自 allowedTools 注入SubAgentadvisor=SubAgent.from(config,chainActor).llm(llm).onToolCall(tc->System.out.println("[accommodation_advisor] ToolCall: "+tc)).onObservation(obs->System.out.println("[accommodation_advisor] Observation: "+obs)).build();// 主 Agent 拥有全部 3 个工具,SubAgent 只会得到白名单里的两个McpAgentExecutormaster=McpAgentExecutor.builder(chainActor).llm(ChatAliyun.builder().model("qwen-plus").temperature(0f).build()).tools(weatherTool,flightTool,hotelTool).subAgent(advisor).systemPrompt("你是旅行总助手,住宿建议任务请使用 accommodation_advisor。").build();Stringresult=master.invoke("我想去桂林,帮我看看住哪里合适").getText();

注入流程:

主 Agent 工具:[get_weather, get_flight_price, get_hotel_price] ↓ allowedTools 白名单过滤 SubAgent 内部工具:[get_weather, get_hotel_price] ← get_flight_price 被拦截

最小权限原则:SubAgent 只能访问它明确声明需要的工具。即使主 Agent 有 50 个工具,SubAgent 也只会看到白名单里的那几个,不会误调用不相关的工具,也减少了 LLM 在选择工具时的噪声。

执行过程:

[accommodation_advisor] ToolCall: get_weather {"city":"桂林"} [accommodation_advisor] Observation: 桂林:阵雨,23~30°C [accommodation_advisor] ToolCall: get_hotel_price {"city":"桂林"} [accommodation_advisor] Observation: 桂林:三星¥200/晚,四星¥380/晚 住宿建议: 桂林近期天气多雨,建议选择市区内的四星酒店(¥380/晚),出行更便利。 三星酒店(¥200/晚)性价比高,适合预算有限的旅行者。 3晚住宿预算:¥600(三星)~ ¥1140(四星)

六、SKILL 内嵌 SubAgent:两层嵌套

Skill 的agents/子目录可以放置轻量的 SubAgent 配置,这些 SubAgent 会被自动注册为 Skill 内部执行器的工具,形成"主 Agent → Skill → SubAgent"的两层嵌套。

目录结构

skills/travel-planner/ SKILL.md agents/ budget-advisor.md ← 内嵌 SubAgent,只能访问 Skill 自身工具集里的工具

budget-advisor.md

--- name: budget_advisor description: 旅行预算顾问。根据城市名称查询酒店均价,计算3晚旅行的住宿预算。 当需要估算旅行预算时调用。 allowed-tools: - get_hotel_price --- 你是旅行预算顾问,专注于住宿费用估算。 收到城市名称后: 1. 调用 get_hotel_price 查询该城市酒店均价 2. 按3晚计算住宿总费用(三星和四星两个档次) 3. 输出简洁的预算建议

内嵌 SubAgent 的allowed-tools引用的是Skill 自身工具集中的工具(不是主 Agent 的工具),借用范围严格限定在 Skill 内部。

代码

SkillConfigconfig=ClasspathSkillConfigLoader.fromClasspath("skills/travel-planner");System.out.println("内嵌 agents 数量: "+config.getAgents().size());config.getAgents().forEach(a->System.out.println(" - "+a.getName()+" allowedTools="+a.getAllowedTools()));SkilltravelSkill=Skill.from(config,chainActor).llm(llm).tools(weatherTool,flightTool,hotelTool).verbose(true).build();McpAgentExecutormaster=McpAgentExecutor.builder(chainActor).llm(ChatAliyun.builder().model("qwen-plus").temperature(0f).build()).skill(travelSkill).systemPrompt("你是旅行总助手,旅行规划任务请使用 travel_planner 技能。").build();Stringresult=master.invoke("我想去三亚旅游3晚,帮我估算一下住宿预算").getText();

执行时日志(verbose(true)开启二级前缀):

内嵌 agents 数量: 1 - budget_advisor allowedTools=[get_hotel_price] [skill:travel_planner] ToolCall: budget_advisor {"input":"三亚住宿预算,3晚"} [skill:travel_planner>budget_advisor] ToolCall: get_hotel_price {"city":"三亚"} [skill:travel_planner>budget_advisor] Observation: 三亚:三星¥480/晚,四星¥950/晚 ========== SKILL 内嵌 SubAgent 结果 ========== 三亚3晚住宿预算: - 三星酒店:¥480 × 3 = ¥1440 - 四星酒店:¥950 × 3 = ¥2850 建议:三亚旅游旺季酒店紧张,建议提前预订四星酒店...

二级日志前缀[skill:travel_planner>budget_advisor]清楚展示了调用链的层级关系,调试多层嵌套时一目了然。


七、四个进阶场景汇总

场景关键 API典型用途
model=inheritAGENT.mdmodel: inherit子任务与主任务用同一模型,减少配置冗余
llmFactory.llmFactory(name -> ...)多 SubAgent 使用不同模型,统一工厂管理
allowedToolsSubAgentConfig.allowedTools(...)SubAgent 借用父工具,最小权限隔离
SKILL 内嵌 SubAgentagents/*.md目录Skill 内部进一步分解子任务

八、运行前置条件

  1. ALIYUN_KEY环境变量:示例使用qwen-plus/qwen-turbo
  2. model=inherit和内嵌 SubAgent 模式需要对应的AGENT.md文件
  3. allowedToolsllmFactory模式可以用代码构造SubAgentConfig,无文件依赖

九、总结

SubAgent 进阶能力让多 Agent 系统在模型选择和工具权限上更加灵活:

  • 三级 LLM 优先链覆盖了所有部署场景:显式注入用于测试,inherit用于复用,llmFactory用于差异化模型管理
  • allowedTools白名单保证最小权限,SubAgent 只能看到声明需要的工具,LLM 不会误调用无关工具
  • SKILL 内嵌 SubAgent让两层嵌套自然表达"Skill 把复杂子任务进一步委托给专属小代理"的意图,verbose日志二级前缀让调用链透明可追踪

📎 相关资源

  • 完整代码:Article23SubAgent.java,方法testInheritModel/testLlmFactory/testAllowedToolsFromParent/testSkillWithEmbeddedAgent
  • 内嵌子代理配置:skills/travel-planner/agents/budget-advisor.md
  • 天气专员配置:agents/weather-checker/AGENT.md
  • j-langchain GitHub:https://github.com/flower-trees/j-langchain
  • 运行环境:ALIYUN_KEYqwen-plus/qwen-turbo
http://www.jsqmd.com/news/859748/

相关文章:

  • 如何让Switch手柄在Windows电脑上完美工作:终极解决方案指南
  • OpenStack系列第二期:认证与镜像管理
  • 终极免费实时屏幕翻译工具:Translumo完全使用指南
  • 智能选岗APP实测:AI帮你筛岗位、查竞争比、规划全年考试,全程免费
  • 2026 成都高端西装定制权威评测:天府之国的商务休闲智慧 - 西装爱好者
  • 力扣——146.LRU缓存详解
  • 自媒体矩阵工具选型避坑!多个平台发布指南,新手也能选对工具
  • IDEA 如何配置 Live Template 快速生成常用代码片段?
  • 终极指南:使用Visual Studio Uninstaller彻底清理开发环境的5个关键步骤
  • 新手教程,在Windows虚拟机中从零开始使用Taotoken调用GPT模型
  • 上海黄浦区刑事律师法律服务观察与执业方向分析(2026) - 法律资讯
  • 2026MISC躲猫猫题目复盘
  • CANN 上跑 Llama3-70B:我踩了 5 个坑,这些经验值 3000 字
  • 开口/闭口闪点测定仪怎么选?从样品特性到标准合规的采购指南 - 品牌推荐大师
  • 2026年主流电化学工作站厂家:武汉科思特仪器股份有限公司全解析 - 品牌评测官
  • CANN-ops-nn推理实战-昇腾NPU跑Llama如何让基础算子不掉链子
  • vinsfusion前端+后端代码流程图
  • 突破底层运维瓶颈:高阶女工程师的医美维稳架构与高通量胶原蛋白饮选型指南
  • 国内主流燕窝线上店盘点:品质与服务维度对比 - 互联网科技品牌测评
  • LinkSwift网盘直链下载助手:告别限速,实现9大网盘高速下载自由
  • 2026年4月靠谱的智慧泵房制造商推荐,供水控制柜/不锈钢智慧泵房/排污泵/衬氟离心泵/供水设备,智慧泵房销售商口碑推荐 - 品牌推荐师
  • 3个步骤快速上手EdiZon:Switch游戏存档修改的完整指南
  • 破局 AI 幻觉——当通用 AI 遇到企业级表格组件
  • 推客系统私有化部署|企业机构商用专属 完整源码独立交付
  • 全球Web4数字基建企业排行:技术与生态实力盘点 - 互联网科技品牌测评
  • 二年级下册语文看图写话作文:奇妙的大自然
  • Midscene.js终极指南:5分钟让AI成为你的全能操作员
  • 2026年Q2中国管道清淤优质厂家首选推荐:合肥玉通管道工程有限公司 - 安互工业信息
  • taotoken cli工具使用教程一键配置多开发环境
  • 高考志愿填报指导师、学业规划指导师、升学规划指导师怎么选授权报名机构? - 实时教育培训动态