Solon v3.9.4

chat - 工具动态添加和 Solon AI Skill

</> markdown
2026年3月3日 下午9:08:49

在实际应用中,我们经常需要根据当前用户的 身份(Role)或上下文(Context) 动态分配工具集。例如:普通用户只能查询天气,而管理员可以调用系统重启工具。

Solon AI 提供了两种实现方式:Options 动态添加工具 和 AI Skill 封装工具。

1、通过 Options 动态添加工具

这种方式最为直接,适合简单的逻辑判断。你可以在每次发起 prompt 请求时,通过 options 配置项实时注入工具。

ChatModel chatModel = ChatModel.of(...).model("...").build();

public void demo(String prompt, String role) {

     chatModel.prompt("今天杭州的天气情况?")
            .options(o -> {
                // 根据业务角色,动态注入不同的工具实例
                if("admin".equals(role)) { //在请求时添加(只能在请求时添加)
                    o.toolAdd(new UserTool());
                    o.toolAdd(new AdminTool());
                } else {
                    o.toolAdd(new UserTool());
                }
            }) //添加请求时选项处理
            .call();
}
  • 优点:上手快,逻辑直观。
  • 缺点:业务判断逻辑耦合在调用层,如果多处用到该逻辑,代码会比较冗余。

2、使用 Solon AI Skill 实现高级解耦(同等效果)

AI Skill 是对一组工具及其选择逻辑的更高维度封装。通过自定义 AI Skill,你可以将“根据角色筛选工具”的逻辑隐藏在组件内部,让调用端保持极致简洁。

更多内容请参考:《Solon AI Skills 开发》

第一步:定义 Skill

继承 AbsSkill 并实现 getTools 方法。你可以从 Prompt 的属性中获取上下文信息。

public class AuthControlSkill extends AbsSkill {
    UserTool userTool =  new UserTool();
    AdminTool adminTool =  new AdminTool();
    
    @Override
    public Coll<Tool> getTools(Prompt prompt) {
        // 从请求上下文中提取角色信息
        String role = prompt.attrAs("role");
        
         if("admin".eq(role)) {
             return Arrays.asList(userTool, adminTool);
          } else {
              return Arrays.asList(userTool);
          }
    }
}

第二步:应用 Skill

你可以选择在 ChatModel 构建时全局挂载,或者在单次请求时按需挂载。

//在构建时添加(或者在请求时添加)
ChatModel chatModel = ChatModel.of(...).model("...").defaultSkillAdd(new AuthControlSkill()).build();

public void demo(String prompt, String role) {
     // 调用端只需传递业务参数,无需关心工具过滤逻辑
     chatModel.prompt(Prompt.of("今天杭州的天气情况?").attrPut("role", role))
            //.options(o -> {
            //    o.toolAdd(new UserSkill()); //在请求时添加(或者在构建时添加)
            //}) 
            .call();
}

3、总结:如何选择?

维度Options 动态添加Solon AI Skill 封装
复用性低,逻辑散落在各处高,可作为独立组件复用
维护性适合临时、简单的逻辑适合复杂权限、多工具协作场景
代码感过程式命令声明式、面向对象