mcpField
W
working-with-ms-agent-framework

working-with-ms-agent-framework

github.com/mhagreliusAgent 工作流42 次安装
代码仓库

关于 working-with-ms-agent-framework

这是一份使用 Microsoft Agent Framework 构建 Agent 的参考技能,涵盖状态管理、上下文提供程序、编排、持久化和开发界面,也介绍从 Semantic Kernel 或 AutoGen 迁移。

主要功能

  1. 01Agent 与线程架构
  2. 02基于策略的上下文与记忆
  3. 03五种编排模式
  4. 04线程序列化与工作流检查点
  5. 05DevUI 配置与追踪
  6. 06从 Semantic Kernel 和 AutoGen 迁移

适用场景

  1. 01设计多 Agent 工作流
  2. 02持久化并恢复 Agent 对话
  3. 03添加受策略控制的上下文
  4. 04将项目从 Semantic Kernel 或 AutoGen 迁移

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mhagrelius/dotfiles --skill working-with-ms-agent-framework

安装后在 Claude Code 中输入/working-with-ms-agent-framework确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

context-providers.md
design-patterns.md
orchestration-patterns.md

详细介绍

使用 Microsoft Agent Framework

Microsoft Agent Framework(2025 年 10 月)将 Semantic Kernel 和 AutoGen 整合到一个 SDK 中。这两个旧框架均处于维护模式。

核心原则: Agent 是无状态的。所有状态都存储在线程中。上下文提供程序会强制执行相关策略,决定哪些内容以何种方式、在何时进入提示词,以及何时衰减。

此技能中的其他参考文件:

  • context-providers.md - 基于策略的记忆、胶囊模式、Mem0 集成
  • orchestration-patterns.md - 5 种编排模式及使用时机指南
  • design-patterns.md - 生产模式、测试、迁移

适用场景

  • 使用 Microsoft 的统一框架构建 AI Agent
  • 使用上下文提供程序实现自定义记忆
  • 创建支持检查点的多 Agent 工作流
  • 从 Semantic Kernel 或 AutoGen 迁移

不适用场景

  • 简单的单轮大模型调用(直接使用聊天客户端)
  • 继续使用旧版 SK/AutoGen 的项目
  • 非 Microsoft 框架(LangChain、CrewAI)

技术栈层级

官方指南(PM Jeremy Licknes): 从 ME AI 开始,仅在需要时升级。

层级用途何时升级
ME AI(Microsoft.Extensions.AI)聊天客户端、结构化输出、嵌入、中间件需要 Agent、工作流、记忆时
Agent FrameworkAgent、线程、编排、上下文提供程序需要特定的 SK 适配器时
Semantic KernelME AI 中没有的特定适配器、实用工具永远不要从这里开始
ME AI (foundation) → Agent Framework (agents/workflows) → SK (specific utilities only)

关键见解: ME AI 提供可用于 OpenAI、Ollama、Foundry Local 等平台的通用 API。Agent Framework 基于 ME AI 构建,提供 Agent 模式。SK 基础功能已迁移到 ME AI;仅在需要 ME AI 尚未提供的特定适配器时使用 SK。

ME AI 自动提供的功能:

  • 结构化输出(通过扩展方法提供类型化响应)
  • 中间件(OpenTelemetry、聊天内容缩减)
  • 通用聊天客户端抽象
  • 嵌入生成

架构速览

概念C# 类型用途
AgentAIAgent无状态的大模型封装器
线程AgentThread有状态的对话容器
上下文提供程序AIContextBehavior基于策略的记忆/上下文注入
编排SequentialOrchestration 等多 Agent 协调

安装

dotnet add package Microsoft.Agents.AI.OpenAI --prerelease
dotnet add package Azure.AI.OpenAI --version 2.1.0

创建 Agent

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

// Azure OpenAI
AIAgent agent = new AzureOpenAIClient(
    new Uri("https://<resource>.openai.azure.com"),
    new AzureCliCredential())
        .GetChatClient("gpt-4o-mini")
        .CreateAIAgent(
            instructions: "You are a helpful assistant.",
            name: "Assistant");

