ChatOptions 详解:精准控制 AI 对话的配置利器
一句话简介
ChatOptions 是 Microsoft.Extensions.AI 中传递给 IChatClient 的统一配置容器,用于在单次请求中精准控制生成策略、工具调用和扩展特性。
🎯 核心价值
- ✅ 统一配置接口:跨提供商的一致配置体验
- ✅ 细粒度控制:从对话上下文到采样策略,全方位调整
- ✅ 灵活扩展 :通过
AdditionalProperties和RawRepresentationFactory支持提供商特定功能
📝 核心属性概览
ChatOptions 的属性按能力维度可分为五大类:
1. 对话上下文
| 属性 | 说明 | 使用场景 |
|---|---|---|
ConversationId |
绑定会话标识 | 无状态客户端的状态恢复 |
Instructions |
附加系统提示词 | 补充场景限定或额外要求 |
2. 生成策略
| 属性 | 说明 | 典型值 |
|---|---|---|
ModelId |
覆盖默认模型 | "gpt-4o-mini" |
ResponseFormat |
强制输出格式 | Text / Json / JSON Schema |
Temperature |
控制多样性 | 0.0-2.0(越高越随机) |
TopP |
核采样参数 | 0.0-1.0 |
TopK |
Top-K 采样 | 整数值 |
MaxOutputTokens |
最大生成长度 | 如 512 |
FrequencyPenalty |
抑制重复词频 | -2.0 到 2.0 |
PresencePenalty |
抑制重复主题 | -2.0 到 2.0 |
Seed |
固定随机种子 | 用于结果复现 |
StopSequences |
截断序列 | 如 ["[DONE]"] |
3. 工具调用
| 属性 | 说明 |
|---|---|
ToolMode |
工具调用策略(禁用/自动/必须) |
Tools |
当前请求可用的工具集合 |
AllowMultipleToolCalls |
允许模型串联多个工具调用 |
4. 背景执行与恢复
| 属性 | 说明 |
|---|---|
AllowBackgroundResponses |
支持后台长任务(实验性) |
ContinuationToken |
用于轮询或恢复流式响应 |
5. 扩展点
| 属性 | 说明 |
|---|---|
AdditionalProperties |
透传自定义键值对 |
RawRepresentationFactory |
返回提供商专属选项对象 |
💻 核心使用示例
示例 1:对话上下文配置
使用 ConversationId 和 Instructions 绑定会话并追加系统提示词:
csharp
var contextMessages = new List<ChatMessage>
{
new(ChatRole.System, "你是贴心的行程规划助手。"),
new(ChatRole.User, "帮我安排一个五一北京两日游的行程计划。")
};
ChatOptions contextOptions = new()
{
ConversationId = "planner-2024-05-01",
Instructions = "回答请保持中文,并按时间顺序给出活动安排。"
};
var response = await chatClient.GetResponseAsync(contextMessages, contextOptions);
示例 2:生成策略调整
覆盖模型并微调采样参数,精准控制回答风格:
csharp
ChatOptions generationOptions = new()
{
ModelId = "gpt-4o-mini",
Temperature = 0.7f,
TopP = 0.9f,
MaxOutputTokens = 512,
StopSequences = new[] { "[DONE]" }
};
var response = await chatClient.GetResponseAsync(messages, generationOptions);
示例 3:工具调用配置
结合 UseFunctionInvocation 中间件,动态控制工具列表:
csharp
AITool weatherTool = AIFunctionFactory.Create(
(string city) => GetCurrentWeather(city),
name: "get_current_weather",
description: "查询指定城市的实时天气");
ChatOptions toolOptions = new()
{
ToolMode = ChatToolMode.Auto,
AllowMultipleToolCalls = true,
Tools = new[] { weatherTool }
};
var toolEnabledClient = chatClient.AsBuilder()
.UseFunctionInvocation()
.Build();
var response = await toolEnabledClient.GetResponseAsync(messages, toolOptions);
💡 提示:
ChatOptions.Tools适合单次请求的定制配置FunctionInvocationOptions.AdditionalTools适合跨请求共享的工具
🔧 扩展点详解
1. AdditionalProperties:透传提供商特定参数
当标准 ChatOptions 属性无法覆盖提供商特殊功能时,使用 AdditionalProperties:
场景 1:传递 OpenAI 特定参数
csharp
var options = new ChatOptions
{
ResponseFormat = ChatResponseFormat.Json,
AdditionalProperties = new()
{
["strictJsonSchema"] = true // OpenAI 的严格 JSON Schema 模式
}
};
场景 2:存储对话摘要
在 SummarizingChatReducer 中,通过 AdditionalProperties 存储和传递摘要内容:
csharp
// 读取摘要
if (message.AdditionalProperties?.TryGetValue<string>(SummaryKey, out var summaryValue) == true)
{
summary = summaryValue;
}
// 写入摘要
var additionalProperties = lastSummarizedMessage.AdditionalProperties ??= [];
additionalProperties[SummaryKey] = newSummary;
场景 3:Azure AI Inference 的额外属性
在 Microsoft.Extensions.AI.AzureAIInference 包中,AdditionalProperties 被转换为 BinaryData 类型:
csharp
if (options.AdditionalProperties is { } props)
{
foreach (var prop in props)
{
byte[] data = JsonSerializer.SerializeToUtf8Bytes(prop.Value);
result.AdditionalProperties[prop.Key] = new BinaryData(data);
}
}
2. RawRepresentationFactory:逃生舱机制
RawRepresentationFactory 是框架提供的逃生舱(Escape Hatch),用于在统一抽象与底层实现之间建立桥梁。
核心设计理念
为什么需要这个属性?
-
抽象与实现的矛盾
ChatOptions提供统一配置,但各提供商有特有选项- 例如 OpenAI 的
IncludeUsage、Azure AI 的自定义配置
-
避免抽象层膨胀
- 不为每个提供商在
ChatOptions中添加专属属性 - 保持框架简洁性
- 不为每个提供商在
-
提供最大灵活性
- 高级用户可完全控制底层 SDK 配置
工作原理
类型签名:
csharp
public Func<IChatClient, object?>? RawRepresentationFactory { get; set; }
- 输入 :
IChatClient- 当前客户端实例 - 输出 :
object?- 底层实现特定的选项对象
核心机制 - 空值合并优先级:
RawRepresentationFactory返回的非 null 属性具有最高优先级ChatOptions的属性仅填充 raw representation 中的 null 属性
使用场景
场景 1:设置 OpenAI 特有配置
csharp
var chatOptions = new ChatOptions
{
Temperature = 0.7f,
MaxOutputTokens = 1000,
RawRepresentationFactory = (client) => new ChatCompletionOptions
{
IncludeUsage = true, // OpenAI 特有:在流式响应中包含使用统计
TopP = 0.95f // 预设值,不会被 ChatOptions 覆盖
}
};
// 最终结果:
// - Temperature: 0.7 (来自 ChatOptions)
// - MaxOutputTokens: 1000 (来自 ChatOptions)
// - TopP: 0.95 (来自 RawRepresentationFactory,优先级更高)
// - IncludeUsage: true (OpenAI 特有)
场景 2:动态适配不同提供商
csharp
var options = new ChatOptions
{
Temperature = 0.7f,
RawRepresentationFactory = (client) => client switch
{
OpenAIChatClient => new ChatCompletionOptions
{
IncludeUsage = true,
Store = true // OpenAI 持久化选项
},
AzureAIInferenceChatClient => new ChatCompletionsOptions
{
AdditionalProperties =
{
["custom_azure_setting"] = new BinaryData("value")
}
},
_ => null // 其他客户端使用默认转换
}
};
优先级总结
配置属性的最终值由以下优先级决定:
高优先级 ←―――――――――――――――――――――――――――→ 低优先级
1. RawRepresentationFactory 中的非 null 值
2. ChatOptions 中的值(仅填充 raw 中的 null 属性)
3. 客户端的默认值
示例可视化:
csharp
RawRepresentation: { Temperature = 0.8, MaxTokens = null, TopP = 0.9 }
ChatOptions: { Temperature = 0.5, MaxTokens = 100, TopP = 0.7, Seed = 42 }
最终结果: { Temperature = 0.8, MaxTokens = 100, TopP = 0.9, Seed = 42 }
↑ 来自 Raw ↑ 来自 ChatOptions ↑ 来自 Raw ↑ 来自 ChatOptions
重要注意事项
| 注意点 | 说明 |
|---|---|
| 必须返回新实例 | 避免共享实例导致状态污染 |
| 类型必须匹配 | 返回错误类型会被忽略,框架创建默认实例 |
| 不会被序列化 | 委托不能序列化,序列化时会丢失此属性 |
csharp
// ❌ 错误:返回共享实例
private static ChatCompletionOptions _sharedOptions = new();
RawRepresentationFactory = (c) => _sharedOptions;
// ✅ 正确:每次返回新实例
RawRepresentationFactory = (c) => new ChatCompletionOptions { IncludeUsage = true };
🏢 最佳实践
1. 配置选择策略
| 场景 | 推荐方式 |
|---|---|
| 标准功能 | 使用 ChatOptions 标准属性 |
| 提供商特定参数 | 使用 AdditionalProperties |
| 底层 SDK 完全控制 | 使用 RawRepresentationFactory |
2. 工具配置策略
| 场景 | 使用属性 |
|---|---|
| 单次请求的工具 | ChatOptions.Tools |
| 跨请求共享的工具 | FunctionInvocationOptions.AdditionalTools |
3. RawRepresentationFactory 使用建议
- ✅ 仅在必要时使用 :优先使用标准
ChatOptions属性 - ✅ 始终返回新实例:避免状态污染
- ✅ 使用类型检查:根据客户端类型返回不同配置
- ✅ 文档化特殊配置:添加注释说明使用原因
🎯 总结
- ✅ 统一配置容器 :
ChatOptions提供跨提供商的一致配置接口 - ✅ 五大能力维度:对话上下文、生成策略、工具调用、背景执行、扩展点
- ✅ 灵活扩展机制 :
AdditionalProperties透传自定义参数,RawRepresentationFactory提供底层控制 - ✅ 清晰的优先级:Raw representation 中的非 null 值具有最高优先级
- ✅ 最佳实践:标准功能用标准属性,特殊功能用扩展点,始终返回新实例
下一步:探索 Microsoft.Extensions.AI 的缓存机制,敬请期待。