微软开源的 Agent Framework 为开发者提供了一套简洁而强大的工具,用于构建具备上下文记忆和多轮对话能力的智能体应用。本文将以一个实战示例,演示如何利用其中的 AgentThread 对象,轻松实现同一个 Agent 的连续对话。
核心概念:AgentThread 与上下文管理
在构建对话式AI应用时,上下文管理是关键挑战。微软 Agent Framework 通过 AgentThread 对象优雅地解决了这一问题。AgentThread 可以理解为一次独立的对话会话,它自动维护和管理该会话中的所有历史消息。开发者无需手动拼接和传递对话历史,只需在调用 Agent 时传入同一个 thread 对象,框架即可确保后续请求基于之前的对话上下文进行响应,从而实现真正的多轮对话。
实战:创建一个会讲故事的江湖说书人Agent
下面我们通过一个完整的 C# 控制台应用示例,创建一个具有特定人设(江湖说书人)的 AI Agent,并体验其多轮对话能力。
1. 项目初始化与包引用
首先,创建一个 .NET 控制台应用,并通过 NuGet 添加必要的依赖包:
dotnet add package Azure.AI.OpenAI
dotnet add package Microsoft.Agents.AI.OpenAI
dotnet add package Microsoft.Extensions.AI.OpenAI
dotnet add package Azure.Identity
这些包分别提供了 Azure OpenAI 的客户端、微软 Agent Framework 的集成、扩展功能以及 Azure 身份认证支持。
2. 核心代码实现
以下是完整的示例代码,它创建了一个 Agent,并通过两个独立的 AgentThread 进行多轮对话。
// Copyright (c) Microsoft. All rights reserved.
// This sample shows how to create and use a simple AI agent with a multi-turn conversation.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI;
using System.Text;
Console.InputEncoding = Encoding.UTF8;
Console.OutputEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
// 从环境变量获取 Azure OpenAI 终结点和部署名
var endpoint = Environment.GetEnvironmentVariable(“AZURE_OPENAI_ENDPOINT”) ?? throw new InvalidOperationException(“AZURE_OPENAI_ENDPOINT is not set.”);
var deploymentName = Environment.GetEnvironmentVariable(“AZURE_OPENAI_DEPLOYMENT_NAME”) ?? “gpt-4o-mini”;
// 1. 创建具有特定人设的 AI Agent
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: “你是一位江湖说书人,擅长用幽默、接地气的方式讲笑话和故事。”, name: “Joker”);
// 2. 创建第一个对话线程 (Thread),并进行两轮交互
AgentThread thread = agent.GetNewThread();
Console.WriteLine(await agent.RunAsync(“给我讲一个发生在茶馆里的段子,轻松一点的那种。”, thread));
Console.WriteLine(await agent.RunAsync(“现在把这个段子加上一些表情符号,并用说书人的语气再讲一遍。”, thread));
// 3. 创建第二个独立的对话线程,体验另一组多轮对话
thread = agent.GetNewThread();
Console.WriteLine(await agent.RunAsync(“再讲一个关于江湖侠客的小笑话,要幽默一点。”, thread));
Console.WriteLine(await agent.RunAsync(“给这个江湖侠客的小笑话加些表情符号,再添加点夸张的江湖腔。”, thread));
// 以下是流式输出(Streaming)的调用方式,适合需要实时显示生成内容的场景
// await foreach (var update in agent.RunStreamingAsync(“再讲一个关于江湖侠客的小笑话,要幽默一点。”, thread))
// {
// Console.Write(update);
// }
3. 运行结果示例
执行上述代码,Agent 会基于我们设定的“江湖说书人”角色生成内容。例如,第一组对话的产出可能如下:
第一轮请求输出:
话说啊,这江湖上最大的事儿,归根结底就是两件儿——喝茶和扯皮。要说这茶馆儿,嘿,那可是江湖的大本营...全场顿时哄堂大笑,这就是江湖嘛,吹牛为主,动手为辅,嗓门最大才是真高手!
基于上下文的第二轮请求输出:
好嘞!客官您稍坐,听我慢慢道来~ 📜🍵咱说这江湖啊,那不外乎两件事儿:喝茶,扯皮!这茶馆喽,嘿,那可是不打眼的地方,却是江湖大侠的聚集地...不愧是江湖,这高手过招“吹牛为主,动手为辅”,嗓门最大,才是天下第一啊!🎤👊
可以看到,在第二个请求中,Agent 不仅记住了第一个请求中生成的茶馆段子内容,还准确地按照新指令添加了表情符号,并强化了说书人的语气。
关键技术要点解析
- 上下文管理的简化:
AgentThread 是管理多轮对话上下文的精髓。框架将其封装成一个透明组件,开发者只需创建并传递该对象,极大地减轻了对话状态管理的负担。
- Agent 角色设定:通过
CreateAIAgent 方法中的 instructions 参数,可以非常直观地为智能体赋予个性、知识背景或行为准则。这使得构建专业领域的对话机器人(如客服、导师、角色扮演)变得非常简单。
- 两种输出模式:
RunAsync:一次性获取完整的回复内容,适用于大多数场景。
RunStreamingAsync:以流式(Streaming)方式逐步获取回复,能够提供更实时、更流畅的用户交互体验,尤其适合生成较长文本时。
- 灵活的适用场景:此模式可广泛应用于智能客服、互动教学、游戏NPC、内容创作助手以及各类需要理解上下文的AI Agent和工具型界面中。
总结
通过这个实战案例可以看出,微软 Agent Framework 通过 AgentThread 等抽象,将复杂的对话状态管理、角色设定和 API 调用封装成简洁易用的接口。开发者可以聚焦于业务逻辑和提示词工程,快速构建出体验良好的多轮对话应用。对于使用 C# .NET 技术栈的团队来说,这是一套非常值得集成和探索的高效开发框架。
示例源代码地址:
https://github.com/bingbing-gui/aspnetcore-developer/tree/master/src/09-AI-Agent/Agent-Framework/MultiturnConversation