为三种OpenAI客户端创建IChatClient对象
penAIClient和AzureOpenAIClient是一个与OpenAI的API进行交互的客户端我们可以指定模型名称调用其GetChatClient方法来获取一个对应的ChatClient对象。虽然名字雷同但是这个ChatClient类型可没有实现IChatClient接口我们需要调用为它定义的扩展方法AsIChatClient来将它转换成一个实现了IChatClient接口的对象。public class AzureOpenAIClient { public override ChatClient GetChatClient(string deploymentName); public override ResponsesClient GetResponsesClient(); } public class OpenAIClient { public virtual ChatClient GetChatClient(string model); public virtual ResponsesClient GetResponsesClient(); } public static class OpenAIClientExtensions { public static IChatClient AsIChatClient(this ChatClient chatClient); public static IChatClient AsIChatClient(this ResponsesClient responseClient, string? defaultModelId null); }前面说过GetChatClient返回的ChatClient对象采用基于文本补全的无状态的Completion API来与模型进行交互如果需要采用有状态的Responses API需要调用GetResponsesClient方法来获取一个ResponsesClient对象。系统依然为ResponsesClient对象定义了一个AsIChatClient的扩展方法来将它转换成一个实现了IChatClient接口的对象。如果使用的是基于Microsoft Foundry的AIProjectClient客户端。由于它的基类是ClientConnectionProviderExtensions我们可以调用其扩展方法GetProjectOpenAIClient得到一个ProjectOpenAIClient对象。由于ProjectOpenAIClient继承自OpenAIClient我们同样可以调用为它定义的AsIChatClient扩展方法来将它转换成一个实现了IChatClient接口的对象。public class AIProjectClient : ClientConnectionProvider public static class ClientConnectionProviderExtensions { public static ProjectOpenAIClient GetProjectOpenAIClient( this ClientConnectionProvider connectionProvider, ProjectOpenAIClientOptions options null); } public class ProjectOpenAIClient : OpenAIClient2. 模拟Agent的ReAct循环接下来我们看看一个利用OpenAIClient创建的IChatClient对象在调用LLM的时候提供的请求和响应内容是什么样子的。下面的代码模拟了一个Agent内部的执行流程ReAct循环我们使用这个Agent来根据苏州的天气给出一些着装建议。我们根据OpenAIClient创建了对应的IChatClient对象整个流程涉及两次针对它的调用。两次调用使用同一个ChatOptions对象我们为这个ChatOptions设置了系统指令你是一个深谙养身之道的时尚顾问并注册了一个用于查询天气的工具GetWeather。using dotenv.net; using Microsoft.Extensions.AI; using OpenAI; using System.ClientModel; using System.ComponentModel; DotEnv.Load(); var model Environment.GetEnvironmentVariable(MODEL)!; var apiKey Environment.GetEnvironmentVariable(API_KEY)!; var openAIUrl Environment.GetEnvironmentVariable(OPENAI_URL)!; var openAIClient new OpenAIClient( credential: new ApiKeyCredential(key: apiKey), options: new OpenAIClientOptions { Endpoint new Uri(openAIUrl) }); var chatClient openAIClient.GetResponsesClient().AsIChatClient(defaultModelId:model); var options new ChatOptions { Instructions 你是一个深谙养身之道的时尚顾问。, Tools [AIFunctionFactory.Create(GetWeather)] }; var message new ChatMessage(role: ChatRole.User, content: 根据苏州的天气给我一些着装建议。); ListChatMessage messages [message]; // First turn: user - assistant (with function call) var response await chatClient.GetResponseAsync( messages: messages, options: options); messages.AddRange(response.Messages); var functionCall response.Messages.Last().Contents.OfTypeFunctionCallContent().Single(); var tool options.Tools.Single(t t.Name functionCall.Name); var toolResult await ((AIFunction)tool).InvokeAsync(new AIFunctionArguments(functionCall.Arguments)); var toolResultMessage new ChatMessage(ChatRole.Tool, [new FunctionResultContent(functionCall.CallId, toolResult)]); messages.Add(toolResultMessage); // Second turn: user - assistant (with tool result) response await chatClient.GetResponseAsync( messages: messages, options: options); Console.WriteLine(response.Messages.Last().Text); static string GetWeather([Description(Location for weather query)] string location) ${location} 当前晴朗气温为25°C。;我们指定查询根据苏州的天气给我一些着装建议和ChatOptions调用IChatClient对象。LLM经过推理任务需要调用工具函数GetWeather来获取苏州的天气信息所以响应消息的内容列表会包含一个FunctionCallContent。在手工将响应消息添加到消息列表中后我们利用FunctionCallContent从注册的工具列表中找到对应的工具。我们将LLM提供的输入参数从FunctionCallContent提取出来后调用工具函数GetWeather得到对应的结果。接下来我们针对工具的返回结果创建一个角色为Tool的ChatMessage对象并将它添加到消息列表中。最后我们再次调用IChatClient对象来获取LLM的最终回复。此时LLM就可以根据工具的返回结果来生成最终如下所示的答案好的我们就顺着苏州此刻**25°C、晴朗**的状态从**养身 时尚**两个角度来搭配。 --- ## ️ 今日苏州着装总思路 **关键词清爽透气、遮阳不闷、早晚微调** 25°C 属于非常舒适的温度但苏州湿度通常不低**选对面料比堆叠衣服更重要**。 --- ## 上装建议 - **首选** - 棉麻衬衫浅色系米白、浅灰、雾蓝 - 薄款针织或天丝T恤 - **养身理由** - 棉麻、天丝透气吸湿减少湿热闷汗对皮肤和气血运行更友好 - **小技巧** - 避免紧身、化纤材质容易“闷火生湿” --- ## 下装建议 - **推荐** - 九分直筒裤 / 轻薄阔腿裤 - 膝下A字裙或真丝半裙 - **颜色** - 浅卡其、灰绿、烟粉色有“降燥感” - **养身点** - 不勒腹、不裹腿有助于脾胃与下肢血液循环 --- ## 鞋履选择 - **白色/浅色透气运动鞋** - **软底乐福鞋 / 平底凉鞋包后跟更养脚** - 避免全天穿完全平底或过硬的鞋对足底经络不友好 --- ## 随身加一件很关键 - **薄开衫 / 防晒衬衫** - 室内空调 早晚微风时护住肩颈 - 肩颈保暖 少落枕、少疲劳 --- ## ️ 配饰与养身小细节 - **帽子或遮阳伞**防晒就是防“耗气” - **天然材质包袋**帆布、草编更符合当下季节气场 - **配色不宜过于浓烈**春夏交替宜“柔不宜躁” --- 如果你愿意告诉我 - 是**上班 / 休闲 / 约会 / 出游** - 或偏**中性、优雅、运动风** 我可以直接帮你搭一整套「今天就能穿出门」的苏州限定穿搭 这是第一轮调用LLM提供的请求和得到的响应内容{ model: gpt-5.2-chat, tools: [ { type: function, name: _Main_g_GetWeather_0_1, description: , parameters: { type: object, required: [ location ], properties: { location: { description: Location for weather query, type: string } }, additionalProperties: false }, strict: null } ], input: [ { type: message, role: user, content: [ { type: input_text, text: 根据苏州的天气给我一些着装建议。 } ] } ], instructions: 你是一个深谙养身之道的时尚顾问。 }{ id: resp_08fd9fcf3071918b006a000a00f53081938f105b04d924cb63, object: response, created_at: 1778387456, status: completed, background: false, completed_at: 1778387457, content_filters: [ { blocked: false, source_type: prompt, content_filter_raw: [], content_filter_results: { hate: { filtered: false, severity: safe }, sexual: { filtered: false, severity: safe }, violence: { filtered: false, severity: safe }, self_harm: { filtered: false, severity: safe } }, content_filter_offsets: { start_offset: 0, end_offset: 49, check_offset: 0 } }, { blocked: false, source_type: completion, content_filter_raw: [], content_filter_results: { hate: { filtered: false, severity: safe }, sexual: { filtered: false, severity: safe }, violence: { filtered: false, severity: safe }, self_harm: { filtered: false, severity: safe } }, content_filter_offsets: { start_offset: 0, end_offset: 1170, check_offset: 0 } } ], error: null, frequency_penalty: 0.0, incomplete_details: null, instructions: 你是一个深谙养身之道的时尚顾问。, max_output_tokens: null, max_tool_calls: null, model: gpt-5.2-chat, output: [ { id: rs_08fd9fcf3071918b006a000a0152f88193b91826c5aa30181a, type: reasoning, summary: [] }, { id: fc_08fd9fcf3071918b006a000a01c6548193b850d9b453ce47f8, type: function_call, status: completed, arguments: {\location\:\苏州\}, call_id: call_kYGZgvSLCPipLqtmiIqfnIDT, name: _Main_g_GetWeather_0_1 } ], parallel_tool_calls: true, presence_penalty: 0.0, previous_response_id: null, prompt_cache_key: null, prompt_cache_retention: null, reasoning: { effort: medium, summary: null }, safety_identifier: null, service_tier: default, store: true, temperature: 1.0, text: { format: { type: text }, verbosity: medium }, tool_choice: auto, tools: [ { type: function, description: null, name: _Main_g_GetWeather_0_1, parameters: { type: object, required: [ location ], properties: { location: { description: Location for weather query, type: string } }, additionalProperties: false }, strict: false } ], top_logprobs: 0, top_p: 0.85, truncation: disabled, usage: { input_tokens: 83, input_tokens_details: { cached_tokens: 0 }, output_tokens: 43, output_tokens_details: { reasoning_tokens: 0 }, total_tokens: 126 }, user: null, metadata: {} }这是第二轮调用LLM提供的请求和得到的响应内容{ model: gpt-5.2-chat, tools: [ { type: function, name: _Main_g_GetWeather_0_1, description: , parameters: { type: object, required: [ location ], properties: { location: { description: Location for weather query, type: string } }, additionalProperties: false }, strict: null } ],

