---
title: "chat - Talent 与 Tool 的使用区别"
---

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

Solon AI 通过 Options 动态添加“工具” 和 “才能”展示它们的使用区别。


### 1、通过 Options 动态添加工具

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

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

public void demo(String prompt, String role) {

     chatModel.prompt("今天杭州的天气情况？")
            .options(o -> {
                //添加系统提示词
                o.systemPrompt("你是个天气预报员");
                
                // 根据业务角色，动态注入不同的工具实例
                if("admin".equals(role)) { //在请求时添加（只能在请求时添加）
                    o.toolAdd(new UserTool());
                    o.toolAdd(new AdminTool());
                } else {
                    o.toolAdd(new UserTool());
                }
            }) //添加请求时选项处理
            .call();
}
```


* 优点：上手快，逻辑直观。
* 缺点：业务判断逻辑耦合在调用层，如果多处用到该逻辑，代码会比较冗余。

### 2、使用 Solon AI Talent 实现高级解耦（同等效果）

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

更多内容请参考：[《Solon AI Talents 开发》](/article/learn-solon-ai-talents)

#### 第一步：定义 Talent

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

```java
public class AuthControlTalent extends AbsTalent {
    UserTool userTool =  new UserTool();
    AdminTool adminTool =  new AdminTool();
   
    @Override
    public String getInstruction(Prompt prompt) {
        return "你是个天气预报员";
    }
    
    @Override
    public boolean isSupported(Prompt prompt) {
        return prompt.getUserContent().contains("天气"); //提示词中有“天气时”才支持
    }
    
    @Override
    public Collection<FunctionTool> getTools(Prompt prompt) {
        // 从请求上下文中提取角色信息
        String role = prompt.attrAs("role");
        
         if("admin".eq(role)) {
             return Arrays.asList(userTool, adminTool);
          } else {
              return Arrays.asList(userTool);
          }
    }
}
```

#### 第二步：应用 Talent

你可以选择在 ChatModel 构建时全局挂载。

```java
ChatModel chatModel = ChatModel.of(...).model("...").defaultTalentAdd(new AuthControlTalent()).build();

public void demo(String prompt, String role) {
     chatModel.prompt(Prompt.of("今天杭州的天气情况？").attrPut("role", role))
            .call();
}
```


或者在单次请求时按需挂载

```java
public void demo(String prompt, String role) {
     chatModel.prompt(Prompt.of("今天杭州的天气情况？").attrPut("role", role))
            .options(o -> {
                o.talentAdd(new UserTalent()); 
            }) 
            .call();
}
```


### 3、总结：如何选择？



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







