You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

366 lines
13 KiB
C#

1 month ago
using AI.Interface;
using AI.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AI.Workflow
{
/// <summary>
/// 执行结果
/// </summary>
public class ExecutionResult
{
/// <summary>
/// 是否成功
/// </summary>
public bool IsSuccess { get; set; }
/// <summary>
/// 执行结果内容
/// </summary>
public string Content { get; set; } = string.Empty;
/// <summary>
/// 错误信息(如果失败)
/// </summary>
public string? ErrorMessage { get; set; }
/// <summary>
/// 是否需要重试
/// </summary>
public bool ShouldRetry { get; set; }
/// <summary>
/// 观察信息ReAct 模式)
/// </summary>
public string? Observation { get; set; }
}
/// <summary>
/// 步骤执行器 - 使用 ReAct 模式执行步骤:推理-行动-观察
/// </summary>
public class Executor
{
private readonly IChatBackend _chatBackend;
private readonly ChatSession _executionSession;
private readonly WorkflowState _state;
private readonly List<ReActStep> _reactHistory = new();
private readonly Action<string, string>? _onThoughtUpdated;
public Executor(IChatBackend chatBackend, WorkflowState state, Action<string, string>? onThoughtUpdated = null)
{
_chatBackend = chatBackend;
_state = state;
_executionSession = new ChatSession();
_onThoughtUpdated = onThoughtUpdated;
// 初始化 ReAct 提示词
_executionSession.AddSystemMessage(GetReActPrompt());
}
/// <summary>
/// 使用 ReAct 模式执行单个步骤
/// </summary>
/// <param name="step">要执行的步骤</param>
/// <param name="context">上下文信息(之前的步骤结果)</param>
/// <param name="maxIterations">最大迭代次数默认3次</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>执行结果</returns>
public async Task<ExecutionResult> ExecuteStepWithReActAsync(PlanStep step, string? context = null, int maxIterations = 3, CancellationToken cancellationToken = default)
{
step.Status = PlanStepStatus.Running;
step.StartedAt = DateTime.Now;
step.ErrorMessage = null;
try
{
Debug.WriteLine($"ReAct 模式执行步骤 {step.Order}: {step.Description}");
var reactStep = new ReActStep
{
StepId = step.Id,
StepDescription = step.Description,
Context = context
};
// ReAct 循环:推理 -> 行动 -> 观察
for (int iteration = 0; iteration < maxIterations; iteration++)
{
cancellationToken.ThrowIfCancellationRequested();
Debug.WriteLine($"ReAct 迭代 {iteration + 1}/{maxIterations}");
// 1. 推理Think
string thought = await ThinkAsync(step, context, reactStep, cancellationToken);
reactStep.Thoughts.Add(thought);
Debug.WriteLine($"推理: {thought}");
// 通知 Thought 更新
_onThoughtUpdated?.Invoke(step.Id, thought);
// 2. 行动Act
string action = await ActAsync(step, thought, context, reactStep, cancellationToken);
reactStep.Actions.Add(action);
Debug.WriteLine($"行动: {action}");
// 3. 观察Observe
string observation = await ObserveAsync(action, reactStep, cancellationToken);
reactStep.Observations.Add(observation);
Debug.WriteLine($"观察: {observation}");
// 检查是否完成
if (IsTaskComplete(observation, reactStep))
{
step.Status = PlanStepStatus.Completed;
step.Result = BuildFinalResult(reactStep);
step.CompletedAt = DateTime.Now;
_reactHistory.Add(reactStep);
Debug.WriteLine($"步骤 {step.Order} 执行完成");
return new ExecutionResult
{
IsSuccess = true,
Content = step.Result,
Observation = observation
};
}
}
// 达到最大迭代次数,返回当前结果
step.Status = PlanStepStatus.Completed;
step.Result = BuildFinalResult(reactStep);
step.CompletedAt = DateTime.Now;
_reactHistory.Add(reactStep);
return new ExecutionResult
{
IsSuccess = true,
Content = step.Result,
Observation = "达到最大迭代次数"
};
}
catch (Exception ex)
{
step.Status = PlanStepStatus.Failed;
step.ErrorMessage = ex.Message;
step.CompletedAt = DateTime.Now;
Debug.WriteLine($"步骤 {step.Order} 执行失败: {ex.Message}");
return new ExecutionResult
{
IsSuccess = false,
ErrorMessage = ex.Message,
ShouldRetry = true
};
}
}
/// <summary>
/// 推理阶段:分析当前情况和需要采取的行动
/// </summary>
private async Task<string> ThinkAsync(PlanStep step, string? context, ReActStep reactStep, CancellationToken cancellationToken)
{
var prompt = new StringBuilder();
prompt.AppendLine("【推理阶段】");
prompt.AppendLine($"当前步骤:{step.Description}");
if (!string.IsNullOrEmpty(context))
{
prompt.AppendLine($"\n上下文信息");
prompt.AppendLine(context);
}
if (reactStep.Thoughts.Count > 0)
{
prompt.AppendLine($"\n之前的推理");
for (int i = 0; i < reactStep.Thoughts.Count; i++)
{
prompt.AppendLine($"{i + 1}. {reactStep.Thoughts[i]}");
}
}
if (reactStep.Observations.Count > 0)
{
prompt.AppendLine($"\n之前的观察结果");
for (int i = 0; i < reactStep.Observations.Count; i++)
{
prompt.AppendLine($"{i + 1}. {reactStep.Observations[i]}");
}
}
prompt.AppendLine($"\n请分析当前情况思考需要采取什么行动来完成这个步骤。");
string thought = await _chatBackend.AskAsync(prompt.ToString(), _executionSession, null, cancellationToken);
return thought;
}
/// <summary>
/// 行动阶段:执行具体的操作
/// </summary>
private async Task<string> ActAsync(PlanStep step, string thought, string? context, ReActStep reactStep, CancellationToken cancellationToken)
{
var prompt = new StringBuilder();
prompt.AppendLine("【行动阶段】");
prompt.AppendLine($"步骤描述:{step.Description}");
prompt.AppendLine($"\n推理结果{thought}");
if (!string.IsNullOrEmpty(context))
{
prompt.AppendLine($"\n上下文信息");
prompt.AppendLine(context);
}
if (reactStep.Actions.Count > 0)
{
prompt.AppendLine($"\n之前的行动");
for (int i = 0; i < reactStep.Actions.Count; i++)
{
prompt.AppendLine($"{i + 1}. {reactStep.Actions[i]}");
}
}
prompt.AppendLine($"\n请根据推理结果执行具体的行动来完成这个步骤。");
string action = await _chatBackend.AskAsync(prompt.ToString(), _executionSession, null, cancellationToken);
return action;
}
/// <summary>
/// 观察阶段:观察行动的结果
/// </summary>
private async Task<string> ObserveAsync(string action, ReActStep reactStep, CancellationToken cancellationToken)
{
var prompt = new StringBuilder();
prompt.AppendLine("【观察阶段】");
prompt.AppendLine($"刚才的行动:{action}");
prompt.AppendLine($"\n请观察行动的结果评估是否完成了步骤目标。如果未完成说明还需要做什么。");
string observation = await _chatBackend.AskAsync(prompt.ToString(), _executionSession, null, cancellationToken);
return observation;
}
/// <summary>
/// 判断任务是否完成
/// </summary>
private bool IsTaskComplete(string observation, ReActStep reactStep)
{
// 简单的完成判断:如果观察结果包含完成相关的关键词
var completionKeywords = new[] { "完成", "成功", "已达成", "已完成", "done", "completed", "success" };
var lowerObservation = observation.ToLower();
foreach (var keyword in completionKeywords)
{
if (lowerObservation.Contains(keyword.ToLower()))
{
return true;
}
}
return false;
}
/// <summary>
/// 构建最终结果
/// </summary>
private string BuildFinalResult(ReActStep reactStep)
{
var result = new StringBuilder();
result.AppendLine("执行过程:");
for (int i = 0; i < reactStep.Thoughts.Count; i++)
{
result.AppendLine($"\n迭代 {i + 1}:");
result.AppendLine($"推理: {reactStep.Thoughts[i]}");
if (i < reactStep.Actions.Count)
{
result.AppendLine($"行动: {reactStep.Actions[i]}");
}
if (i < reactStep.Observations.Count)
{
result.AppendLine($"观察: {reactStep.Observations[i]}");
}
}
return result.ToString();
}
/// <summary>
/// 获取 ReAct 提示词
/// </summary>
private string GetReActPrompt()
{
return @"你是一个使用 ReAct推理-行动-观察)模式执行任务的智能助手。
ReAct
ReAct
1. **Think**
-
-
-
-
-
2. **Act**
-
-
-
- 便
3. **Observe**
-
-
-
-
-
- ****
- ****
- ****
- ****
-
-
-
-
-
-
-
-
-
-
-
-
ReAct ";
}
/// <summary>
/// ReAct 步骤记录
/// </summary>
internal class ReActStep
{
public string StepId { get; set; } = string.Empty;
public string StepDescription { get; set; } = string.Empty;
public string? Context { get; set; }
public List<string> Thoughts { get; } = new List<string>();
public List<string> Actions { get; } = new List<string>();
public List<string> Observations { get; } = new List<string>();
}
}
}