找回密码
 立即注册
首页 业界区 业界 Solon AI 开发学习19 - 结合 Solon Flow 实现 ReAct 效 ...

Solon AI 开发学习19 - 结合 Solon Flow 实现 ReAct 效果

柴古香 昨天 23:30
Solon Flow 是一个通用流程编排引擎,采用 yaml 或 json 配置。下面演示 solon-ai 和 solon-flow 演示一个人机交互的 RcAct 效果。
1、演示步骤预期:

让 LLM 根据主题编写文章,然后由人工审核,如果没有通过重复上面的动作。步骤如下:

  • Agent 编写: 流程进入 agent 节点,LLM 编写初稿。
  • 人机回路 1: 流程进入 review 节点。

    • 用户输入 reject,并输入反馈:“文章太短,请增加挑战部分的具体细节。”

  • 动态循环: 评审 link 到  "agent",流程回到 agent 节点。
  • Agent 修改: LLM 读取反馈,修改内容。
  • 人机回路 2: 流程再次进入 review 节点。

    • 用户输入 approve。

  • 流程结束: 评审 link 到 "approved",流程结束。
2、流程编排

flow/demo1.yml
  1. id: demo1
  2. layout:
  3.   - {type: 'start'}
  4.   - {task: '@agent', id: 'agent'}
  5.   - {task: '@review', id: 'review', type: exclusive, link: [
  6.       {nextId: 'final_approval', title: 'approved', when: '"APPROVED".equals(review_status)'},
  7.       {nextId: 'final_failure', title: 'failed', when: '"REJECTED".equals(review_status) && revision_count.get() >= MAX_REVISIONS'},
  8.       {nextId: 'agent', title: 'revise', when: '"REJECTED".equals(review_status) && revision_count.get() < MAX_REVISIONS'},
  9.       {nextId: 'review', title: 'review'}
  10.     ]}
  11.   - {task: '@final_approval', id: 'final_approval', link: 'end'}
  12.   - {task: '@final_failure', id: 'final_failure', link: 'end'}
  13.   - {type: 'end', id: 'end'}
复制代码
3、编写组件


  • agent 根据状态编写内容或修改内容。
  1. @Component("agent")
  2. public class AiNodeAgent implements TaskComponent {
  3.     private static final Logger log = LoggerFactory.getLogger(AiNodeAgent.class);
  4.     private final ChatModel chatModel;
  5.     public AiNodeAgent(ChatModel chatModel) {
  6.         this.chatModel = chatModel;
  7.     }
  8.     @Override
  9.     public void run(FlowContext context, Node node) throws Throwable {
  10.         AtomicInteger revision_count = context.getAs("revision_count");
  11.         String draft_content = context.getAs("draft_content");
  12.         String feedback = context.getAs("feedback");
  13.         List<ChatMessage> messages = context.getAs("messages");
  14.         Prompt prompt = new Prompt();
  15.         //构建 LLM 提示词
  16.         if (revision_count.get() == 0) {
  17.             //第一次:编写内容
  18.             String topic = messages.get(0).getContent();
  19.             prompt.addMessage(ChatMessage.ofSystem("你是一个专业的内容创作者,请根据主题草拟一篇简短的文章。"));
  20.             prompt.addMessage(ChatMessage.ofUser("请草拟关于主题 '" + topic + "' 的文章。"));
  21.         } else {
  22.             //循环:根据反馈修改内容
  23.             prompt.addMessage(ChatMessage.ofSystem("你是一个专业的内容创作者。你收到了人工审核员的反馈,请根据反馈修改你的草稿。"));
  24.             prompt.addMessage(ChatMessage.ofUser("这是你的旧草稿:\\n---\\n" + draft_content + "\\n---\\n这是人工审核员的反馈:\\n---\\n" + feedback + "\\n---\\n请提供修改后的新草稿。"));
  25.         }
  26.         ChatMessage new_draft = chatModel.prompt(prompt).call().getMessage();
  27.         revision_count.incrementAndGet();
  28.         log.info("--- LLM 完成第 {} 次草稿/修改 ---", revision_count.get());
  29.         context.put("draft_content", new_draft.getContent());
  30.         context.put("review_status", "PENDING");
  31.         messages.add(ChatMessage.ofAssistant("提交第 " + revision_count.get() + " 次草稿进行审核。"));
  32.     }
  33. }
