Semantic Kernel A2A Client 实战:用命令行构建调用远程 Agent 的 A2A 协议客户端
发布时间:2026/9/13 5:42:20 锦皓数字建站

Semantic Kernel A2A Client 实战用命令行构建调用远程 Agent 的 A2A 协议客户端【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel导读本文聚焦 Semantic Kernel 仓库中的 A2A 客户端示例dotnet/samples/Demos/A2AClientServer/A2AClient讲解如何基于 Google A2AAgent-to-Agent协议构建一个带命令行交互界面的客户端通过该客户端把远程 A2A 服务器上暴露的多个 Agent 转化为本地 Kernel 函数并借助 Chat Completion Agent 自动编排调用。读完本文你将掌握 A2A 客户端的运行方式、Secret Manager 配置方法以及A2AAgent、AgentKernelFunctionFactory与FunctionChoiceBehavior.Auto()在客户端侧的底层配合原理。示例背景A2A Client 与 A2A Server 的分工本演示包含两个组件详见 A2AClientServer 目录 READMEA2AServer需要运行三个实例分别对应 Invoice发票、Policy政策、Logistics物流三个 Agent每个实例通过 A2A 协议将单个 Agent 暴露为可访问的服务A2AClient代表一个客户端应用使用 A2A 协议连接远程 A2A 服务器从而在你提问时借助这些远程 Agent 来回答问题。客户端本身不直接持有业务数据而是通过 A2A 协议借用远端 Agent 的能力。下图展示了整个演示的架构需要特别说明的是A2A 协议仍处于快速演进阶段仓库在 A2AClientServer 目录 README 中有明确警告示例会随协议演进持续更新。快速运行三行命令启动客户端按照 A2AClient README 的说明运行客户端只需两步cd dotnet/samples/Demos/A2AClientServer/A2AClient dotnet run程序启动后会进入交互式命令行等待你输入请求例如Show me all invoices for Contoso?随后客户端会调用远程 Agent 并给出最终回答。退出交互循环的方式是在提示符后输入:q或quit这一行为定义在 Program.cs 中。用 Secret Manager 配置客户端密钥A2A 客户端需要三个配置项通过 .NET Secret Manager 写入。原文档的配置命令如下原文档中有一处引号笔误以下为修正后的可用形式cd dotnet/samples/Demos/A2AClientServer/A2AClient dotnet user-secrets set A2AClient:ModelId ... dotnet user-secrets set A2AClient:ApiKey ... dotnet user-secrets set A2AClient:AgentUrls http://localhost:5000/;http://localhost:5001/;http://localhost:5002/各配置项的具体语义、默认值与代码依据可以通过 Program.cs 确认配置项是否必填默认值说明A2AClient:ApiKey必填无缺失时抛出ArgumentException提示 A2AClient:ApiKey must be provided用于创建 OpenAI Chat Completion 的 API KeyA2AClient:ModelId可选gpt-4.1托管 AgentHost Agent使用的模型 IDA2AClient:AgentUrls可选http://localhost:5000/;http://localhost:5001/;http://localhost:5002/要连接的远程 A2A Agent 地址列表分隔符注意原文档把AgentUrls描述为空格分隔的字符串列表但示例命令与源码实现实际都以分号;分隔——Program.cs 中通过agentUrls!.Split(;)拆分因此请以分号作为分隔符。另外原文档示例中出现了http://localhost:5000/policy这类带路径的地址而代码默认值与服务器端实际映射见下文均为根路径使用默认根路径即可。配置的读取机制在 Program.csConfigurationBuilder依次加载环境变量AddEnvironmentVariables与程序集对应的 User SecretsAddUserSecrets这意味着你也可以通过环境变量注入同样的配置键。UserSecretsId定义在 A2AClient.csproj 中。客户端工作原理远程 Agent 如何变成 Kernel 函数A2A 客户端的核心逻辑集中在 HostClientAgent.cs其初始化流程清晰地展示了 Semantic Kernel 与 A2A 协议的桥接方式1. 为每个远程地址创建 A2AAgentCreateAgentAsync见 HostClientAgent.cs对每个 URL 执行创建带 60 秒超时的HttpClient用A2AClient(url, httpClient)建立 A2A 协议客户端用A2ACardResolver拉取远程服务器的 Agent Card.well-known端点返回new A2AAgent(client, agentCard)。也就是说客户端在连接时会先发现并校验远程 Agent 的能力描述Agent Card再基于它构造A2AAgent。A2AAgent是 Semantic Kernel 中基于 A2A 协议的Agent实现见 A2AAgent.cs其InvokeAsync会把TextContent转换为 A2A 的TextPart通过Client.SendMessageAsync发送message/send请求并处理AgentTask返回 artifacts与AgentMessage两类响应。2. 用 AgentKernelFunctionFactory 把 Agent 包装成函数var agents await Task.WhenAll(createAgentTasks); var agentFunctions agents.Select(agent AgentKernelFunctionFactory.CreateFromAgent(agent)).ToList(); var agentPlugin KernelPluginFactory.CreateFromFunctions(AgentPlugin, agentFunctions);代码见 HostClientAgent.cs这里发生了关键转换远程 A2A Agent 被包装为 Kernel 函数并统一注册进名为AgentPlugin的插件中。这样Host Agent一个ChatCompletionAgent就能像调用本地函数一样调用远程 Agent。3. 构建 Host Agent 并开启自动函数调用var builder Kernel.CreateBuilder(); builder.AddOpenAIChatCompletion(modelId, apiKey); builder.Plugins.Add(agentPlugin); var kernel builder.Build(); kernel.FunctionInvocationFilters.Add(new ConsoleOutputFunctionInvocationFilter()); this.Agent new ChatCompletionAgent() { Kernel kernel, Name HostClient, Instructions You specialize in handling queries for users and using your tools to provide answers., Arguments new KernelArguments(new PromptExecutionSettings() { FunctionChoiceBehavior FunctionChoiceBehavior.Auto() }), };代码见 HostClientAgent.csFunctionChoiceBehavior.Auto()让 LLM 自主决定何时调用远程 Agent 函数ConsoleOutputFunctionInvocationFilter则把每次调用哪个 Agent、传了什么参数、返回了什么结果以缩进格式打印到控制台见 HostClientAgent.cs这正是运行输出中Calling Agent ... with arguments:片段的来源。4. 命令行交互循环Program.cs 中维护一个ChatHistoryAgentThread循环读取用户输入并调用await foreach (AgentResponseItemChatMessageContent response in hostAgent.Agent!.InvokeAsync(message, thread)) { Console.ForegroundColor ConsoleColor.Cyan; Console.WriteLine($\nAgent: {response.Message.Content}); Console.ResetColor(); thread response.Thread; }每次回答后都会用返回的thread更新对话状态保证多轮对话上下文连续。整个会话置于 try/catch 中任何异常都会记录到控制台日志A2AClientlogger日志级别为Information见 Program.cs。搭配 A2AServer 跑通完整流程客户端默认连接的三个远程 Agent 正是由示例 A2AServer 提供的默认地址为http://localhost:5000/、http://localhost:5001/、http://localhost:5002/。使用 Chat Completion Agent 方式时先为服务器设置 OpenAI Keydotnet user-secrets set A2AServer:ApiKey ...然后分别启动三个服务器实例命令来自 A2AClientServer 目录 READMEcd dotnet/samples/Demos/A2AClientServer/A2AServer dotnet run --urls http://localhost:5000;https://localhost:5010 --agentType invoice dotnet run --urls http://localhost:5001;https://localhost:5011 --agentType policy dotnet run --urls http://localhost:5002;https://localhost:5012 --agentType logistics服务器端解析--agentType参数并据此创建对应 Agent见 A2AServer/Program.cs随后通过app.MapA2A(hostAgent!.TaskManager!, /)和app.MapWellKnownAgentCard(...)把 A2A 端点与 Agent Card 都映射到根路径/。三个 Agent 分别内置了不同的系统提示词与能力声明Agent Card例如 Policy Agent 固定输出 Short Shipment Dispute Handling Policy V2.1定义见 HostAgentFactory.cs。如果改用 Azure AI Foundry 中的 Agent则需设置端点并为每个实例传入--agentIddotnet user-secrets set A2AServer:Endpoint ... dotnet run --urls http://localhost:5000;https://localhost:5010 --agentId Invoice Agent Id --agentType invoicePolicy、Logistics 同理分别使用http://localhost:5001、http://localhost:5002。服务器全部就绪后回到客户端目录执行dotnet run并输入请求例如Customer is disputing transaction TICKET-XYZ987 as they claim the received fewer t-shirts than ordered.完整运行输出摘自 A2AClientServer 目录 README实际可见性取决于本次会话调用了哪些 Agentinfo: A2AClient[0] Initializing Semantic Kernel agent with model: gpt-4o-mini User (:q or quit to exit): Customer is disputing transaction TICKET-XYZ987 as they claim the received fewer t-shirts than ordered. Calling Agent InvoiceAgent with arguments: query: TICKET-XYZ987 instructions: Investigate the transaction details for TICKET-XYZ987 ... Response from Agent InvoiceAgent: The invoice associated with the transaction ID TICKET-XYZ987 is for the company Contoso. ... Calling Agent LogisticsAgent with arguments: query: TICKET-XYZ987 instructions: Check the shipping details for TICKET-XYZ987 ... Response from Agent LogisticsAgent: Shipment number: SHPMT-SAP-001 Item: TSHIRT-RED-L Quantity: 900 Calling Agent PolicyAgent with arguments: query: TICKET-XYZ987 instructions: Review the policy regarding disputes and claims ... Response from Agent PolicyAgent: Policy: Short Shipment Dispute Handling Policy V2.1 Summary: For short shipments reported by customers, ... Agent: Heres the investigation result for transaction TICKET-XYZ987: 1. **Invoice Details**: The invoice ... indicates that 150 t-shirts were ordered. 2. **Shipment Details**: The logistics records show that a total of 900 t-shirts ... ...从输出可以清晰看到三层结果先由 Host Agent 自动调用多个远程 Agent 取证最后汇总成面向用户的最终答案。Invoice Agent 的查询能力来自 InvoiceQueryPlugin.cs 中基于内存模拟数据实现的QueryByTransactionId、QueryInvoices等 Kernel 函数。验证与调试REST Client 与 A2A Inspector在启动客户端之前可以用仓库自带的 A2AServer.httpVisual Studio 的 .http 文件支持直接验证每个 Agent 是否可用查询 Agent CardGET {{hostInvoice}}/.well-known/agent-card.json发送 A2A 消息POST {{hostInvoice}}请求体为 JSON-RPC 2.0 格式的message/send调用例如{ id: 1, jsonrpc: 2.0, method: message/send, params: { id: 12345, message: { kind: message, role: user, messageId: msg_1, parts: [ { kind: text, text: Show me all invoices for Contoso? } ] } } }也可以使用 A2A InspectorWeb 端工具在浏览器中连接http://127.0.0.1:8080/并输入 Agent 地址例如http://host.docker.internal:5000它会自动校验 Agent Card、发送消息并展示原始 JSON 响应适合在排查客户端连接问题时使用。源码速览与注意事项客户端入口Program.cs —— 配置读取、命令行循环、异常处理客户端核心HostClientAgent.cs —— A2AAgent 创建、Agent→函数转换、Host Agent 构建、调用日志过滤器工程配置A2AClient.csproj —— 目标框架net10.0引用A2A、System.CommandLine、Microsoft.Extensions.Hosting包以及src/Agents/A2A、src/Agents/Core、src/Connectors/Connectors.OpenAI三个项目A2A 协议实现A2AAgent.cs 与 A2AHostAgent.cs —— 客户端侧的调用封装与服务器侧的任务管理、Agent Card 下发。几个实践要点ApiKey是唯一必填配置缺失会直接抛出异常ModelId与AgentUrls均有合理默认值最小的启动实验只需配置ApiKeyAgentUrls务必以分号;分隔多个地址A2A 协议仍在演进中示例中的A2AAgent目前只支持文本内容TextContent传入其他内容类型会抛出NotSupportedException见 A2AAgent.cs在多 Agent 协作场景下这一点需要留意。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。