MAF快速入门(10)循环工作流
大家好,我是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
{
public int PolitenessScore { get; set; }
public int AccuracyScore { get; set; }
public bool CompliancePassed { get; set; }
public List<QualityIssueDto> Issues { get; set; } = new();
}
internal class QualityIssueDto
{
public string Type { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
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,假设其用于客服工单的自动回复:
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($"
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! 过来提前占个楼 感谢分享,学习下。 这个有用。 喜欢鼓捣这些软件,现在用得少,谢谢分享! 新版吗?好像是停更了吧。 懂技术并乐意极积无私分享的人越来越少。珍惜 感谢发布原创作品,程序园因你更精彩 用心讨论,共获提升! 喜欢鼓捣这些软件,现在用得少,谢谢分享! 感谢,下载保存了 很好很强大我过来先占个楼 待编辑 过来提前占个楼 谢谢楼主提供! 新版吗?好像是停更了吧。 谢谢楼主提供! 很好很强大我过来先占个楼 待编辑 感谢发布原创作品,程序园因你更精彩 感谢发布原创作品,程序园因你更精彩 感谢分享,下载保存了,貌似很强大
页:
[1]
2