核心组件
用户输入 → AI代理 → 工具调用 → 外部服务
         ↓                    ↓
      LLM处理            MCP服务器
         ↓                    ↓
      决策逻辑  ←  执行结果  ←
         ↓
      响应生成
增强组件
  • 会话(Session):管理多轮对话状态
  • 上下文提供者(Context Provider):提供代理记忆能力
  • 中间件(Middleware):拦截和增强代理行为
  • 工具集成:通过MCP客户端集成外部工具
适用场景

✅ 适合使用AI代理的场景:

  • 客户支持:处理多模态查询(文本、语音、图像)
  • 教育辅导:利用外部知识库提供个性化辅导
  • 代码生成与调试:辅助开发者进行实现、代码审查和调试
  • 研究助手:搜索网络、总结文档、整合多源信息
  • 动态任务处理:需要自主决策、临时规划和试错探索的场景

❌ 不适合使用AI代理的场景:

  • 高度结构化且需要严格遵循预定义规则的任务
  • 可以直接编写函数处理的确定性任务
  • 简单的CRUD操作
  • 需要100%确定性结果的场景

关键原则如果可以编写函数来处理任务,就直接编写函数,而不是使用AI代理。可以用AI辅助编写函数。

2. 工作流(Workflows)

定义

工作流是一种图形化的执行流程,它可以连接多个AI代理和函数来执行复杂的多步骤任务,同时保持一致性和可靠性。

工作流结构
开始节点
   ↓
AI代理1 → 决策节点 → AI代理2
   ↓          ↓         ↓
函数调用  ← 条件路由  → 并行处理
   ↓                     ↓
结束节点  ←  汇总结果  ←
核心特性
  1. 模块化:可分解为更小的可重用组件
  2. 代理集成:可整合多个AI代理和非代理组件
  3. 类型安全:强类型确保组件间消息正确流转
  4. 灵活控制流:支持条件路由、并行处理和动态执行路径
  5. 外部集成:内置请求/响应模式用于系统集成
  6. 检查点机制:保存工作流状态,支持恢复和续接
  7. 多代理编排:内置顺序、并发、移交等编排模式
  8. 可组合性:工作流可嵌套或组合创建更复杂流程
AI代理 vs 工作流对比
特性 AI代理 工作流
执行方式 LLM驱动的动态步骤 预定义的操作序列
决策方式 基于对话上下文和可用工具自动决定 明确定义的流程路径
适用任务 非结构化、需要探索的任务 结构化、多步骤的复杂任务
控制程度 较低(LLM自主决策) 较高(显式定义)
可预测性 较低 较高

安装与配置

.NET环境要求

# 前置条件
- .NET 8.0 SDK 或更高版本
- Azure OpenAI 资源(已部署模型,如 gpt-4o-mini)
- Azure CLI(已安装并认证,可选)

创建项目

# 创建新控制台应用
dotnet new console -o AgentFrameworkDemo
cd AgentFrameworkDemo

安装NuGet包

# 安装核心包(实际使用的包)
dotnet add package Azure.AI.OpenAI --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.Configuration.Json

# 注意:Microsoft.Agents.AI 包仍在开发中
# 当前示例使用 Azure.AI.OpenAI 实现相同功能

配置Azure认证

# 使用Azure CLI登录(可选)
az login

# 确保账户具有以下角色之一:
# - Cognitive Services OpenAI User
# - Cognitive Services OpenAI Contributor

创建配置文件

创建 appsettings.json 文件:

{
  "AzureOpenAI": {
    "Endpoint": "https://your-resource.openai.azure.com/",
    "DeploymentName": "gpt-4o-mini",
    "ApiKey": ""
  }
}

注意

  • Endpoint: 你的 Azure OpenAI 资源端点
  • DeploymentName: 部署的模型名称(如 gpt-4o-mini, gpt-4o)
  • ApiKey: 可留空使用 Azure CLI 认证,或填入 API 密钥

快速入门

