### 1、模型配置（ChatConfig）

ChatConfig，聊天模型配置


| 属性                                          | 要求    | 描述                                                         |
| -------------------------- | ----- | ---------------------------------- |
| `apiUrl:String`                             | 必须    | 模型服务接口地址<mark>（是完整地址）</mark>                                    |
| `apiKey:String`                            |           | 接口令牌                                                   |
| `provider:String`                          |           | 服务提供者（如ollama、dashscope、openai），默认为 openai                 |
| `model:String`                             | 必须    | 模型名字                                                |
| `headers:Map<String, String>`       |           | 头信息（其它配置，都以头信息形式添加）      |
| `timeout:Duration`                        |           | 请求超时（默认：60s）                               |
| `proxy:ProxyDesc`                        |           | 网络代理                                                   |
| | | |
| `defaultToolContext:Map`            |           | 默认工具上下文（每次请求，都会附上）             |
| `defaultOptions:Map`                  |           | 默认选项（每次请求，都会附上）                       |
| `defaultAutoToolCall:Boolean`      |           | 默认选项（自动执行工具调用），默认为 `true` ，v3.8.4 后支持      |
| | | |
| `modelOptions(ChatOptions->{})`      |         |  模型选项（温度、工具、拦截器等）。v3.8.4 后支持 |

关于 model 配置：

* 如果是 ollama ，运行什么模型即填什么（如： `ollama run deepseek-r1:7b`，则填：`deepseek-r1:7b`）
* 如果是其它服务平台，请按平台的接口说明填写

更多可参考：《模型实例的构建和简单调用》


示例：

```java
//用 ChatConfig 构建聊天模型（ChatConfig 一般用于接收配置注入）
public void case1(@Inject("${xxx.yyy}") ChatConfig config) {
    ChatModel chatModel = ChatModel.of(config).build(); 
}

//直接构建聊天模型（ChatModel.Builder 内置 ChatConfig）
public void case2() {
    ChatModel chatModel = ChatModel.of(apiUrl)
                .apiKey(apiKey)
                .model(model)
                .modelOptions(o -> o.optionSet("enable_thinking", false)
                                    .temperature(0.1)) //v3.8.4 之后（还支持温度等配置）
                //.defaultOptionAdd("enable_thinking",false)  //v3.8.4 之前
                .build();
}
```


### 2、请求选项（ChatOptions）


ChatOptions，聊天请求选项（不同模型，支持情况不同）


| 方法                                                 | 描述          |
| ------------------------------ | -------- |
| `toolContext():Map`                         | 获取工具上下文（附加参数）。    |   
| `toolContextPut(Map):self`                    | 设置工具上下文（附加参数）。    |   
| | | 
| `tools():FunctionTool[]`                         | 获取所有函数工具（内部构建请求时用）    |    
| `tool(name):FunctionTool`                     | 获取函数工具    |   
| `toolAdd(FunctionTool):self`                 | 添加函数工具    |   
| `toolAdd(Iterable<FunctionTool>):self`   | 添加函数工具    |   
| `toolAdd(ToolProvider):self`                  | 添加函数工具    |   
| `toolAdd(Object):self`                          | 添加函数工具（`@ToolMapping` object）    | 
| `toolAdd(String, Consumer<FunctionToolDesc>):self`     | 添加函数工具（构建模式）    |   
| | | 
| `skills():Skill[]`                | 获取所有技能（内部构建请求时用），v3.8.4 后支持     |      
| `skillAdd(Skill):self`         | 添加技能，v3.8.4 后支持     |   
| `skillAdd(int, Skill):self`    | 添加技能，v3.8.4 后支持     |   
| | | 
| `interceptors():ChatInterceptor[]`                | 获取所有聊天拦截器（内部构建请求时用）     |      
| `interceptorAdd(ChatInterceptor):self`         | 添加聊天拦截器     |   
| `interceptorAdd(int, ChatInterceptor):self`    | 添加聊天拦截器     |   
| | | 
| `options():Map<String, Object>`             | 获取所有选项（内部构建请求时用）     |      
| `option(key):Object`                             | 获取选项     |   
| `optionSet(key,val):self`                       | 添加选项（常用选项之外的选项）     |     
| | | 
| `tool_choice(choiceOrName):self`          | 常用选项：工具选择（可选：none，auto，required，或 tool-name）    | 
| `max_tokens(val):self`                          | 常用选项：最大提示语令牌数限制    | 
| `max_completion_tokens(val):self`         | 常用选项：最大完成令牌数限制       | 
| `temperature(val):self`                         | 常用选项：temperature 采样          | 
| `top_p(val):self`                                  | 常用选项：top_p 采样                   | 
| `top_k(val):self`                                   | 常用选项：top_k 采样                   | 
| `frequency_penalty(val):self`                 | 常用选项：频率惩罚                      | 
| `presence_penalty(val):self`                  | 常用选项：存在惩罚                      | 
| | | 
| `response_format(map):self`                  | 常用选项：响应格式                      | 
| `user(user):self`                                   | 常用选项：用户                      | 


示例：

```java
public void case1(ChatConfig config) {
    ChatModel chatModel = ChatModel.of(config).build(); //使用聊天配置
    
    chatModel.prompt("hello")
        .options(o->o.max_tokens(500)) //使用聊天选项
        .call();
}
```

```java
public void case2(ChatConfig config, String user) {
    ChatModel chatModel = ChatModel.of(config).build(); //使用聊天配置
    
    chatModel.prompt("hello")
        .options(o->o.toolAdd(new WeatherTool()).toolContextPut(Utils.asMap("user", user))) //使用聊天选项
        .call();
}

//user 参数不加 @Param（即不要求 llm 输出），由 toolContext 传入（扩展参数）！
public class WeatherTool {
    @ToolMapping(description = "获取指定城市的天气情况")
    public String get_weather(@Param(description = "根据用户提到的地点推测城市") String location, String user) {
        return "晴，24度"; //可使用 “数据库” 或 “网络” 接口根据 location 查询合适数据;
    }
}
```

### 3、关于 response_format （模型的响应格式）

每个模型可能不同，一般：默认为 md 格式。其它格式参考（具体要看模型的说明）：

```java
chatModel.prompt("hello")
    .options(o->o.response_format(Utils.asMap("type", "json_object"))) //使用聊天选项
    .call();
```

```java
chatModel.prompt("hello")
    .options(o->o.response_format(Utils.asMap("type", "json_schema",
                                    "json_schema", Utils.asMap("type","object","properties",Utils.asMap()),
                                    "strict", true))) //使用聊天选项
    .call();
```