复制代码

  • review 模拟人工审核流程,流程在此暂停,等待人工输入。
  1. @Component("review")
  2. public class AiNodeReview implements TaskComponent {
  3.     private static final Logger log = LoggerFactory.getLogger(AiNodeReview.class);
  4.     @Override
  5.     public void run(FlowContext context, Node node) throws Throwable {
  6.         AtomicInteger revision_count = context.getAs("revision_count");
  7.         String draft_content = context.getAs("draft_content");
  8.         List<ChatMessage> messages = context.getAs("messages");
  9.         String feedback;
  10.         String status = null;
  11.         log.info("**人机回路节点激活** - 当前草稿 ({} 次修改):{}",
  12.                 revision_count.get(),
  13.                 (draft_content.length() > 200 ? draft_content.substring(0, 200) + "..." : draft_content));
  14.         //为了演示,我们用 "控制台" 模拟人工输入:
  15.         while (true) {
  16.             System.out.println("请输入审核结果 (approve or reject):");
  17.             String action = getInput();
  18.             if ("approve".equals(action)) {
  19.                 feedback = "Approved.";
  20.                 status = "APPROVED";
  21.                 break;
  22.             } else if ("reject".equals(action)) {
  23.                 System.out.println("请输入拒绝反馈意见: ");
  24.                 feedback = getInput();
  25.                 status = "REJECTED";
  26.                 break;
  27.             } else {
  28.                 System.out.println("输入无效,请重新输入。");
  29.             }
  30.         }
  31.         context.put("review_status", status);
  32.         context.put("feedback", feedback);
  33.         messages.add(ChatMessage.ofUserTmpl("审核结果: #{status}. 反馈: #{feedback}")
  34.                 .paramAdd("status", status)
  35.                 .paramAdd("feedback", feedback)
  36.                 .generate());
  37.     }
  38.     private String getInput() throws Throwable {
  39.         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  40.         return reader.readLine();
  41.     }
  42. }
复制代码

  • final_approval 运行通过。
  1. @Component("final_approval")
  2. public class AiNodeFinalApproval implements TaskComponent {
  3.     @Override
  4.     public void run(FlowContext context, Node node) throws Throwable {
  5.         List<ChatMessage> messages = context.getAs("messages");
  6.         messages.add(ChatMessage.ofAssistant("最终内容已发布!"));
  7.     }
  8. }
复制代码

  • final_failure 运行失败。
  1. @Component("final_failure")
  2. public class AiNodeFinalFailure implements TaskComponent {
  3.     @Override
  4.     public void run(FlowContext context, Node node) throws Throwable {
  5.         List<ChatMessage> messages = context.getAs("messages");
  6.         messages.add(ChatMessage.ofAssistant("流程失败:内容修改次数过多,已退出。"));
  7.     }
  8. }
复制代码
4、组合运行与测试
  1. @Configuration
  2. public class DemoAgent {
  3.     private static final Logger log = LoggerFactory.getLogger(DemoAi.class);
  4.     @Inject
  5.     FlowEngine flowEngine;
  6.     @Bean
  7.     public ChatModel chatModel(){
  8.         return ChatModel.of("http://127.0.0.1:11434/api/chat")
  9.                 .provider("ollama")
  10.                 .model("qwen2.5:1.5b")
  11.                 .build();
  12.     }
  13.     @Init
  14.     public void test() {
  15.         FlowContext context = FlowContext.of()
  16.                 .put("MAX_REVISIONS", 3)
  17.                 .put("draft_content", "")
  18.                 .put("review_status", "NONE")
  19.                 .put("feedback", "")
  20.                 .put("revision_count", new AtomicInteger(0))
  21.                 .put("messages", Utils.asList(ChatMessage.ofUser("智能家居的未来趋势和潜在挑战。")));
  22.         log.info("--- 启动内容审核 Agent ---");
  23.         //执行
  24.         flowEngine.eval("demo1", context);
  25.         //执行后打印
  26.         System.out.println(context.get("draft_content").toString());
  27.         
  28.         List<ChatMessage> messageList = context.getAs("messages");
  29.         for (ChatMessage message : messageList) {
  30.             System.out.println(message);
  31.         }
  32.     }
  33. }
复制代码
5、运行效果截图

1.png

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册