人工智能大模型AI Agent工作流自动化RAG【免费下载链接】PocketFlowPocket Flow: 100-line LLM framework. Let Agents build Agents!项目地址https://gitcode.com/gh_mirrors/poc/PocketFlow点击查看免费下载多个 Agent 可以通过各自处理子任务、互相沟通进度来协同完成复杂工作。在 PocketFlow 中Agent 之间最常见的通信方式是共享存储 消息队列每个 Agent 是一个监听循环从队列中取消息、处理、再把结果投递给下一个 Agent。本文以官方设计模式文档 docs/design_pattern/multi_agent.md 为核心骨架结合AsyncNode/AsyncFlow的源码实现与仓库内可运行的完整示例 cookbook/pocketflow-multi-agent从零讲解如何用asyncio.Queue在多个异步 Agent 之间建立可靠的双向通信并给出一个可直接运行的Taboo 猜词游戏多 Agent 实战。什么时候才需要多 Agent多 Agent 的核心思想是分治与协作把一个大任务拆成子任务交给不同的 Agent每个 Agent 专注做好自己的部分并通过通信机制交换中间结果与进度。但在动手设计多 Agent 系统之前请先记住 PocketFlow 官方文档给出的一条最佳实践Most of time, you dont need Multi-Agents. Start with a simple solution first.大多数时候你并不需要多 Agent先从一个简单的方案开始。原因在于多 Agent 引入了额外的通信开销、协调复杂度和故障排查成本。如果单个 Flow 加上条件分支就能解决问题就不值得引入多 Agent。只有当任务确实需要多个职责独立、需要并行推进且彼此交换信息的角色时才适合采用这种架构。多 Agent 的通信基石共享存储与消息队列多个 Agent 协同的通信机制通常用共享存储中的消息队列来实现。在 PocketFlow 中所有节点共享一个shared字典shared store而asyncio.Queue对象可以被放进这个shared字典中成为 Agent 之间天然的异步消息通道共享存储sharedAgent 之间交换的上下文、历史记录等状态放在同一个字典里。消息队列asyncio.QueueAgent 之间点对点投递消息。发送方await queue.put(msg)接收方await queue.get()阻塞等待天然支持异步非阻塞通信。这一模式与 PocketFlow 的异步核心抽象一脉相承。从 pocketflow/init.py 的源码可以看到AsyncNode提供了prep_async/exec_async/exec_fallback_async/post_async四个可覆写的异步钩子而AsyncFlow通过_orch_async循环驱动节点执行async def _orch_async(self, shared, paramsNone): curr, p, last_action copy.copy(self.start_node), (params or {**self.params}), None while curr: curr.set_params(p) last_action await curr._run_async(shared) if isinstance(curr, AsyncNode) else curr._run(shared) curr copy.copy(self.get_next_node(curr, last_action)) return last_action这里的last_action由节点post_async返回的字符串决定了下一步走向哪个后继节点这正是实现监听 → 处理 → 回环继续监听无限循环 Agent 的底层机制。官方文档 docs/core_abstraction/async.md 也明确指出post_async()的典型用途之一就是跨多 Agent 的协调coordinating across multi-agents。示例一用 asyncio.Queue 实现心跳消息监听 Agent先看一个最简单的多 Agent 通信骨架一个 Agent 节点不断从队列中取消息、处理、然后连接到自己形成监听循环同时一个独立的协程作为系统消息发送者周期性向队列投递消息。class AgentNode(AsyncNode): async def prep_async(self, _): message_queue self.params[messages] message await message_queue.get() print(fAgent received: {message}) return message # Create node and flow agent AgentNode() agent agent # connect to self flow AsyncFlow(startagent) # Create heartbeat sender async def send_system_messages(message_queue): counter 0 messages [ System status: all systems operational, Memory usage: normal, Network connectivity: stable, Processing load: optimal ] while True: message f{messages[counter % len(messages)]} | timestamp_{counter} await message_queue.put(message) counter 1 await asyncio.sleep(1) async def main(): message_queue asyncio.Queue() shared {} flow.set_params({messages: message_queue}) # Run both coroutines await asyncio.gather( flow.run_async(shared), send_system_messages(message_queue) ) asyncio.run(main())运行输出Agent received: System status: all systems operational | timestamp_0 Agent received: Memory usage: normal | timestamp_1 Agent received: Network connectivity: stable | timestamp_2 Agent received: Processing load: optimal | timestamp_3这个例子展示了多 Agent 通信的三个关键要素通过 params 注入队列flow.set_params({messages: message_queue})把队列传给流节点在prep_async中通过self.params[messages]取出。从源码看AsyncFlow._orch_async会在每轮循环调用curr.set_params(p)把参数注入当前节点。自连接形成监听循环agent agent利用BaseNode.__rshift__把节点连接到自己post_async返回的 action 让流回到同一节点形成取一条 → 处理一条 → 再取一条的持续监听循环。并发驱动asyncio.gather(flow.run_async(shared), send_system_messages(queue))让 Agent 流与消息发送者协程并行运行队列在这两者之间完成数据搬运。示例二Taboo 猜词游戏 —— 双 Agent 交互式实战接下来是官方文档中更复杂的交互式多 Agent 示例两个 Agent 玩文字猜词游戏 Taboo。AsyncHinter提示者负责给出避开禁用词、不超过 5 个词的提示AsyncGuesser猜词者根据提示猜目标词。两者通过两条消息队列往返通信猜对即结束游戏。class AsyncHinter(AsyncNode): async def prep_async(self, shared): guess await shared[hinter_queue].get() if guess GAME_OVER: return None return shared[target_word], shared[forbidden_words], shared.get(past_guesses, []) async def exec_async(self, inputs): if inputs is None: return None target, forbidden, past_guesses inputs prompt fGenerate hint for {target}\nForbidden words: {forbidden} if past_guesses: prompt f\nPrevious wrong guesses: {past_guesses}\nMake hint more specific. prompt \nUse at most 5 words. hint call_llm(prompt) print(f\nHinter: Heres your hint - {hint}) return hint async def post_async(self, shared, prep_res, exec_res): if exec_res is None: return end await shared[guesser_queue].put(exec_res) return continue class AsyncGuesser(AsyncNode): async def prep_async(self, shared): hint await shared[guesser_queue].get() return hint, shared.get(past_guesses, []) async def exec_async(self, inputs): hint, past_guesses inputs prompt fGiven hint: {hint}, past wrong guesses: {past_guesses}, make a new guess. Directly reply a single word: guess call_llm(prompt) print(fGuesser: I guess its - {guess}) return guess async def post_async(self, shared, prep_res, exec_res): if exec_res.lower() shared[target_word].lower(): print(Game Over - Correct guess!) await shared[hinter_queue].put(GAME_OVER) return end if past_guesses not in shared: shared[past_guesses] [] shared[past_guesses].append(exec_res) await shared[hinter_queue].put(exec_res) return continue async def main(): # Set up game shared { target_word: nostalgia, forbidden_words: [memory, past, remember, feeling, longing], hinter_queue: asyncio.Queue(), guesser_queue: asyncio.Queue() } print(Game starting!) print(fTarget word: {shared[target_word]}) print(fForbidden words: {shared[forbidden_words]}) # Initialize by sending empty guess to hinter await shared[hinter_queue].put() # Create nodes and flows hinter AsyncHinter() guesser AsyncGuesser() # Set up flows hinter_flow AsyncFlow(starthinter) guesser_flow AsyncFlow(startguesser) # Connect nodes to themselves hinter - continue hinter guesser - continue guesser # Run both agents concurrently await asyncio.gather( hinter_flow.run_async(shared), guesser_flow.run_async(shared) ) asyncio.run(main())运行输出Game starting! Target word: nostalgia Forbidden words: [memory, past, remember, feeling, longing] Hinter: Heres your hint - Thinking of childhood summer days Guesser: I guess its - popsicle Hinter: Heres your hint - When childhood cartoons make you emotional Guesser: I guess its - nostalgic Hinter: Heres your hint - When old songs move you Guesser: I guess its - memories Hinter: Heres your hint - That warm emotion about childhood Guesser: I guess its - nostalgia Game Over - Correct guess!逐环节拆解通信流程这个游戏本质上是两条单向队列拼成的双向通信管道初始化main先把一个空字符串投进hinter_queue相当于开始信号否则AsyncHinter.prep_async会永久阻塞在await queue.get()。Hinter 出题取出 guess首轮为空串后把target_word、forbidden_words、past_guesses组装成提示词 prompt调用 LLM 生成提示语post_async把提示语put进guesser_queue返回continue触发自连接回环。Guesser 猜词从guesser_queue拿到提示语结合历史错误猜测生成单个词的猜测若猜中向hinter_queue投递GAME_OVER终止信号并返回end结束自身循环若未猜中把猜测追加进shared[past_guesses]作为上下文供下一轮提示使用再把猜测投回hinter_queue返回continue继续循环。终止机制AsyncHinter.prep_async读到GAME_OVER时返回Noneexec_async/post_async随之短路返回endHinter 循环终止。两个 Flow 都结束时asyncio.gather返回。这里用到了 PocketFlow 的条件转移语法hinter - continue hinter。从 pocketflow/init.py 源码可以看到BaseNode.__sub__返回一个_ConditionalTransition其__rshift__最终调用src.next(tgt, action)把continue这个动作注册为指向自身的后继边def __sub__(self, action): if isinstance(action, str): return _ConditionalTransition(self, action) raise TypeError(Action must be a string) class _ConditionalTransition: def __init__(self, src, action): self.src, self.action src, action def __rshift__(self, tgt): return self.src.next(tgt, self.action)这也印证了post_async返回值action 字符串与转移边- action 之间的对应关系——这是 PocketFlow 中实现回环监听与状态机流转的统一机制官方测试 tests/test_async_flow.py 中的test_async_flow_branching等用例也验证了异步节点基于 action 分流的正确性。仓库内可直接运行的完整实现官方文档中的两个示例是精简的教学版仓库的 cookbook 目录下提供了完整的、可直接运行的 Taboo 游戏实现 cookbook/pocketflow-multi-agent包含 4 个文件文件作用main.py入口AsyncHinter/AsyncGuesser节点、双队列、双 AsyncFlow 并发驱动utils.pycall_llm()封装基于 OpenAI SDK 调用gpt-4o-minirequirements.txt依赖pocketflow0.0.1、openai1.0.0、pyyaml6.0README.md架构说明AsyncHinter -- MessageQueue -- AsyncGuesser与运行输出示例运行步骤pip install -r requirements.txt export OPENAI_API_KEYyour_api_key_here python main.py相比文档示例cookbook 版在几处做了实战化调整值得对照学习目标词与终止判断cookbook 使用nostalgic作为目标词并统一用.lower()做大小写不敏感匹配exec_res.lower() shared[target_word].lower()避免 LLM 输出大小写差异导致死循环。循环终止hinter - continue hinter与guesser - continue guesser两条自连接边让两个 Agent 各自循环直到猜中后经GAME_OVER信号与end动作双双退出。共享状态演进past_guesses通过shared.get(past_guesses, [])惰性初始化并持续累积成为 Hint 的上下文记忆——这与 Agent 设计模式 中强调的上下文管理要点一致给 LLM 提供相关且精简的上下文最近几次错误猜测而不是堆砌全部历史。仓库示例的运行输出也展示了一次完整对局Hinter 给出提示、Guesser 连续猜测、最终猜中Nostalgic后游戏自动结束可以作为验证程序正确性的对照基准。从设计模式到生产实践的要点综合官方文档 docs/design_pattern/multi_agent.md 与上述实现落地多 Agent 通信时有几点经验值得沉淀先简单后复杂能用一个 Flow 条件分支解决的不要引入多 Agent多 Agent 的价值在于职责解耦与并行推进代价是通信与协调复杂度。队列与共享状态职责分离asyncio.Queue负责消息流谁在什么时候说话shared字典负责状态共同记忆、上下文、最终结果。示例中past_guesses放在 shared、而即时消息走队列正是这一分工的体现。显式定义终止条件无限循环的监听 Agent 必须有明确的结束信号。Taboo 示例用GAME_OVER哨兵消息 endaction 双保险终止避免两个 Agent 永久空转。善用 AsyncNode 的三阶段钩子prep_async做阻塞式取消息I/O 友好、exec_async放 LLM 调用、post_async做跨 Agent 协调写回队列、判定 next action。这一阶段划分在 docs/core_abstraction/async.md 中有明确说明能有效隔离读数据 / 算 / 写状态三类职责。失败重试与容错多 Agent 场景中任何一方 LLM 调用失败都会卡住通信循环可结合 Node 的max_retries与wait参数如AsyncHinter(max_retries3, wait10)为exec_async增加重试与退避提升整体鲁棒性。从源码层面看整个机制最终都收敛到 pocketflow/init.py 中不足百行的核心实现AsyncNode._run_async依次执行prep_async → _exec → post_asyncAsyncFlow._orch_async依据返回的 action 驱动节点跳转。多 Agent 通信并不需要框架层面的任何特殊支持——asyncio.Queue塞进 shared 字典配合自连接边PocketFlow 的既有抽象就足以支撑任意复杂的 Agent 协作拓扑。赞分享人工智能大模型AI Agent工作流自动化RAG【免费下载链接】PocketFlowPocket Flow: 100-line LLM framework. Let Agents build Agents!项目地址https://gitcode.com/gh_mirrors/poc/PocketFlow点击查看免费下载相关推荐lamp-cloud消息队列实战基于RabbitMQ的异步通信方案lamp cloud消息队列实战基于RabbitMQ的异步通信方案 lamp cloud是一个功能强大的微服务架构平台其消息队列功能基于RabbitMQ实现后端微服务认证鉴权API网关终极指南如何利用Hyperswitch实现高可靠支付消息异步通信终极指南如何利用Hyperswitch实现高可靠支付消息异步通信 Hyperswitch作为一款功能强大的支付编排平台其内部集成了高效的消息队列系统专门用后端金融科技agents24 Agent Teams 实战指南七套多 Agent 通信消息模板与协议全解agents24 Agent Teams 实战指南七套多 Agent 通信消息模板与协议全解 本篇围绕 agents24 仓库中 agent teams 插件AI 插件AI 技能开发工具上一篇告别PDF安全焦虑Stirling-PDF如何用AES守护你的文档隐私下一篇从源码到应用7 Taskbar Tweaker核心功能实现原理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
YOLOv5实战:从环境配置到TensorRT部署的完整避坑指南 简介:一份面向YOLOv5初学者的完整实战代码仓库,源自B站手把手课程,系统覆盖入门、拓展、进阶、部署四个篇章,适合希望从环境搭建到模型部署全流程跟学的开发者和学生。压缩包共340个文件,以Python训练/推理脚本、YAML模… · 2026/9/23 21:39:31
交通标志检测实战:YOLOv8数据集转换与训练调参全攻略 简介:基于Python的交通标志检测与识别项目源码与数据模型包,定位为计算机专业毕业设计、期末大作业及项目实战练习者的完整参考方案,内容覆盖了从图像预处理、特征提取、模型训练到交通标志识别输出的主要开发环节,难度适中&#… · 2026/9/23 21:39:25
X光安检目标检测数据集:VOC+YOLO双格式3600张10类实战指南 简介:本资源是面向计算机视觉初学者与目标检测算法研发者的X光安检场景专用数据集,覆盖打火机、刀具、充电宝等10类违禁物品,适用于YOLO系列、Faster R-CNN等主流检测模型的训练与测试验证。压缩包共2000个文件,主体为3600张JPG图… · 2026/9/23 21:39:25
10吨锅炉配多大的脱硫塔?风量、直径、高度怎么算 开篇结论:脱硫塔选多大,不是看感觉,是看两个数:烟气量定塔径,入口SO₂浓度定塔高和层数。1蒸吨锅炉约2500–3500 m/h烟气,10吨约25000–35000 m/h,参考塔径2.0–2.6米。浓度高就加喷淋层。1. 塔… · 2026/9/23 22:20:29
RedwoodJS 教程实战:从 Prisma 建模到 Service 测试,为博客添加完整评论功能 RedwoodJS 教程实战:从 Prisma 建模到 Service 测试,为博客添加完整评论功能 【免费下载链接】redwood RedwoodGraphQL 项目地址: https://gitcode.com/gh_mirrors/re/redwood
本篇技术指南以 RedwoodJS 官方教程第 6 章为核心,完整演… · 2026/9/23 22:20:17
脱硫塔和洗涤塔有什么区别?六种废气处理塔一张表分清 开篇结论:脱硫塔专治锅炉烟气SO₂,洗涤塔是通用主力;碱洗塔治酸性废气,酸洗塔治碱性废气,水洗塔洗可溶气体,喷淋塔是统称。六种废气塔分不清?一张表帮你选对。1. 六塔对比表名称原理主要处理对象… · 2026/9/23 22:20:04
旅游景点情感分析:细粒度属性级建模与BERT微调实践 简介:本资源是一套面向计算机专业本科生的毕业设计实战项目,聚焦旅游景点评论的细粒度情感分析任务,适用于Python Web开发、自然语言处理与数据库应用等课程实践或毕设选题参考。项目基于Django框架构建Web系统,集成RNCC情感分析模… · 2026/9/23 22:19:58
117 Kubernetes部署Agent服务 117 Kubernetes部署Agent服务
那晚的告警到现在还记得,新上线的采集Agent在测试集群里一会儿Running一会儿CrashLoopBackOff,kubectl logs抓出来就一行“Failed to create Kubernetes client: can’t create rest client: dial tcp: lookup kube-apiserver on 10.96.0.10:53… · 2026/9/23 22:19:58
119、Agent的配置管理与动态化 119、Agent的配置管理与动态化
那晚线上告警响得人头皮发麻。一个负责代码审查的Agent,突然开始对每一行 print 都提出“请使用日志框架”的整改意见,连测试文件都不放过。我拉出日志,发现它加载的规则版本号还停留在三天前——可我明明昨天才在配置中心把这条规则下架了。… · 2026/9/23 22:19:52
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29