大家好,我是Edison。
最近我一直在跟着圣杰的《.NET+AI智能体开发进阶》课程学习MAF的开发技巧,我强烈推荐你也上车跟我一起出发!
上一篇,我们学习了MAF中如何进行switch-case类型的多条件路由。本篇,我们来了解下在MAF中如何实现循环(自我修正)工作流。
1 循环与自我修正
在实际业务场景中,往往需要在工作流中设置一些循环与自我修正的机制,构建出一个“生成→审核→修复”的闭环,来确保AI产出的内容能够满足企业级质量标准。
在MAF中,我们可以使用 Loop Edge 即 循环边 来实现这个目的,如下代码片段所示:- var workflow = new WorkflowBuilder(draftExecutor)
- .AddEdge(draftExecutor, qcExecutor)
- .AddEdge(qcExecutor, draftExecutor)
- .WithOutputFrom(qcExecutor)
- .Build();
复制代码 可以看到,我们添加了两个边关联关系,这样就形成了一个循环。
2 循环工作流实验案例
假设我们是一个电商平台的客服中心,每天需要处理产生的大量客服工单进行回复。这里我们希望AI助手先帮我们生成一个回复草稿,然后经过多维度的质检(礼貌度、准确性、合规性),不合格的则自动进行改进,直到满足标准 或者是 转给人工处理。因此,我们的目标是:配置一个自动迭代的循环“生成→审核→修复”,达标即可退出循环,否则转人工处理。
2.1 关键依赖包引入
在今天的这个案例中,我们仍然创建了一个.NET控制台应用程序,安装了以下NuGet包:
- Microsoft.Agents.AI.OpenAI
- Microsoft.Agents.AI.Workflows
- Microsoft.Extensions.AI.OpenAI
2.2 定义数据传输模型
首先,我们定义一下在这个工作流中需要生成传递的数据模型:
(1)QualityReportDto :质检结果输出模型DTO- // 质检结果的结构化输出模型
- internal class QualityReportDto
- {
- [JsonPropertyName("politenessScore")]
- public int PolitenessScore { get; set; }
- [JsonPropertyName("accuracyScore")]
- public int AccuracyScore { get; set; }
- [JsonPropertyName("compliancePassed")]
- public bool CompliancePassed { get; set; }
- [JsonPropertyName("issues")]
- public List<QualityIssueDto> Issues { get; set; } = new();
- }
- internal class QualityIssueDto
- {
- [JsonPropertyName("type")]
- public string Type { get; set; } = string.Empty;
- [JsonPropertyName("description")]
- public string Description { get; set; } = string.Empty;
- [JsonPropertyName("scoreImpact")]
- public int ScoreImpact { get; set; }
- }
复制代码 (2)一些值对象,不赘述了- internal record ReplyDraft(
- string TicketId,
- string Content,
- int Attempt);
- internal record TicketRequest(
- string Id,
- string Query,
- string Category,
- string Priority);
- internal record TicketOutcome(
- string TicketId,
- string Status,
- int Attempts,
- QualityReport FinalReport);
- internal sealed record QualityScoreTimelineItem(
- int Attempt,
- int PolitenessScore,
- int AccuracyScore,
- string ComplianceStatus);
- internal record QualityIssue(
- string Type,
- string Description,
- int ScoreImpact);
- internal record QualityReport(
- string TicketId,
- int PolitenessScore,
- int AccuracyScore,
- bool CompliancePassed,
- IReadOnlyList<QualityIssue> Issues);
复制代码 (3)一些常量:用于定义一些阈值标准- public static class QualityCheckConstants
- {
- // 质检标准:礼貌度 ≥ 85,准确性 ≥ 90,合规性必须 100%
- // 注意:阈值设置较高,配合第一次生成简化版本,确保能体现循环改进过程
- public const int PolitenessThreshold = 85;
- public const int AccuracyThreshold = 90;
- }
- internal enum QualityCheckSignal
- {
- Init,
- Revise
- }
复制代码 2.3 定义自定义工作流事件
其次,我们定义一下在这个工作流中需要产生的自定义事件:
(1)AdaptiveQualityScoreEvent :质检评分已完成事件- internal sealed class AdaptiveQualityScoreEvent : WorkflowEvent
- {
- public AdaptiveQualityScoreEvent(string ticketId,
- int attempt,
- int politenessScore,
- int accuracyScore,
- bool compliancePassed)
- : base(new { TicketId = ticketId, Attempt = attempt, PolitenessScore = politenessScore, AccuracyScore = accuracyScore, CompliancePassed = compliancePassed })
- {
- }
- }
复制代码 (2)AdaptiveMaxAttemptsReachedEvent :质检超过最大次数事件- internal sealed class AdaptiveMaxAttemptsReachedEvent : WorkflowEvent
- {
- public AdaptiveMaxAttemptsReachedEvent(string ticketId, int maxAttempts)
- : base(new { TicketId = ticketId, MaxAttempts = maxAttempts })
- {
- }
- }
复制代码 2.4 定义Agents
(1)回复生成:模这里通过执行器的方式包裹一个回复生成的Agent,假设其用于客服工单的自动回复:
[code]internal sealed class AdaptiveReplyDraftExecutor : Executor{ private readonly TicketRequest _ticket; private readonly IChatClient _chatClient; public AdaptiveReplyDraftExecutor(TicketRequest ticket, IChatClient chatClient) : base("AdaptiveReplyDraft") { _ticket = ticket; _chatClient = chatClient; } public override async ValueTask HandleAsync(QualityCheckSignal message, IWorkflowContext context, CancellationToken cancellationToken = default) { int attempt = await context.ReadOrInitStateAsync("attempt", () => 0, cancellationToken); attempt++; await context.QueueStateUpdateAsync("attempt", attempt, cancellationToken); // 使用 AI 生成客服回复(渐进式生成策略) var prompt = attempt == 1 ? $""" 你是一位电商客服。请针对以下客户问题生成一条简短回复(刻意保持简短、缺少礼貌用语): 客户问题:{_ticket.Query} 产品类别:{_ticket.Category} 要求: 1. 只用1-2句话回答,不要称呼语和感谢语 2. 只说结论,不提供具体处理时间 3. 字数控制在30字以内 直接返回回复内容,不要添加任何前缀或说明。 """ : $""" 你是一位专业的电商客服。请针对以下客户问题生成一条改进后的回复: 客户问题:{_ticket.Query} 产品类别:{_ticket.Category} 优先级:{_ticket.Priority} 要求: 1. 语气亲和、专业,使用恰当的称呼和感谢语 2. 提供具体的解决方案或处理时间 3. 符合客服规范,不包含敏感词 4. 字数控制在80-100字 直接返回回复内容,不要添加任何前缀或说明。 """; var response = await _chatClient.GetResponseAsync(prompt, cancellationToken: cancellationToken); var content = response.Text ?? "抱歉,我们会尽快处理您的问题。"; Console.WriteLine($"✍️ 第 {attempt} 次生成回复草稿 (策略: {(attempt == 1 ? "简化版" : "完整版")})"); Console.WriteLine($"
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |