使用 maf重构
This commit is contained in:
217
Service/AgentFramework/BaseAgent.cs
Normal file
217
Service/AgentFramework/BaseAgent.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Service.AgentFramework;
|
||||
|
||||
/// <summary>
|
||||
/// Agent 基类 - 提供通用的工作流编排能力
|
||||
/// </summary>
|
||||
public abstract class BaseAgent
|
||||
{
|
||||
protected readonly IToolRegistry _toolRegistry;
|
||||
protected readonly ILogger<BaseAgent> _logger;
|
||||
protected readonly List<ExecutionStep> _steps = new();
|
||||
protected readonly Dictionary<string, object?> _metadata = new();
|
||||
|
||||
// 定义 ActivitySource 供 DevUI 捕获
|
||||
private static readonly ActivitySource _activitySource = new("Microsoft.Agents.Workflows");
|
||||
|
||||
protected BaseAgent(
|
||||
IToolRegistry toolRegistry,
|
||||
ILogger<BaseAgent> logger)
|
||||
{
|
||||
_toolRegistry = toolRegistry;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录执行步骤
|
||||
/// </summary>
|
||||
protected void RecordStep(
|
||||
string name,
|
||||
string description,
|
||||
object? output = null,
|
||||
long durationMs = 0)
|
||||
{
|
||||
var step = new ExecutionStep
|
||||
{
|
||||
Name = name,
|
||||
Description = description,
|
||||
Status = "Completed",
|
||||
Output = output,
|
||||
DurationMs = durationMs
|
||||
};
|
||||
|
||||
_steps.Add(step);
|
||||
|
||||
// 使用 Activity 进行埋点,将被 DevUI 自动捕获
|
||||
using var activity = _activitySource.StartActivity(name);
|
||||
activity?.SetTag("agent.step.description", description);
|
||||
if (output != null) activity?.SetTag("agent.step.output", output.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录失败的步骤
|
||||
/// </summary>
|
||||
protected void RecordFailedStep(
|
||||
string name,
|
||||
string description,
|
||||
string error,
|
||||
long durationMs = 0)
|
||||
{
|
||||
var step = new ExecutionStep
|
||||
{
|
||||
Name = name,
|
||||
Description = description,
|
||||
Status = "Failed",
|
||||
Error = error,
|
||||
DurationMs = durationMs
|
||||
};
|
||||
|
||||
_steps.Add(step);
|
||||
|
||||
using var activity = _activitySource.StartActivity($"{name} (Failed)");
|
||||
activity?.SetTag("agent.step.error", error);
|
||||
_logger.LogError("[Agent步骤失败] {StepName}: {Error}", name, error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置元数据
|
||||
/// </summary>
|
||||
protected void SetMetadata(string key, object? value)
|
||||
{
|
||||
_metadata[key] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取执行日志
|
||||
/// </summary>
|
||||
protected List<ExecutionStep> GetExecutionLog()
|
||||
{
|
||||
return _steps.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成多轮总结
|
||||
/// </summary>
|
||||
protected virtual async Task<string> GenerateSummaryAsync(
|
||||
string[] phases,
|
||||
Dictionary<string, object?> phaseResults)
|
||||
{
|
||||
var summaryParts = new List<string>();
|
||||
|
||||
// 简单的总结生成逻辑
|
||||
// 实际项目中可以集成 AI 生成更复杂的总结
|
||||
foreach (var phase in phases)
|
||||
{
|
||||
if (phaseResults.TryGetValue(phase, out var result))
|
||||
{
|
||||
summaryParts.Add($"{phase}:已完成");
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.FromResult(string.Join(";", summaryParts) + "。");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 调用 Tool(简化接口)
|
||||
/// </summary>
|
||||
protected async Task<TResult> CallToolAsync<TResult>(
|
||||
string toolName,
|
||||
string stepName,
|
||||
string stepDescription)
|
||||
{
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("开始执行 Tool: {ToolName}", toolName);
|
||||
var result = await _toolRegistry.InvokeToolAsync<TResult>(toolName);
|
||||
sw.Stop();
|
||||
|
||||
RecordStep(stepName, stepDescription, result, sw.ElapsedMilliseconds);
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sw.Stop();
|
||||
RecordFailedStep(stepName, stepDescription, ex.Message, sw.ElapsedMilliseconds);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 调用带参数的 Tool
|
||||
/// </summary>
|
||||
protected async Task<TResult> CallToolAsync<TParam, TResult>(
|
||||
string toolName,
|
||||
TParam param,
|
||||
string stepName,
|
||||
string stepDescription)
|
||||
{
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("开始执行 Tool: {ToolName},参数: {Param}", toolName, param);
|
||||
var result = await _toolRegistry.InvokeToolAsync<TParam, TResult>(toolName, param);
|
||||
sw.Stop();
|
||||
|
||||
RecordStep(stepName, stepDescription, result, sw.ElapsedMilliseconds);
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sw.Stop();
|
||||
RecordFailedStep(stepName, stepDescription, ex.Message, sw.ElapsedMilliseconds);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 调用带多参数的 Tool
|
||||
/// </summary>
|
||||
protected async Task<TResult> CallToolAsync<TParam1, TParam2, TResult>(
|
||||
string toolName,
|
||||
TParam1 param1,
|
||||
TParam2 param2,
|
||||
string stepName,
|
||||
string stepDescription)
|
||||
{
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("开始执行 Tool: {ToolName},参数: {Param1}, {Param2}", toolName, param1, param2);
|
||||
var result = await _toolRegistry.InvokeToolAsync<TParam1, TParam2, TResult>(
|
||||
toolName, param1, param2);
|
||||
sw.Stop();
|
||||
|
||||
RecordStep(stepName, stepDescription, result, sw.ElapsedMilliseconds);
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sw.Stop();
|
||||
RecordFailedStep(stepName, stepDescription, ex.Message, sw.ElapsedMilliseconds);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 Agent 执行结果
|
||||
/// </summary>
|
||||
protected AgentResult<T> CreateResult<T>(
|
||||
T data,
|
||||
string summary,
|
||||
bool success = true,
|
||||
string? error = null)
|
||||
{
|
||||
return new AgentResult<T>
|
||||
{
|
||||
Data = data,
|
||||
Summary = summary,
|
||||
Steps = _steps,
|
||||
Metadata = _metadata,
|
||||
Success = success,
|
||||
Error = error
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user