相关新闻

曲线曲面求交解析方案-平面+曲线

曲线曲面求交解析方案-平面+曲线

曲线曲面求交解析方案-平面曲线 文章目录曲线曲面求交解析方案-平面曲线一. 通用约定1. 输入对象2. 容差规则3. 结果规则二. 直线与平面求交1. 有限线段的端点距离分类2. 穿越时的精确交点3. 无限直线情况三. 圆/椭圆与平面求交1. 为什么不直接用两平面交线与圆/椭圆求交2. 统一…

2026/6/28 3:28:17阅读更多 →
2026年论文降AI保姆级教程:亲测5款好用的AI智能降重工具,教你从80%降至10%

2026年论文降AI保姆级教程:亲测5款好用的AI智能降重工具,教你从80%降至10%

2026年各大院校对AIGC的检测越来越严了!不少同学对着高AI率的文章发愁,但其实找对方法,降下来真没那么难。为了帮大家搞定AI率问题,我把市面上十几款主流降AI工具都挨个测了一遍,今天就来分享——怎么在保住文章逻辑的…

2026/6/28 3:23:16阅读更多 →
GPT-5.6 三款模型分层亮相、美团大规模开源、A 股周五大跌

GPT-5.6 三款模型分层亮相、美团大规模开源、A 股周五大跌

