效果
實踐
有時候AI生成的結果我們并不滿意在進入下一步之前,我們需要對AI生成的結果進行人工審核,同意了才能進入下一個流程。
Human_Evaluation就是人工判斷的一個簡單示例。
internal class Program{static async Task Main(string[] args){// Load .env fileDotEnv.Load();// Get environment variables from .env filevar envVars = DotEnv.Read();string ModelName = envVars["ModelName"];string EndPoint = envVars["EndPoint"];string ApiKey = envVars["ApiKey"];Utils.ModelName = ModelName;Utils.EndPoint = EndPoint;Utils.ApiKey = ApiKey;// 創建共享數據字典var shared = new Dictionary<string, object>();// 創建并運行流程var humanEvalFlow = CreateFlow();Console.WriteLine("\n歡迎使用人工判斷示例!");Console.WriteLine("------------------------");await humanEvalFlow.RunAsync(shared);Console.WriteLine("\n感謝使用人工判斷示例!");}static AsyncFlow CreateFlow(){// 創建節點實例var inputNode = new TaskInputNode();var aiResponseNode = new AIResponseNode();var humanApprovalNode = new HumanApprovalNode();var endNode = new NoOpNode();// 創建從輸入節點開始的流程var flow = new AsyncFlow(inputNode);// 連接節點_ = inputNode - "generate" - aiResponseNode;_ = aiResponseNode - "approve" - humanApprovalNode;_ = humanApprovalNode - "retry" - aiResponseNode; // 不接受時重新生成_ = humanApprovalNode - "accept" - endNode; // 接受時結束流程return flow;}}
看一下整體的流程圖:
輸入節點:
public class TaskInputNode : AsyncNode{protected override async Task<object> PrepAsync(Dictionary<string, object> shared){Console.WriteLine("\n請輸入需要AI處理的任務:");string task = Console.ReadLine();return task;}protected override async Task<object> ExecAsync(object prepResult){string task = (string)prepResult;Console.WriteLine($"\n已收到任務:{task}");return task;}protected override async Task<object> PostAsync(Dictionary<string, object> shared, object prepResult, object execResult){string task = (string)execResult;shared["task"] = task;return "generate";}}
AI回復節點:
public class AIResponseNode : AsyncNode
{private static int attemptCount = 0;protected override async Task<object> PrepAsync(Dictionary<string, object> shared){return shared["task"];}protected override async Task<object> ExecAsync(object prepResult){string task = (string)prepResult;attemptCount++;Console.WriteLine("AI正在生成回復...\n");Console.WriteLine($"任務:{task}\n");Console.WriteLine($"這是第 {attemptCount} 次生成的AI回復:\n");var result = await Utils.CallLLMStreamingAsync(task);string response="";Console.ForegroundColor = ConsoleColor.Green;await foreach (StreamingChatCompletionUpdate completionUpdate in result){if (completionUpdate.ContentUpdate.Count > 0){Console.Write(completionUpdate.ContentUpdate[0].Text);response += completionUpdate.ContentUpdate[0].Text.ToString();}}Console.ForegroundColor = ConsoleColor.White;return response;}protected override async Task<object> PostAsync(Dictionary<string, object> shared, object prepResult, object execResult){string response = (string)execResult;shared["response"] = response;return "approve";}
}
人工審核節點:
public class HumanApprovalNode : AsyncNode{protected override async Task<object> PrepAsync(Dictionary<string, object> shared){return shared["response"];}protected override async Task<object> ExecAsync(object prepResult){Console.Write("\n您接受這個AI回復嗎?(y/n): ");string answer = Console.ReadLine()?.ToLower() ?? "n";return answer;}protected override async Task<object> PostAsync(Dictionary<string, object> shared, object prepResult, object execResult){string answer = (string)execResult;if (answer == "y"){Console.WriteLine($"已接受的回復:\n{shared["response"]}");return "accept";}else{Console.WriteLine("\n好的,讓AI重新生成回復...");return "retry";}}}
結束節點:
public class NoOpNode : AsyncNode{protected override async Task<object> PrepAsync(Dictionary<string, object> shared) => null;protected override async Task<object> ExecAsync(object prepResult) => null;protected override async Task<object> PostAsync(Dictionary<string, object> shared, object prepResult, object execResult) => null;}
幫助類:
public static class Utils{public static string ModelName { get; set; }public static string EndPoint { get; set; }public static string ApiKey { get; set; }public static async Task<string> CallLLMAsync(string prompt){ApiKeyCredential apiKeyCredential = new ApiKeyCredential(ApiKey);OpenAIClientOptions openAIClientOptions = new OpenAIClientOptions();openAIClientOptions.Endpoint = new Uri(EndPoint);ChatClient client = new(model: ModelName, apiKeyCredential, openAIClientOptions);ChatCompletion completion = await client.CompleteChatAsync(prompt);return completion.Content[0].Text;}public static async Task<AsyncCollectionResult<StreamingChatCompletionUpdate>> CallLLMStreamingAsync(string prompt){ApiKeyCredential apiKeyCredential = new ApiKeyCredential(ApiKey);OpenAIClientOptions openAIClientOptions = new OpenAIClientOptions();openAIClientOptions.Endpoint = new Uri(EndPoint);ChatClient client = new(model: ModelName, apiKeyCredential, openAIClientOptions);var completion = client.CompleteChatStreamingAsync(prompt);return completion;}}
全部代碼在:https://github.com/Ming-jiayou/PocketFlowSharp/tree/main/PocketFlowSharpSamples.Console/Human_Evaluation