// Direct OpenAI
var agent = new OpenAIClient("api-key")
    .GetChatClient("gpt-4o-mini")
    .AsIChatClient()
    .CreateAIAgent(instructions: "...", name: "Assistant");

// With tools
[Description("Gets weather for a location")]
static string GetWeather(string location) => $"Sunny in {location}";

AIAgent agent = chatClient.CreateAIAgent(
    instructions: "You help with weather queries.",
    tools: [AIFunctionFactory.Create(GetWeather)]
);

执行

// Simple
Console.WriteLine(await agent.RunAsync("Hello!"));

// With thread for multi-turn
AgentThread thread = agent.GetNewThread();
await agent.RunAsync("My name is Alice.", thread);
await agent.RunAsync("What's my name?", thread); // Remembers "Alice"

// Streaming
await foreach (var update in agent.RunStreamingAsync("Tell me a story.", thread))
{
    Console.Write(update.Text);
}

具备弹性的流式处理

对于生产环境中的流式处理,请添加取消支持和弹性机制:

// Basic streaming with cancellation
await foreach (var update in agent.RunStreamingAsync("Tell me a story.", thread)
    .WithCancellation(cancellationToken))
{
    Console.Write(update.Text);
}

// With Polly resilience pipeline
var pipeline = new ResiliencePipelineBuilder()
    .AddRetry(new RetryStrategyOptions { MaxRetryAttempts = 3 })
    .AddTimeout(TimeSpan.FromMinutes(2))
    .Build();

await pipeline.ExecuteAsync(async token =>
{
    await foreach (var chunk in agent.RunStreamingAsync(userMessage, thread)
        .WithCancellation(token))
    {
        Console.Write(chunk.Text);
    }
}, cancellationToken);

错误区分:

  • OperationCanceledException:用户取消
  • TimeoutRejectedException:Polly 超时
  • HttpRequestException:网络问题

开发界面(DevUI)

用于测试 Agent 和工作流的轻量级 Web 界面。仅用于开发,不适用于生产环境。

Python 设置

安装:

pip install agent-framework-devui --pre

选项 1:以编程方式注册

from agent_framework import ChatAgent
from agent_framework.openai import OpenAIChatClient
from agent_framework.devui import serve

agent = ChatAgent(
    name="WeatherAgent",
    chat_client=OpenAIChatClient(),
    tools=[get_weather]
)

# Launch DevUI with tracing
serve(entities=[agent], auto_open=True, tracing_enabled=True)
# Opens browser to http://localhost:8080

选项 2:目录发现(CLI)

devui ./entities --port 8080 --tracing

用于发现的目录结构:

entities/
    weather_agent/
        __init__.py      # Must export: agent = ChatAgent(...)
        .env             # Optional: API keys
    my_workflow/
        __init__.py      # Must export: workflow = WorkflowBuilder()...
C# 设置

C# 将 DevUI 作为 SDK 组件嵌入(文档正在编写中):

var app = builder.Build();

app.MapOpenAIResponses();
app.MapConversation();

if (app.Environment.IsDevelopment())
{
    app.MapAgentUI(); // Accessible at /ui
}
功能
功能描述
Web 界面交互式测试 Agent/工作流
兼容 OpenAI 的 API使用 OpenAI SDK 调用本地 Agent
追踪在调试面板中查看 OpenTelemetry spans
文件上传多模态输入(图像、文档)
自动生成输入根据第一个执行器类型生成工作流输入
在 DevUI 中追踪

使用 --tracing 标志或 tracing_enabled=True 启用。在调试面板中查看:

Agent Execution
├── LLM Call (prompt → response)
├── Tool Call
│   ├── Tool Execution
│   └── Tool Result
└── LLM Call (prompt → response)

导出到外部工具(Jaeger、Azure Monitor):

export OTLP_ENDPOINT="http://localhost:4317"
devui ./entities --tracing
OpenAI SDK 集成

