深入.NET AI Agent开发:利用Microsoft.Agents.AI提取思考、调用工具与执行脚本
时间:2026-06-07 16:43
在基于 NET 的 AI Agent 开发领域,`Microsoft Agents AI` 这套抽象层可称得上是一把利器,它让开发者能够直观地构建具备工具调用、思考过程展示乃至自定义脚本执行能力的智能体。本文将从实际代码片段入手,深入探讨如何利用该框架提取模型的思考过程(Reasoning)、处理
在基于 .NET 的 AI Agent 开发领域,`Microsoft.Agents.AI` 这套抽象层可称得上是一把利器,它让开发者能够直观地构建具备工具调用、思考过程展示乃至自定义脚本执行能力的智能体。本文将从实际代码片段入手,深入探讨如何利用该框架提取模型的思考过程(Reasoning)、处理工具调用(Tool Calls),以及安全地将外部脚本作为 Agent 的 Skill 运行起来。
先从整体架构说起。
## 整体架构概览
示例中的 `AIAgentService` 作为整个系统的核心服务,主要负责创建 OpenAI 兼容的聊天客户端,并进一步封装为 `AIAgent`。具体实现流程如下:
1. **配置 OpenAI 客户端**:支持自定义端点、超时时间以及重试策略的设置。
2. **启用或禁用工具与技能**:通过 `AISetting` 控制是否注入工具列表(`Tools`)和技能上下文提供者(`AIContextProviders`)。
3. **发送消息并获取响应**:支持流式(`RunStreamingAsync`)和非流式(`RunAsync`)两种模式。
4. **在流式输出中解析结构化内容**:通过判断 `update.Contents` 中的具体类型,捕获工具调用、工具结果和普通文本,同时从原始响应中提取模型的思考过程。
## 提取思考过程(Reasoning)
许多大语言模型,例如 OpenAI 的 o1 系列,在生成最终答案之前会先输出一段内部的“思考链”(reasoning tokens)。`Microsoft.Agents.AI` 中的 `AgentResponseUpdate` 对象在流式模式下提供了 `RawRepresentation`,使我们能够访问底层模型的原始更新。
方法 `GetReasoningTextAsync` 展示了完整的提取逻辑。其原理并不复杂:`StreamingChatCompletionUpdate.Patch` 是一个 `JsonPatch` 对象,包含了本次增量更新的原始 JSON 数据。通过调用 `TryGetJson` 并指定 JSONPath `$.choices`,可以获取 `choices` 数组的完整片段。接着遍历数组中的每个 `choice`,在 `delta` 中查找 `reasoning` 或 `reasoning_content` 字段(兼容不同模型),将字符串值拼接起来,便得到了模型的思考过程。
这样一来,即使框架的上层接口没有直接暴露 reasoning,我们也能通过原始数据将其提取出来并单独回调,实现思考过程的实时展示。
## 处理工具调用(Tool Calls)
在 `AIAgent` 的流式响应循环中,`update.Contents` 是一系列 `AIContent` 派生对象。我们可以根据具体类型,区分工具调用请求和工具执行结果。
代码逻辑清晰明了:
- `FunctionCallContent` 表示模型请求调用某个函数,包含 `Name`、`CallId` 和 `Arguments`(JSON 对象)。序列化后通过回调通知外部系统,便于记录或展示。
- `FunctionResultContent` 在工具执行完成后出现,包含调用 ID 和结果。同样通过回调传递,有助于构建完整的对话记录。
- `TextContent` 通常对应普通文本输出,但框架一般会将文本聚合到 `update.Text` 属性中,因此此处主要处理非文本类型。
借助这种模式,Agent 执行过程中工具调用的状态可以被实时监控,无论是日志记录还是界面更新都变得十分便捷。
## 执行 Skill 脚本
在 `Microsoft.Agents.AI` 中,`AgentFileSkill` 允许将外部脚本(如 Python、Shell、PowerShell)注册为 Agent 的技能。`PySubprocessScriptRunner` 类展示了一个通用的脚本执行器,其核心方法是 `StaticRunAsync`。
### 脚本类型与解释器选择
根据脚本文件的扩展名动态决定启动进程的命令。例如,`.py` 文件使用 `python`,`.sh` 文件使用 `bash`,`.ps1` 文件根据操作系统选择 `powershell` 或 `pwsh`,其他情况直接执行。
### 进程配置与编码处理
为避免跨平台输出乱码,`CreateStartInfo` 方法会根据运行平台设置编码:Windows 使用默认编码,其他系统使用 UTF-8。同时启用输入输出重定向,并禁用 Shell 执行,确保安全性。
### 向脚本传递参数
Agent 调用技能时会传入 `arguments`(`JsonElement?` 类型),脚本执行器将其序列化为 JSON 字符串,通过标准输入(stdin)传递给脚本。这要求脚本能够从 stdin 读取 JSON 数据并自行解析。
### 异步执行与结果处理
进程启动后立即开始异步读取标准输出和标准错误,然后等待进程结束或被取消。如果退出码不为零,则抛出异常并附带错误信息;否则,尝试将输出反序列化为 JSON 对象,失败时返回原始字符串。这样一来,Agent 便能把脚本结果当作工具返回值,参与后续对话。
## 总结
从这些代码实践中可以看出,`Microsoft.Agents.AI` 框架的灵活性和扩展性相当出色:
- **思考过程提取**:借助原始响应中的 JSON Patch 数据,轻松穿透抽象层获取模型内部推理细节。
- **工具调用监控**:通过 `update.Contents` 的多态类型判断,精准拦截和展示工具调用请求与结果。
- **Skill 脚本执行**:将外部脚本无缝集成为 Agent 的工具,通过子进程调用并传递 JSON 参数,实现语言模型与本地代码的协同工作。
结合这些技术,开发者能够构建出功能强大、可观测性高、且能充分利用现有代码资产的 AI Agent 系统。无论是增强对话体验,还是整合复杂的业务逻辑,`Microsoft.Agents.AI` 都提供了坚实的基础。
## 代码开源地址
NetCoreKevin 框架下的 kevin.AI.AgentFramework 模块,是基于 .NET 构建的企业级 SaaS AI 智能体应用架构。
项目地址:
github:[https://github.com/junkai-li/NetCoreKevin](https://github.com/junkai-li/NetCoreKevin)
Gitee: [https://gitee.com/netkevin-li/NetCoreKevin](https://gitee.com/netkevin-li/NetCoreKevin)
来源:https://cloud.tencent.com.cn/developer/article/2674704
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。