[MAF的Agent管道详解-03]连接LLM的IChatClient对象
在IChatClient管道的最末端是一个与LLM进行交互的IChatClient对象,这个对象负责将最终的请求发送给LLM并返回响应结果。这个IChatClient对象的具体类型取决于我们使用的是什么模型以及模型的部署方式。系统提供了很多这样的IChatClient实现来支持不同的模型和部署方式。对于目前主流的LLM,我们都可以直接利用其客户端来创建一个对应的IChatClient对象.
1. 为三种OpenAI客户端创建IChatClient对象
OpenAIClient和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 : OpenAIClient
2. 模拟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: "根据苏州的天气给我一些着装建议。");
List<ChatMessage> 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.OfType<FunctionCallContent>().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从注册的工具列表中找到对应的工具。
m.u868jtj.cn/Article/795301.shtml
m.u868jtj.cn/Article/486903.shtml
m.u868jtj.cn/Article/264882.shtml
m.u868jtj.cn/Article/011955.shtml
m.u868jtj.cn/Article/935889.shtml
m.u868jtj.cn/Article/643126.shtml
m.u868jtj.cn/Article/511632.shtml
m.u868jtj.cn/Article/441590.shtml
m.u868jtj.cn/Article/250830.shtml
m.u868jtj.cn/Article/756187.shtml
m.u868jtj.cn/Article/909201.shtml
m.u868jtj.cn/Article/565860.shtml
m.u868jtj.cn/Article/935471.shtml
m.u868jtj.cn/Article/477663.shtml
m.u868jtj.cn/Article/796554.shtml
m.u868jtj.cn/Article/995279.shtml
m.u868jtj.cn/Article/625989.shtml
m.u868jtj.cn/Article/909081.shtml
m.u868jtj.cn/Article/013087.shtml
m.u868jtj.cn/Article/866731.shtml
m.u868jtj.cn/Article/109134.shtml
m.u868jtj.cn/Article/673545.shtml
m.u868jtj.cn/Article/654093.shtml
m.u868jtj.cn/Article/961622.shtml
m.u868jtj.cn/Article/887056.shtml
m.u868jtj.cn/Article/201495.shtml
m.u868jtj.cn/Article/195736.shtml
m.u868jtj.cn/Article/585183.shtml
m.u868jtj.cn/Article/682000.shtml
m.u868jtj.cn/Article/833829.shtml
m.u868jtj.cn/Article/565660.shtml
m.u868jtj.cn/Article/119542.shtml
m.u868jtj.cn/Article/177239.shtml
m.u868jtj.cn/Article/457083.shtml
m.u868jtj.cn/Article/447644.shtml
m.u868jtj.cn/Article/470595.shtml
m.u868jtj.cn/Article/514004.shtml
m.u868jtj.cn/Article/903446.shtml
m.u868jtj.cn/Article/156075.shtml
m.u868jtj.cn/Article/903717.shtml
m.u868jtj.cn/Article/312290.shtml
m.u868jtj.cn/Article/730281.shtml
m.u868jtj.cn/Article/872682.shtml
m.u868jtj.cn/Article/375447.shtml
m.u868jtj.cn/Article/620041.shtml
m.u868jtj.cn/Article/973019.shtml
m.u868jtj.cn/Article/369571.shtml
m.u868jtj.cn/Article/896610.shtml
m.u868jtj.cn/Article/879763.shtml
m.u868jtj.cn/Article/160722.shtml
m.u868jtj.cn/Article/584438.shtml
m.u868jtj.cn/Article/809397.shtml
m.u868jtj.cn/Article/924194.shtml
m.u868jtj.cn/Article/537552.shtml
m.u868jtj.cn/Article/824164.shtml
m.u868jtj.cn/Article/774215.shtml
m.u868jtj.cn/Article/730371.shtml
m.u868jtj.cn/Article/793381.shtml
m.u868jtj.cn/Article/356379.shtml
m.u868jtj.cn/Article/794837.shtml
m.u868jtj.cn/Article/373203.shtml
m.u868jtj.cn/Article/648989.shtml
m.u868jtj.cn/Article/397490.shtml
m.u868jtj.cn/Article/951217.shtml
m.u868jtj.cn/Article/826080.shtml
m.u868jtj.cn/Article/043431.shtml
m.u868jtj.cn/Article/538850.shtml
m.u868jtj.cn/Article/681729.shtml
m.u868jtj.cn/Article/323418.shtml
m.u868jtj.cn/Article/416736.shtml
m.u868jtj.cn/Article/556881.shtml
m.u868jtj.cn/Article/955895.shtml
m.u868jtj.cn/Article/970273.shtml
m.u868jtj.cn/Article/128750.shtml
m.u868jtj.cn/Article/216278.shtml
m.u868jtj.cn/Article/723330.shtml
m.u868jtj.cn/Article/793586.shtml
m.u868jtj.cn/Article/189386.shtml
m.u868jtj.cn/Article/223353.shtml
m.u868jtj.cn/Article/630407.shtml
m.u868jtj.cn/Article/224027.shtml
m.u868jtj.cn/Article/283313.shtml
m.u868jtj.cn/Article/890519.shtml
m.u868jtj.cn/Article/184093.shtml
m.u868jtj.cn/Article/794396.shtml
m.u868jtj.cn/Article/019970.shtml
m.u868jtj.cn/Article/398521.shtml
m.u868jtj.cn/Article/418661.shtml
m.u868jtj.cn/Article/922571.shtml
m.u868jtj.cn/Article/631605.shtml
m.u868jtj.cn/Article/347556.shtml
m.u868jtj.cn/Article/742840.shtml
m.u868jtj.cn/Article/965531.shtml
m.u868jtj.cn/Article/618094.shtml
m.u868jtj.cn/Article/346400.shtml
m.u868jtj.cn/Article/975784.shtml
m.u868jtj.cn/Article/279449.shtml
m.u868jtj.cn/Article/889497.shtml
m.u868jtj.cn/Article/661310.shtml
m.u868jtj.cn/Article/595530.shtml
m.u868jtj.cn/Article/180503.shtml
m.u868jtj.cn/Article/317853.shtml
m.u868jtj.cn/Article/668112.shtml
m.u868jtj.cn/Article/872640.shtml
m.u868jtj.cn/Article/157512.shtml
m.u868jtj.cn/Article/226029.shtml
m.u868jtj.cn/Article/222803.shtml
m.u868jtj.cn/Article/173867.shtml
m.u868jtj.cn/Article/536785.shtml
m.u868jtj.cn/Article/932832.shtml
m.u868jtj.cn/Article/768580.shtml
m.u868jtj.cn/Article/516360.shtml
m.u868jtj.cn/Article/057836.shtml
m.u868jtj.cn/Article/149488.shtml
m.u868jtj.cn/Article/349687.shtml
m.u868jtj.cn/Article/797989.shtml
m.u868jtj.cn/Article/089266.shtml
m.u868jtj.cn/Article/420551.shtml
m.u868jtj.cn/Article/862474.shtml
m.u868jtj.cn/Article/668463.shtml
m.u868jtj.cn/Article/739606.shtml
m.u868jtj.cn/Article/547867.shtml
m.u868jtj.cn/Article/351617.shtml
m.u868jtj.cn/Article/758590.shtml
m.u868jtj.cn/Article/922925.shtml
m.u868jtj.cn/Article/911340.shtml
m.u868jtj.cn/Article/677002.shtml
m.u868jtj.cn/Article/890554.shtml
m.u868jtj.cn/Article/778990.shtml
m.u868jtj.cn/Article/835948.shtml
m.u868jtj.cn/Article/425659.shtml
m.u868jtj.cn/Article/791034.shtml
m.u868jtj.cn/Article/718125.shtml
m.u868jtj.cn/Article/315903.shtml
m.u868jtj.cn/Article/231419.shtml
m.u868jtj.cn/Article/781537.shtml
m.u868jtj.cn/Article/520674.shtml
m.u868jtj.cn/Article/585453.shtml
m.u868jtj.cn/Article/647949.shtml
m.u868jtj.cn/Article/041201.shtml
m.u868jtj.cn/Article/157471.shtml
m.u868jtj.cn/Article/555454.shtml
m.u868jtj.cn/Article/317155.shtml
我们将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提供的请求和得到的响应内容:m.u868jtj.cn/Article/376850.shtml
m.u868jtj.cn/Article/537411.shtml
m.u868jtj.cn/Article/962345.shtml
m.u868jtj.cn/Article/207330.shtml
m.u868jtj.cn/Article/055860.shtml
m.u868jtj.cn/Article/061286.shtml
m.u868jtj.cn/Article/358081.shtml
m.u868jtj.cn/Article/076371.shtml
m.u868jtj.cn/Article/638054.shtml
m.u868jtj.cn/Article/041820.shtml
m.u868jtj.cn/Article/626280.shtml
m.u868jtj.cn/Article/959720.shtml
m.u868jtj.cn/Article/577904.shtml
m.u868jtj.cn/Article/455800.shtml
m.u868jtj.cn/Article/170256.shtml
m.u868jtj.cn/Article/548895.shtml
m.u868jtj.cn/Article/981782.shtml
m.u868jtj.cn/Article/101364.shtml
m.u868jtj.cn/Article/884406.shtml
{
"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": "根据苏州的天气给我一些着装建议。"
}
]
},
{
"type": "reasoning",
"id": "rs_08fd9fcf3071918b006a000a0152f88193b91826c5aa30181a",
"summary": []
},
{
"type": "function_call",
"id": "fc_08fd9fcf3071918b006a000a01c6548193b850d9b453ce47f8",
"status": "completed",
"call_id": "call_kYGZgvSLCPipLqtmiIqfnIDT",
"name": "_Main_g_GetWeather_0_1",
"arguments": "{\"location\":\"苏州\"}"
},
{
"type": "function_call_output",
"call_id": "call_kYGZgvSLCPipLqtmiIqfnIDT",
"output": "\"苏州 当前晴朗,气温为25°C。\""
}
],
"instructions": "你是一个深谙养身之道的时尚顾问。"
}
{
"id": "resp_08fd9fcf3071918b006a000a025fbc8193a1219305fbea8789",
"object": "response",
"created_at": 1778387458,
"status": "completed",
"background": false,
"completed_at": 1778387467,
"content_filters": [
{
"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": 1912,
"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": "msg_08fd9fcf3071918b006a000a02c53c819385543898398da88e",
"type": "message",
"status": "completed",
"content": [
{
"type": "output_text",
"annotations": [],
"logprobs": [],
"text": "...(同上面展示的LLM最终回复内容)..."
}
],
"role": "assistant"
}
],
"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": 157,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 612,
"output_tokens_details": {
"reasoning_tokens": 0
},
"total_tokens": 769
},
"user": null,
"metadata": {}
}
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)