使用PocketFlowSharp创建一个Human_Evaluation示例

效果

image-20250516142423902

image-20250516142438960

实践

有时候AI生成的结果我们并不满意在进入下一步之前,我们需要对AI生成的结果进行人工审核,同意了才能进入下一个流程。

Human_Evaluation就是人工判断的一个简单示例。

 internal class Program
 {
     static async Task Main(string[] args)
     {
         // Load .env file
         DotEnv.Load();

         // Get environment variables from .env file
         var 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;
     }
 }

看一下整体的流程图:

generate

approve

approve

retry

输入节点

AI回复节点

人工审核节点

结束节点

输入节点:

 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

原创作者: mingupupu 转载于: https://www.cnblogs.com/mingupupu/p/18880039
### 开发环境配置 在使用 Java 开发数字人应用之前,确保开发环境正确配置是至关重要的。首先,需要从 Git 上下载相关的代码库,并进行初步的设置。设置过程中,需要指定合适的 SDK 版本,并进入工程结构设置以确保所有模块正确识别。接着,在 Project 选项页中设定项目的 SDK 和语言级别,然后在 Modules 选项页中配置各个模块的依赖关系和内容根目录。完成这些设置后,可以尝试运行测试代码以验证环境配置是否正确[^2]。 ### 创建包与代码组织 创建包是组织 Java 代码的重要步骤。包不仅可以帮助开发者更好地管理代码文件,还能避免类名冲突。创建包时,应遵循一定的命名规范,例如使用反向域名格式(如 `com.example.digitalhuman`)。包的作用不仅限于代码组织,它还可以控制类、接口、方法的访问权限,提高代码的安全性和可维护性。在开发数字人系统时,合理的包结构有助于模块化开发和后期维护[^2]。 ### Java 示例代码 为了更好地理解 Java 在数字人开发中的应用,可以从简单的示例开始。例如,`HelloWorld` 示例是学习任何编程语言的基础,它展示了如何编写、编译和运行一个简单的 Java 程序: ```java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, Digital Human!"); } } ``` 此外,了解 Java 的数据类型、标识符和常量也是开发过程中的基础。例如,定义一个表示数字人年龄的常量: ```java public class DigitalHumanConstants { public static final int MAX_AGE = 100; } ``` ### 数字人开发的关键技术 AI 数字人系统涉及多个复杂技术领域,包括但不限于角色建模、自然语言处理、语音合成与识别、计算机视觉以及用户界面设计。角色建模需要使用 3D 建模工具和技术来创建逼真的虚拟形象。自然语言处理技术则用于实现数字人的对话能力,使其能够理解和回应用户的指令。语音合成与识别技术使数字人能够以自然的方式与用户交流。计算机视觉技术可以赋予数字人感知环境的能力,例如通过摄像头识别用户的表情和动作。最后,用户界面设计是确保数字人系统用户友好性的关键环节[^1]。 ### 实现与优化 尽管 Java 提供了强大的功能来支持数字人系统的开发,但在实际应用中仍需根据具体场景进行调整与优化。这包括性能优化、用户体验改进以及功能扩展等方面。性能优化可能涉及算法改进、资源管理以及并发处理等策略。用户体验改进则需要关注交互设计、响应速度和稳定性等因素。功能扩展可能包括增加新的交互模式、集成更多 AI 功能或支持多种平台和设备。随着技术的进步,持续创新是保持数字人系统竞争力的关键。 ### 开发建议 对于初学者而言,建议从基础的 Java 编程学习开始,逐步掌握面向对象编程的概念和实践。随后,可以尝试使用 Java 编写简单的 AI 应用程序,如基于规则的聊天机器人。当对 Java 和 AI 开发有了一定的理解后,再尝试更复杂的项目,如使用 Java 集成深度学习框架(如 TensorFlow 或 DL4J)来实现更高级的 AI 功能。开发过程中,不断测试和迭代是非常重要的,这有助于发现并解决问题,同时也能促进功能的不断完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值