通过 OpenAI Python SDK 与 DevUI Agent 交互:

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8080/v1", api_key="not-needed")
response = client.responses.create(
    metadata={"entity_id": "weather_agent"},
    input="What's the weather in Seattle?"
)
CLI 选项
devui [directory] [options]
  --port, -p      Port (default: 8080)
  --tracing       Enable OpenTelemetry tracing
  --reload        Auto-reload on file changes
  --headless      API only, no UI
  --mode          developer|user (default: developer)

线程序列化(关键模式)

// Serialize for persistence
JsonElement serialized = await thread.SerializeAsync();
await File.WriteAllTextAsync("thread.json", serialized.GetRawText());

// Later: restore and resume
string json = await File.ReadAllTextAsync("thread.json");
JsonElement element = JsonSerializer.Deserialize<JsonElement>(json);
AgentThread restored = agent.DeserializeThread(element, JsonSerializerOptions.Web);
await agent.RunAsync("Continue...", restored);

关键行为:

  • 服务管理的线程:仅序列化线程 ID
  • 内存中的线程:序列化所有消息
  • 警告:使用不同的 Agent 配置进行反序列化可能会出错

上下文提供程序(基于策略的记忆)

上下文提供程序不是“记忆注入”,而是策略执行:

策略决定内容
选择什么内容成为记忆
门控何时检索记忆
衰减何时过期
避免噪声何时不使用
ChatHistoryAgentThread thread = new();

// Long-term user memory
thread.AIContextProviders.Add(new Mem0Provider(httpClient, new() { UserId = "user123" }));

// Short-term conversation context
thread.AIContextProviders.Add(new WhiteboardProvider(chatClient));

// RAG integration
thread.AIContextProviders.Add(new TextSearchProvider(textSearch, new()
{
    SearchTime = TextSearchProviderOptions.RagBehavior.OnDemandFunctionCalling
}));

自定义实现模式请参阅 context-providers.md。

编排模式

模式适用场景
顺序依赖关系明确(起草 → 审阅 → 润色)
并发独立视角、集成推理
交接事先无法确定最佳 Agent,需要动态调度专业能力
GroupChat协作构思、人在回路
Magentic复杂的开放式问题
// Sequential
SequentialOrchestration orchestration = new(analystAgent, writerAgent);

// Handoff - CRITICAL: Always set termination conditions!
var workflow = AgentWorkflowBuilder.StartHandoffWith(triageAgent)
    .WithHandoffs(triageAgent, [mathTutor, historyTutor])
    .WithHandoff(mathTutor, triageAgent)      // Allows routing back
    .WithHandoff(historyTutor, triageAgent)
    .WithMaxHandoffs(10)                      // REQUIRED: Prevent infinite loops
    .Build();

// Execute
InProcessRuntime runtime = new();
await runtime.StartAsync();
var result = await orchestration.InvokeAsync(task, runtime);

交接的关键注意事项:缺少 .WithMaxHandoffs() 会导致无限循环。务必设置终止条件。

详细模式和适用场景指南请参阅 orchestration-patterns.md。

工作流检查点与持久性

对于必须在进程重启后继续运行的工作流:

// Basic checkpointing with CheckpointManager
var checkpointManager = CheckpointManager.Default;

await using Checkpointed<StreamingRun> checkpointedRun =
    await InProcessExecution.StreamAsync(workflow, input, checkpointManager);

// Resume from checkpoint
await InProcessExecution.ResumeStreamAsync(savedCheckpoint, checkpointManager);
基于线程的持久化模式

对于长时间运行的工作流,在每个步骤后检查点保存线程状态:

// Save thread state after each workflow step
var serialized = await thread.SerializeAsync();
await checkpointStore.SaveAsync(workflowId, currentStep, serialized.GetRawText());

