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

news/2025/12/9 23:08:59/文章来源:https://www.cnblogs.com/noear/p/19328690

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

id: demo1
layout:- {type: 'start'}- {task: '@agent', id: 'agent'}- {task: '@review', id: 'review', type: exclusive, link: [{nextId: 'final_approval', title: 'approved', when: '"APPROVED".equals(review_status)'},{nextId: 'final_failure', title: 'failed', when: '"REJECTED".equals(review_status) && revision_count.get() >= MAX_REVISIONS'},{nextId: 'agent', title: 'revise', when: '"REJECTED".equals(review_status) && revision_count.get() < MAX_REVISIONS'},{nextId: 'review', title: 'review'}]}- {task: '@final_approval', id: 'final_approval', link: 'end'}- {task: '@final_failure', id: 'final_failure', link: 'end'}- {type: 'end', id: 'end'}

3、编写组件

  • agent 根据状态编写内容或修改内容。
@Component("agent")
public class AiNodeAgent implements TaskComponent {private static final Logger log = LoggerFactory.getLogger(AiNodeAgent.class);private final ChatModel chatModel;public AiNodeAgent(ChatModel chatModel) {this.chatModel = chatModel;}@Overridepublic void run(FlowContext context, Node node) throws Throwable {AtomicInteger revision_count = context.getAs("revision_count");String draft_content = context.getAs("draft_content");String feedback = context.getAs("feedback");List<ChatMessage> messages = context.getAs("messages");Prompt prompt = new Prompt();//构建 LLM 提示词if (revision_count.get() == 0) {//第一次:编写内容String topic = messages.get(0).getContent();prompt.addMessage(ChatMessage.ofSystem("你是一个专业的内容创作者,请根据主题草拟一篇简短的文章。"));prompt.addMessage(ChatMessage.ofUser("请草拟关于主题 '" + topic + "' 的文章。"));} else {//循环:根据反馈修改内容prompt.addMessage(ChatMessage.ofSystem("你是一个专业的内容创作者。你收到了人工审核员的反馈,请根据反馈修改你的草稿。"));prompt.addMessage(ChatMessage.ofUser("这是你的旧草稿:\\n---\\n" + draft_content + "\\n---\\n这是人工审核员的反馈:\\n---\\n" + feedback + "\\n---\\n请提供修改后的新草稿。"));}ChatMessage new_draft = chatModel.prompt(prompt).call().getMessage();revision_count.incrementAndGet();log.info("--- LLM 完成第 {} 次草稿/修改 ---", revision_count.get());context.put("draft_content", new_draft.getContent());context.put("review_status", "PENDING");messages.add(ChatMessage.ofAssistant("提交第 " + revision_count.get() + " 次草稿进行审核。"));}
}
  • review 模拟人工审核流程,流程在此暂停,等待人工输入。
@Component("review")
public class AiNodeReview implements TaskComponent {private static final Logger log = LoggerFactory.getLogger(AiNodeReview.class);@Overridepublic void run(FlowContext context, Node node) throws Throwable {AtomicInteger revision_count = context.getAs("revision_count");String draft_content = context.getAs("draft_content");List<ChatMessage> messages = context.getAs("messages");String feedback;String status = null;log.info("**人机回路节点激活** - 当前草稿 ({} 次修改):{}",revision_count.get(),(draft_content.length() > 200 ? draft_content.substring(0, 200) + "..." : draft_content));//为了演示,我们用 "控制台" 模拟人工输入:while (true) {System.out.println("请输入审核结果 (approve or reject):");String action = getInput();if ("approve".equals(action)) {feedback = "Approved.";status = "APPROVED";break;} else if ("reject".equals(action)) {System.out.println("请输入拒绝反馈意见: ");feedback = getInput();status = "REJECTED";break;} else {System.out.println("输入无效,请重新输入。");}}context.put("review_status", status);context.put("feedback", feedback);messages.add(ChatMessage.ofUserTmpl("审核结果: #{status}. 反馈: #{feedback}").paramAdd("status", status).paramAdd("feedback", feedback).generate());}private String getInput() throws Throwable {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));return reader.readLine();}
}
  • final_approval 运行通过。
@Component("final_approval")
public class AiNodeFinalApproval implements TaskComponent {@Overridepublic void run(FlowContext context, Node node) throws Throwable {List<ChatMessage> messages = context.getAs("messages");messages.add(ChatMessage.ofAssistant("最终内容已发布!"));}
}
  • final_failure 运行失败。
@Component("final_failure")
public class AiNodeFinalFailure implements TaskComponent {@Overridepublic void run(FlowContext context, Node node) throws Throwable {List<ChatMessage> messages = context.getAs("messages");messages.add(ChatMessage.ofAssistant("流程失败:内容修改次数过多,已退出。"));}
}

4、组合运行与测试

@Configuration
public class DemoAgent {private static final Logger log = LoggerFactory.getLogger(DemoAi.class);@InjectFlowEngine flowEngine;@Beanpublic ChatModel chatModel(){return ChatModel.of("http://127.0.0.1:11434/api/chat").provider("ollama").model("qwen2.5:1.5b").build();}@Initpublic void test() {FlowContext context = FlowContext.of().put("MAX_REVISIONS", 3).put("draft_content", "").put("review_status", "NONE").put("feedback", "").put("revision_count", new AtomicInteger(0)).put("messages", Utils.asList(ChatMessage.ofUser("智能家居的未来趋势和潜在挑战。")));log.info("--- 启动内容审核 Agent ---");//执行flowEngine.eval("demo1", context);//执行后打印System.out.println(context.get("draft_content").toString());List<ChatMessage> messageList = context.getAs("messages");for (ChatMessage message : messageList) {System.out.println(message);}}
}

5、运行效果截图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/995694.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全编程——基于Python达成的SSH通信(Windows执行)

网络安全编程——基于Python达成的SSH通信(Windows执行)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…

2025 最新水磨石抗污剂厂家 TOP5 评测!环保高性能标杆榜单发布,守护石材持久美观。国内水磨石抗污剂品牌2025年度盘点 - 全局中转站

随着水磨石在商业空间、高端住宅及公共设施中的广泛应用,其易渗污、难养护的问题日益凸显,水磨石抗污剂市场需求持续攀升。本榜单基于产品环保性能、抗污效果持久性、适用场景广泛性及行业口碑四大核心维度,结合国内…

OTOFIX IM2 1-Year Update Subscription: Ensure Latest Vehicle Diagnostics for European/American Cars

Staying Ahead in Automotive Diagnostics: The OTOFIX IM2 One Year Update Service Problem: Outdated Data Holds Back Repairs In today’s rapidly evolving automotive landscape, European and American mechan…

深入解析:2025年11月11日 AI快讯

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

北京守嘉健康干细胞项目介绍 - 品牌排行榜单

守嘉(北京)健康管理有限公司,秉承“引领主动健康,解码生命未来”的理念,通过与生命科学领域的前沿机构北京九思九如健康科技有限公司和北京福安华生物科技有限公司的深度战略合作,整合顶尖科研与临床资源,正式推…

统计文本文件记录

$folderPath = Read-Host "Enter the folder path" function mainMenu { while($prompt -ne ){$totaLines = 0 $n = 0 Get-ChildItem -Path $folderPath -Filter *.txt -Recurse | ForEach-Object { $fileL…

2025最新水洗石抗污剂厂家TOP5评测!环保性能与抗污效果品牌双权威榜单发布,技术赋能重构景观防护生态 - 全局中转站

随着水洗石材料在园林景观、市政工程、商业空间等场景的广泛应用,其抗污防护需求日益凸显。水洗石抗污剂作为提升材料耐久性与美观度的核心产品,市场关注度持续升温。本榜单基于环保安全、抗污性能、场景适配、服务体…

When Ongeki Gets Stuck at the Aime Check

When I updated Ongeki to version 1.21i, I inexplicably ran into the problem of getting stuck at the Aime check. If you are encountering the same issue: I know this is totally messed up, but trust me �…

如果同一个子网中,设备超过255台,那会如何才能保证处于同一子网

要让超过 255 台设备处于同一子网,核心是 扩大网段容量—— 通过选择「网络位更短、主机位更长」的子网掩码(即 CIDR 标识中「/」后面的数字小于 24),让网段可容纳的设备数量超过 253 台(/24 的上限)。关键原理:…

Autel MaxiPRO MP808TS 1-Year Update Subscription: Keep Your Diagnostic Tool Updated Effective

The Challenge: Outdated Diagnostics in a Rapidly Evolving Market Modern vehicles are evolving at an unprecedented pace, with advanced ECUs, hybrid/electric systems, and complex safety protocols becomin…

需求的变更控制

目录1. “变更的影响是可以接受的。”理解方式典型实践2. “受到变更影响的所有人都接到通知并明白这一点。”理解方式典型实践3. “由合适的人选来作出接受变更的正式决定。”理解方式如果没有“正式决定”会发生什么…

在java中实现c#的int.TryParse方法

在java中实现c#的int.TryParse方法在Java中实现类似C#的 int.TryParse方法,确实能带来更安全、更优雅的编码体验(指数字转换)。在.net(c#)的mscorlib程序集中,以System.Int32(int的实际类型)为例,有如下TryParse…

【值得收藏】构建企业级智能体RAG系统:解决大模型五大痛点,让AI真正理解业务 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

基于微信小应用的茶叶茶具销售和管理系统(源码+论文+部署+安装)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

我的 OI 生涯(更新中)

生活记录而已,全是流水账,不喜勿喷。 坐标:FJ XM 于 2025-12-9 开始编撰。 内容不会涉及其他人。 前言 父母都是程序员,所以从小多多少少有接触一些编程,也为我日后 OI 的生涯打下了基础。 大概是五年级时,被朋友…

少儿编程哪家强?这几家机构不容错过! - 品牌测评鉴赏家

少儿编程哪家强?这几家机构不容错过!编程热下的选择难题 在当今数字化飞速发展的时代,少儿编程学习已然成为一股热潮。走在街头,时不时就能看到少儿编程培训机构的招牌;打开社交媒体,也总能刷到孩子们展示自己编…

为AI时代蓄力:除了几大热门,还有哪些值得关注的少儿编程选择? - 品牌测评鉴赏家

为AI时代蓄力:除了几大热门,还有哪些值得关注的少儿编程选择?在为孩子选择人工智能与编程学习机构时,许多家长的目光往往聚焦于少数几个知名品牌。然而,教育的选择在于“适合”而非“名气”。如果您希望为孩子寻找…

网络协议之传统DNS存在的问题以及httpdns - 详解

网络协议之传统DNS存在的问题以及httpdns - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", …

孩子想学人工智能,有推荐的机构吗?2025 年权威测评与精选指南 - 品牌测评鉴赏家

孩子想学人工智能,有推荐的机构吗?2025 年权威测评与精选指南20 25 年教育行业数据显示,75% 的家长在为孩子选择人工智能机构时面临 “课程内容浅层化”“师资背景不透明”“实践场景缺失” 三大难题。调研发现,家…

[挑战成为CCPC传奇单挑王暨第二届CACC游记]一、我又回来了

一首应景小歌送给各位 现在是2025-12-09,刚从CACC回来了,总之是没爆零。第一题是高精度加法,前30%的数据随便过,但是我很不屑,非要拿100%的分,然后没调出来。最后拿了30%。不会套模板,hh。第二题爆零了,我总是…