基础AI代理示例(C#)

注意:Microsoft Agent Framework 目前仍在预览阶段,本示例使用 Azure OpenAI SDK 实现相同的功能。

using System;
using Azure;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using OpenAI.Chat;

// 加载配置
var configuration = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .Build();

var endpoint = configuration["AzureOpenAI:Endpoint"];
var deploymentName = configuration["AzureOpenAI:DeploymentName"];
var apiKey = configuration["AzureOpenAI:ApiKey"];

// 创建Azure OpenAI客户端
AzureOpenAIClient openAIClient;

if (!string.IsNullOrEmpty(apiKey))
{
    // 使用API Key认证
    openAIClient = new AzureOpenAIClient(
        new Uri(endpoint),
        new AzureKeyCredential(apiKey)
    );
}
else
{
    // 使用Azure CLI认证
    openAIClient = new AzureOpenAIClient(
        new Uri(endpoint),
        new AzureCliCredential()
    );
}

// 获取聊天客户端
var chatClient = openAIClient.GetChatClient(deploymentName);

// 创建对话
var messages = new List<ChatMessage>
{
    new SystemChatMessage("You are good at telling jokes."),
    new UserChatMessage("Tell me a joke about a pirate.")
};

var response = await chatClient.CompleteChatAsync(messages);
Console.WriteLine(response.Value.Content[0].Text);

配置文件示例

创建 appsettings.json 文件:

{
  "AzureOpenAI": {
    "Endpoint": "https://your-resource.openai.azure.com/",
    "DeploymentName": "gpt-4o-mini",
    "ApiKey": ""
  }
}

Python快速示例

import asyncio
from agent_framework.azure import AzureAIClient
from azure.identity.aio import AzureCliCredential

async def main():
    async with (
        AzureCliCredential() as credential,
        AzureAIClient(async_credential=credential).as_agent(
            name="JokeAgent",
            instructions="You are good at telling jokes.",
        ) as agent,
    ):
        result = await agent.run("Tell me a joke about a pirate.")
        print(result.text)

if __name__ == "__main__":
    asyncio.run(main())

AI代理详解

代理工具(Agent Tools / Function Calling)

定义工具函数
using System.ComponentModel;

public class CustomerServiceTools
{
    [Description("Search for customer order by order ID")]
    public async Task<string> GetOrderInfoAsync(
        [Description("Order ID to search, format like ORD-12345")] string orderId)
    {
        // 模拟数据库查询
        await Task.Delay(100);
        
        return $@"订单信息查询成功:
- 订单号:{orderId}
- 客户姓名:张三
- 产品:Surface Laptop 5
- 状态:已发货
- 物流单号:SF1234567890";
    }

    [Description("Process refund request for an order")]
    public async Task<string> ProcessRefundAsync(
        [Description("Order ID to refund")] string orderId,
        [Description("Refund reason provided by customer")] string reason)
    {
        await Task.Delay(200);
        
        var refundId = $"RF-{DateTime.Now:yyyyMMddHHmmss}";
        return $@"退款申请已成功提交:
- 退款单号:{refundId}
- 订单号:{orderId}
- 退款原因:{reason}
- 预计处理时间:3-5个工作日";
    }
}
使用 Function Calling
using OpenAI.Chat;

// 创建工具实例
var tools = new CustomerServiceTools();

// 定义工具(Function Calling)
var chatOptions = new ChatCompletionOptions();

chatOptions.Tools.Add(ChatTool.CreateFunctionTool(
    "GetOrderInfo",
    "Search for customer order by order ID",
    BinaryData.FromString("""
    {
        "type": "object",
        "properties": {
            "orderId": {
                "type": "string",
                "description": "Order ID to search, format like ORD-12345"
            }
        },
        "required": ["orderId"]
    }
    """)
));

chatOptions.Tools.Add(ChatTool.CreateFunctionTool(
    "ProcessRefund",
    "Process refund request for an order",
    BinaryData.FromString("""
    {
        "type": "object",
        "properties": {
            "orderId": {
                "type": "string",
                "description": "Order ID to refund"
            },
            "reason": {
                "type": "string",
                "description": "Refund reason provided by customer"
            }
        },
        "required": ["orderId", "reason"]
    }
    """)
));

// 调用AI并处理工具调用
var messages = new List<ChatMessage>
{
    new SystemChatMessage("你是专业的客户服务助手"),
    new UserChatMessage("查询订单 ORD-12345")
};

var completion = await chatClient.CompleteChatAsync(messages, chatOptions);

// 检查是否需要调用工具
if (completion.Value.FinishReason == ChatFinishReason.ToolCalls)
{
    // 添加助手消息到历史
    messages.Add(new AssistantChatMessage(completion.Value));
    
    // 执行工具调用
    foreach (var toolCall in completion.Value.ToolCalls)
    {
        var functionName = toolCall.FunctionName;
        var arguments = JsonDocument.Parse(toolCall.FunctionArguments.ToString());
        
        string result = functionName switch
        {
            "GetOrderInfo" => await tools.GetOrderInfoAsync(
                arguments.RootElement.GetProperty("orderId").GetString()!
            ),
            "ProcessRefund" => await tools.ProcessRefundAsync(
                arguments.RootElement.GetProperty("orderId").GetString()!,
                arguments.RootElement.GetProperty("reason").GetString()!
            ),
            _ => "未知工具"
        };
        
        // 添加工具结果到历史
        messages.Add(new ToolChatMessage(toolCall.Id, result));
    }
    
    // 再次调用AI生成最终响应
    var finalResponse = await chatClient.CompleteChatAsync(messages, chatOptions);
    Console.WriteLine(finalResponse.Value.Content[0].Text);
}

多轮对话(Multi-turn Conversation)

using OpenAI.Chat;

// 创建对话历史以保持上下文
var conversationHistory = new List<ChatMessage>
{
    new SystemChatMessage("You are a helpful assistant.")
};

// 第一轮对话
conversationHistory.Add(new UserChatMessage("My name is John."));
var response1 = await chatClient.CompleteChatAsync(conversationHistory);
var assistantMessage1 = response1.Value.Content[0].Text;
Console.WriteLine(assistantMessage1);

// 将助手响应添加到历史
conversationHistory.Add(new AssistantChatMessage(assistantMessage1));

// 第二轮对话(AI记得之前的上下文)
conversationHistory.Add(new UserChatMessage("What's my name?"));
var response2 = await chatClient.CompleteChatAsync(conversationHistory);
var assistantMessage2 = response2.Value.Content[0].Text;
Console.WriteLine(assistantMessage2); // 输出:Your name is John.

// 将响应添加到历史
conversationHistory.Add(new AssistantChatMessage(assistantMessage2));

// 第三轮对话
conversationHistory.Add(new UserChatMessage("Tell me a joke about my name."));
var response3 = await chatClient.CompleteChatAsync(conversationHistory);
Console.WriteLine(response3.Value.Content[0].Text);

代理记忆(Agent Memory)

注意:此示例展示记忆管理概念,实际实现通过维护对话历史来管理上下文。

using OpenAI.Chat;

// 使用对话历史实现记忆功能
var conversationHistory = new List<ChatMessage>
{
    new SystemChatMessage("You are a personal assistant. Remember user preferences.")
};

// 用户设置偏好
conversationHistory.Add(new UserChatMessage("Remember that I prefer meetings in the morning."));
var response1 = await chatClient.CompleteChatAsync(conversationHistory);
conversationHistory.Add(new AssistantChatMessage(response1.Value.Content[0].Text));

conversationHistory.Add(new UserChatMessage("My favorite programming language is C#."));
var response2 = await chatClient.CompleteChatAsync(conversationHistory);
conversationHistory.Add(new AssistantChatMessage(response2.Value.Content[0].Text));

// 稍后查询 - AI会从对话历史中回忆
conversationHistory.Add(new UserChatMessage("When do I prefer meetings?"));
var response3 = await chatClient.CompleteChatAsync(conversationHistory);
Console.WriteLine(response3.Value.Content[0].Text); // 输出:You prefer meetings in the morning.

代理中间件(Agent Middleware)

注意:此示例展示中间件概念,实际实现可以通过包装函数来实现类似功能。

using OpenAI.Chat;

// 创建包装类实现日志和过滤功能
public class ChatClientWrapper
{
    private readonly ChatClient _chatClient;
    
    public ChatClientWrapper(ChatClient chatClient)
    {
        _chatClient = chatClient;
    }
    
    public async Task<string> CompleteChatWithLoggingAsync(
        List<ChatMessage> messages, 
        ChatCompletionOptions? options = null)
    {
        // 日志记录请求
        var userMessage = messages.LastOrDefault(m => m is UserChatMessage);
        if (userMessage != null)
        {
            Console.WriteLine($"[Request] {((UserChatMessage)userMessage).Content[0].Text}");
        }
        
        // 检查敏感内容
        if (userMessage != null && ContainsSensitiveInfo(((UserChatMessage)userMessage).Content[0].Text))
        {
            Console.WriteLine("[Filter] Sensitive information detected");
            return "I cannot process sensitive information.";
        }
        
        // 调用实际的API
        var response = await _chatClient.CompleteChatAsync(messages, options);
        var responseText = response.Value.Content[0].Text;
        
        // 日志记录响应
        Console.WriteLine($"[Response] {responseText}");
        
        return responseText;
    }
    
    private bool ContainsSensitiveInfo(string message)
    {
        // 实现敏感信息检测逻辑
        return message.Contains("password") || message.Contains("credit card");
    }
}

// 使用示例
var wrapper = new ChatClientWrapper(chatClient);
var messages = new List<ChatMessage>
{
    new SystemChatMessage("You are a helpful assistant."),
    new UserChatMessage("Tell me a joke.")
};

var response = await wrapper.CompleteChatWithLoggingAsync(messages);

工作流详解

重要说明:以下工作流示例为概念性设计,展示多代理协作的思路。Microsoft Agent Framework 的工作流 API 仍在开发中,实际实现需要通过组合多个 ChatClient 调用来完成。

基础工作流结构(概念性示例)

using OpenAI.Chat;
using System.Text.Json;

// 概念性的客户支持工作流实现
public class CustomerSupportWorkflow
{
    private readonly ChatClient _chatClient;
    
    public CustomerSupportWorkflow(ChatClient chatClient)
    {
        _chatClient = chatClient;
    }
    
    public async Task<string> ExecuteAsync(string userQuery)
    {
        // 步骤1: 意图识别
        var intent = await TriageAsync(userQuery);
        
        // 步骤2: 根据意图路由到专门的处理逻辑
        return intent switch
        {
            "technical" => await HandleTechnicalIssueAsync(userQuery),
            "billing" => await HandleBillingIssueAsync(userQuery),
            _ => await HandleGeneralQueryAsync(userQuery)
        };
    }
    
    private async Task<string> TriageAsync(string query)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage(@"你是客户服务分类助手。分析用户问题并返回以下类别之一:
- technical: 技术问题
- billing: 账单问题
- general: 一般咨询

只返回类别名称,不要其他内容。"),
            new UserChatMessage(query)
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text.Trim().ToLower();
    }
    
    private async Task<string> HandleTechnicalIssueAsync(string query)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是技术支持专家,负责解决技术问题。"),
            new UserChatMessage(query)
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
    
    private async Task<string> HandleBillingIssueAsync(string query)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是账单支持专家,负责处理账单相关问题。"),
            new UserChatMessage(query)
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
    
    private async Task<string> HandleGeneralQueryAsync(string query)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是客户服务代表,负责回答一般性问题。"),
            new UserChatMessage(query)
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
}

条件路由(概念性示例)

using OpenAI.Chat;

public class OrderProcessingWorkflow
{
    private readonly ChatClient _chatClient;
    
    public async Task<string> ExecuteAsync(string orderId)
    {
        // 步骤1: 验证订单
        var isValid = await ValidateOrderAsync(orderId);
        
        if (isValid)
        {
            // 步骤2: 处理支付
            await ProcessPaymentAsync(orderId);
            
            // 步骤3: 发货
            return await ShipOrderAsync(orderId);
        }
        else
        {
            // 通知客户
            return await NotifyCustomerAsync(orderId, "订单验证失败");
        }
    }
    
    private async Task<bool> ValidateOrderAsync(string orderId)
    {
        // 实现订单验证逻辑
        await Task.Delay(100);
        return orderId.StartsWith("ORD-");
    }
    
    private async Task ProcessPaymentAsync(string orderId)
    {
        // 实现支付处理逻辑
        await Task.Delay(200);
    }
    
    private async Task<string> ShipOrderAsync(string orderId)
    {
        // 实现发货逻辑
        await Task.Delay(150);
        return $"订单 {orderId} 已发货";
    }
    
    private async Task<string> NotifyCustomerAsync(string orderId, string reason)
    {
        // 实现客户通知逻辑
        await Task.Delay(100);
        return $"订单 {orderId} 处理失败: {reason}";
    }
}

并行处理(概念性示例)

using OpenAI.Chat;

public class DataAnalysisWorkflow
{
    private readonly ChatClient _chatClient;
    
    public async Task<string> ExecuteAsync(string data)
    {
        // 步骤1: 加载数据
        var loadedData = await LoadDataAsync(data);
        
        // 步骤2: 并行执行三种分析
        var statisticalTask = StatisticalAnalysisAsync(loadedData);
        var sentimentTask = SentimentAnalysisAsync(loadedData);
        var trendTask = TrendAnalysisAsync(loadedData);
        
        await Task.WhenAll(statisticalTask, sentimentTask, trendTask);
        
        // 步骤3: 汇总结果
        return await AggregateResultsAsync(
            statisticalTask.Result,
            sentimentTask.Result,
            trendTask.Result
        );
    }
    
    private async Task<string> LoadDataAsync(string data)
    {
        await Task.Delay(100);
        return data;
    }
    
    private async Task<string> StatisticalAnalysisAsync(string data)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是统计分析专家。"),
            new UserChatMessage($"对以下数据进行统计分析:{data}")
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
    
    private async Task<string> SentimentAnalysisAsync(string data)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是情感分析专家。"),
            new UserChatMessage($"对以下数据进行情感分析:{data}")
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
    
    private async Task<string> TrendAnalysisAsync(string data)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是趋势分析专家。"),
            new UserChatMessage($"对以下数据进行趋势分析:{data}")
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
    
    private async Task<string> AggregateResultsAsync(
        string statistical,
        string sentiment,
        string trend)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是数据分析总结专家。"),
            new UserChatMessage($@"汇总以下分析结果:
统计分析:{statistical}
情感分析:{sentiment}
趋势分析:{trend}")
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
}

多代理编排模式

1. 顺序编排(Sequential)(概念性示例)
using OpenAI.Chat;

public class ResearchWorkflow
{
    private readonly ChatClient _chatClient;
    
    public async Task<string> ExecuteAsync(string topic)
    {
        // 步骤1: 搜索信息
        var searchResults = await SearchAsync(topic);
        
        // 步骤2: 分析数据
        var analysis = await AnalyzeAsync(searchResults);
        
        // 步骤3: 生成摘要
        var summary = await SummarizeAsync(analysis);
        
        // 步骤4: 审查结果
        return await ReviewAsync(summary);
    }
    
    private async Task<string> SearchAsync(string topic)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是信息搜索专家。"),
            new UserChatMessage($"搜索关于 '{topic}' 的相关信息")
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
    
    private async Task<string> AnalyzeAsync(string data)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是数据分析专家。"),
            new UserChatMessage($"分析以下数据:{data}")
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
    
    private async Task<string> SummarizeAsync(string analysis)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是内容摘要专家。"),
            new UserChatMessage($"总结以下分析:{analysis}")
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
    
    private async Task<string> ReviewAsync(string summary)
    {
        var messages = new List<ChatMessage>
        {
            new SystemChatMessage("你是质量审查专家。"),
            new UserChatMessage($"审查以下摘要:{summary}")
        };
        
        var response = await _chatClient.CompleteChatAsync(messages);
        return response.Value.Content[0].Text;
    }
}
2. 并发编排(Concurrent)(概念性示例)
using OpenAI.Chat;

public class ContentCreationWorkflow
{
    private readonly ChatClient _chatClient;
    
    public async Task<string> ExecuteAsync(string topic)
    {
        // 步骤1: 生成大纲
        var outline = await CreateOutlineAsync(topic);
        
        // 步骤2: 并行撰写各部分
        var section1Task = WriteSectionAsync(outline, "section1");
        var section2Task = WriteSectionAsync(outline, "section2");
        var section3Task = WriteSectionAsync(outline, "section3");
        
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