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
{
///
/// 执行结果
///
public class ExecutionResult
{
///
/// 是否成功
///
public bool IsSuccess { get; set; }
///
/// 执行结果内容
///
public string Content { get; set; } = string.Empty;
///
/// 错误信息(如果失败)
///
public string? ErrorMessage { get; set; }
///
/// 是否需要重试
///
public bool ShouldRetry { get; set; }
///
/// 观察信息(ReAct 模式)
///
public string? Observation { get; set; }
}
///
/// 步骤执行器 - 使用 ReAct 模式执行步骤:推理-行动-观察
///
public class Executor
{
private readonly IChatBackend _chatBackend;
private readonly ChatSession _executionSession;
private readonly WorkflowState _state;
private readonly List _reactHistory = new();
private readonly Action? _onThoughtUpdated;
public Executor(IChatBackend chatBackend, WorkflowState state, Action? onThoughtUpdated = null)
{
_chatBackend = chatBackend;
_state = state;
_executionSession = new ChatSession();
_onThoughtUpdated = onThoughtUpdated;
// 初始化 ReAct 提示词
_executionSession.AddSystemMessage(GetReActPrompt());
}
///
/// 使用 ReAct 模式执行单个步骤
///
/// 要执行的步骤
/// 上下文信息(之前的步骤结果)
/// 最大迭代次数(默认3次)
/// 取消令牌
/// 执行结果
public async Task 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
};
}
}
///
/// 推理阶段:分析当前情况和需要采取的行动
///
private async Task 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;
}
///
/// 行动阶段:执行具体的操作
///
private async Task 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;
}
///
/// 观察阶段:观察行动的结果
///
private async Task 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;
}
///
/// 判断任务是否完成
///
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;
}
///
/// 构建最终结果
///
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();
}
///
/// 获取 ReAct 提示词
///
private string GetReActPrompt()
{
return @"你是一个使用 ReAct(推理-行动-观察)模式执行任务的智能助手。
【ReAct 工作模式】
ReAct 是一种迭代式的问题解决方法,通过不断循环以下三个步骤来完成任务:
1. **推理(Think)**:深入分析当前情况
- 理解当前步骤的目标和要求
- 分析已有的上下文信息和历史记录
- 识别需要解决的问题和可能的障碍
- 制定具体的行动计划
- 推理过程要逻辑清晰、条理分明
2. **行动(Act)**:执行具体的操作
- 根据推理结果,采取明确的行动
- 行动要具体、可执行、有针对性
- 如果涉及工具调用,确保参数正确
- 行动描述要清晰,便于后续观察
3. **观察(Observe)**:评估行动结果
- 仔细分析行动产生的结果
- 判断是否达到了预期目标
- 识别成功点和失败点
- 评估是否需要继续迭代
- 观察要客观、准确、全面
【执行原则】
- **迭代优化**:如果任务未完成,基于观察结果进行下一轮推理,不断优化策略
- **目标导向**:始终牢记当前步骤的最终目标,不要偏离方向
- **充分利用上下文**:仔细分析之前步骤的结果和观察,避免重复工作
- **明确完成标准**:当任务完成时,明确说明已完成,并总结关键成果
【推理质量要求】
- 推理要深入,不能停留在表面
- 要分析问题的根本原因,而不仅仅是症状
- 要考虑多种可能的解决方案,选择最优的
- 要预测行动可能的结果,提前规避风险
【行动执行要求】
- 行动要具体,避免模糊的描述
- 要充分利用可用的工具和资源
- 要确保行动的可执行性和有效性
- 如果遇到障碍,要灵活调整策略
【观察评估要求】
- 要全面评估结果,不能只看表面
- 要识别成功的关键因素和失败的根因
- 要判断是否真正完成了目标
- 要为下一轮迭代提供有价值的反馈
请严格按照 ReAct 模式执行任务,确保推理深入、行动有效、观察准确。";
}
///
/// ReAct 步骤记录
///
internal class ReActStep
{
public string StepId { get; set; } = string.Empty;
public string StepDescription { get; set; } = string.Empty;
public string? Context { get; set; }
public List Thoughts { get; } = new List();
public List Actions { get; } = new List();
public List Observations { get; } = new List();
}
}
}