GPT-5.6 三款模型分层亮相、美团大规模开源、A 股周五大跌 免责声明:本文内容综合自公开媒体报道,仅供参考,不构成任何投资建议。股市有风险,投资需谨慎。作者不对因使用本文内容而产生的任何损失承担责任。 🔥 今天你…

2026/6/28 3:23:16阅读更多 →
UnityUI中使用中文文本

UnityUI中使用中文文本

生成支持中文的.asset文件找到支持中文的字体,如:Windows 系统自带:C:\Windows\Fonts\simhei.ttf(黑体)、msyh.ttf(微软雅黑)导入Unity(导入的字体文件)选中刚导入的字体文件 → 右键 → Create…

2026/6/28 5:03:22阅读更多 →
基于大数据爬虫+Hadoop+深度学习的商品管理系统

基于大数据爬虫+Hadoop+深度学习的商品管理系统

选题背景 在数字经济浪潮席卷全球的今天,电子商务已成为驱动经济增长的核心引擎之一。海量的商品数据以前所未有的速度在互联网上生成、流动与沉淀,构成了一个庞大而复杂的数字商业生态。然而,面对如此浩瀚的数据海洋,传统的商品信…

2026/6/28 5:03:22阅读更多 →
将正在运行的 shell 进程从当前终端剥离,并重新挂载到新的 screen 会话中

将正在运行的 shell 进程从当前终端剥离,并重新挂载到新的 screen 会话中

别再担心 VPN 连接断开导致远程任务被杀掉了。你可以通过分离 screen 会话并在稍后重新连接,以安全可控的方式从笔记本电脑或台式机连接到远程服务器工作。 如何将正在运行的任务从当前 shell 会话中剥离? 有几种方法可以实现这一点。最简单且最常用的方式可能是将进程放入…

2026/6/28 5:03:22阅读更多 →
BSC链空窗期黑马:Crypto Lifeline低门槛办公室经营链游

BSC链空窗期黑马:Crypto Lifeline低门槛办公室经营链游

时隔一段时间,链游板块再度受到关注。目前Solana链上有几款链游表现活跃,单个游戏日内在线人数可达数千人,其龙头代币Kins市值峰值曾突破2000万美元,在短时间内吸引了较多玩家参与,链游叙事重新成为市场讨论点之一。随…

2026/6/28 5:03:22阅读更多 →
2026年蚌埠家电清洗培训公司盘点涵盖各类信息整理

2026年蚌埠家电清洗培训公司盘点涵盖各类信息整理

导语在当今注重生活品质的时代,家电清洗服务的需求日益增长,专业的家电清洗培训公司也如雨后春笋般涌现。2026年蚌埠地区的家电清洗培训公司为有兴趣投身这一行业的人提供了学习机会。小绿人家电清洗培训作为行业内较知名的品牌,以其独特的教…

2026/6/28 5:03:22阅读更多 →
unity 2d 平调跳跃 小游戏 源码 免费开源

unity 2d 平调跳跃 小游戏 源码 免费开源

【免费】unity2d平调跳跃小游戏源码免费开源资源-CSDN下载

2026/6/28 4:58:21阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/28 0:08:01阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/28 0:08:01阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/28 0:08:01阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/28 0:08:01阅读更多 →