// Resume after restart
var json = await checkpointStore.GetAsync(workflowId);
var element = JsonSerializer.Deserialize<JsonElement>(json);
var restored = agent.DeserializeThread(element, JsonSerializerOptions.Web);
await agent.RunAsync(nextStep, restored);
启动时恢复
public class WorkflowRecoveryService : BackgroundService
{
    private readonly ICheckpointStore _store;
    private readonly AIAgent _agent;

    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        var pending = await _store.GetPendingWorkflowsAsync();
        foreach (var workflow in pending)
        {
            var thread = _agent.DeserializeThread(workflow.State, JsonSerializerOptions.Web);
            await _agent.RunAsync(workflow.NextStep, thread, cancellationToken: ct);
        }
    }
}

关键原则:每个步骤完成后再创建检查点,而不是之前。这样可确保从最后一个成功完成的步骤继续执行。

迁移速查

从 Semantic Kernel 迁移
SKAgent Framework
KernelAIAgent
ChatHistoryAgentThread
方法上的 [KernelFunction][Description]
IPromptFilterAIContextBehavior
KernelFunctionFactory.CreateFromMethodAIFunctionFactory.Create
从 AutoGen 迁移
AutoGenAgent Framework
AssistantAgent通过 CreateAIAgent() 创建 AIAgent
FunctionToolAIFunctionFactory.Create()
GroupChat/TeamsWorkflowBuilder 模式
TopicSubscriptionAgentWorkflowBuilder.WithHandoffs()
BaseAgent, IHandle<>配备工具的 AIAgent

从基于主题的模式迁移到交接模式:

// ❌ OLD AutoGen pattern (deprecated)
[TopicSubscription("queries")]
public class MyAgent : BaseAgent, IHandle<Query>
{
    public async Task Handle(Query msg, CancellationToken ct)
    {
        // Process and publish to another topic
        await PublishMessageAsync(new Response(...), "responses");
    }
}

// ✅ NEW Agent Framework pattern
var triageAgent = chatClient.CreateAIAgent(
    instructions: "Route queries to appropriate specialist.",
    name: "Triage");

var mathAgent = chatClient.CreateAIAgent(
    instructions: "Handle math queries.",
    name: "Math");

var workflow = AgentWorkflowBuilder.StartHandoffWith(triageAgent)
    .WithHandoffs(triageAgent, [mathAgent, otherAgent])
    .WithMaxHandoffs(10)  // REQUIRED
    .Build();

await workflow.InvokeStreamingAsync(input, runtime);

反模式

不要这样做应这样做
在 Agent 实例中存储状态所有状态都使用 AgentThread 存储
仅序列化消息序列化整个线程
在工作流中共享 Agent 实例使用工厂模式
在服务之间混用线程类型线程特定于各自的服务
顺序模式足以满足需求时仍使用 Magentic使用能解决问题的最简单模式
使用 ContextualFunctionProvider 时跳过 UseImmutableKernel始终设置 UseImmutableKernel = true
新项目从 Semantic Kernel 入手从 ME AI 入手,必要时再升级到 Agent Framework

警示信号——停止

  • 使用 Kernel 而非 AIAgent(旧版 SK)
  • 使用 AssistantAgent 而非 AIAgent(旧版 AutoGen)
  • 线程反序列化失败(上下文提供程序缺少序列化构造函数)
  • 会话之间记忆丢失(序列化了消息而非线程)
  • 交接陷入无限循环(需要设置终止条件)

已知限制

  • 分布式运行时:仅支持进程内执行;计划支持分布式执行
  • C# Magentic:大多数示例使用 Python
  • C# 消息存储:Redis/数据库需要自定义实现
  • Token 计数:提供程序中的预算计算没有文档说明
  • DevUI C# 文档:Python 文档完整;C# DevUI 文档“即将推出”(嵌入式 SDK 的实现方式有所不同)
  • GA 时间线:Agent Framework 稳定版“即将推出”(截至 2025 年 1 月)

资源

  • GitHub:github.com/microsoft/agent-framework
  • 文档:learn.microsoft.com/en-us/agent-framework/
  • 迁移指南:learn.microsoft.com/en-us/agent-framework/migration-guide/

评论

支持 Markdown