
1. 先搞清楚“AI智能体编写自己的循环架构”到底在解决什么问题看到这个标题很多人的第一反应可能是“AI智能体”和“循环架构”这两个词都懂但连在一起就有点模糊。这很正常因为这是一个非常前沿且具体的工程实践领域。简单来说它要解决的核心问题是如何让一个AI智能体Agent不仅能执行单次任务还能在无人干预的情况下自主地、持续地、有逻辑地运行一个包含多个步骤的复杂流程并且这个流程的“蓝图”即架构可以由智能体自己来生成或优化。这和我们常见的“调用一次API完成一个任务”有本质区别。举个例子一个普通的翻译智能体你给它文本它返回译文任务结束。而一个具备“编写自己循环架构”能力的智能体它的任务可能是“请持续监控这个技术论坛发现有新的关于‘Spring AI’的帖子就总结其核心观点并对比之前类似主题的帖子最后将分析结果发布到周报中。” 这个任务里“监控-总结-对比-发布”就是一个循环架构。更高级的是智能体可能需要自己判断“如何更高效地监控”、“总结的格式是否需要调整”、“对比的维度是否足够”并据此动态修改自己的运行逻辑。所以这篇文章适合两类人看一是对AI智能体Agent开发感兴趣已经不满足于单次问答想探索持续性、自动化任务的开发者二是正在寻找方案来解决复杂、多步骤业务流程自动化问题的技术决策者。最关键的价值在于它能将模糊的“自动化”需求落地为可设计、可观察、可迭代的智能体工作流。2. 理解智能体与循环架构的核心组件在动手之前我们必须把几个关键概念拆开揉碎否则很容易在复杂的代码和框架中迷失方向。一个能“编写自己循环架构”的智能体系统通常由以下几个核心部分组成2.1 智能体Agent本身这不是一个简单的聊天机器人。在这里智能体是一个具备感知、决策、执行、学习能力的程序实体。感知获取外部信息如读取数据库、调用API获取数据、解析网页内容、监听消息队列。决策基于目标、当前状态和历史信息决定下一步做什么。这通常由一个大语言模型LLM驱动但决策逻辑可以被规则引擎约束。执行调用工具Tools去完成具体操作如写入文件、调用另一个服务、发送邮件。学习从历史执行结果中总结经验可能用于优化未来的决策或调整自身的架构参数。2.2 循环架构Loop Architecture这就是智能体运行的“剧本”或“流程图”。它定义了任务执行的顺序、循环条件、分支判断和错误处理。常见的模式有顺序循环A - B - C - (判断是否回到A)。例如获取数据 - 处理数据 - 保存结果 - 等待一段时间 - 重新获取数据。事件驱动循环智能体处于监听状态当特定事件如新文件产生、API被调用触发时执行一系列动作然后回到监听状态。规划-执行-反思循环智能体先规划一系列子任务Plan然后逐个执行Execute最后根据结果反思Reflect并调整后续计划。这个循环可以嵌套。2.3 “编写自己”的含义这是最精妙也最困难的部分。它并不意味着智能体像程序员一样写代码。而是指智能体能够根据任务目标、环境反馈和自身能力动态地调整其循环架构中的某些环节。例如参数调优在数据处理的循环中智能体发现某种数据清洗方法失败率高于是自动调整清洗参数或切换备用方法。路径选择遇到一个分支判断if-else智能体通过尝试或推理选择成功率更高的路径并将此经验固化到后续的循环中。子任务生成面对一个复杂目标智能体将其分解为一系列子任务并安排执行顺序这本身就是创建了一个临时架构。理解了这些我们就知道要实现这个目标不能只靠一个“超级AI”。它需要一个框架Framework来提供运行环境、工具集、状态管理和记忆能力而LLM则作为这个框架的“大脑”负责高级决策和规划。3. 从零搭建环境、框架与第一个循环智能体理论讲完我们进入实战。我会以一个典型的开发路径为例使用目前比较流行且适合上手的框架组合。请注意这里不会推荐任何特定商业平台或存在合规风险的模型服务我们聚焦于开源、可本地部署的方案。3.1 基础环境准备你需要一个能运行Python的环境。我强烈建议使用Linux或macOS进行开发Windows用户可以使用WSL2以获得最佳体验。# 1. 创建并激活虚拟环境以conda为例 conda create -n ai_agent python3.10 conda activate ai_agent # 2. 安装核心框架。这里以LangChain为例它是一个广泛使用的智能体开发框架。 pip install langchain langchain-community # 3. 安装大语言模型接口。为了本地化和可控我们使用Ollama来运行本地LLM。 # 首先去Ollama官网下载并安装Ollama然后拉取一个轻量级模型。 ollama pull llama3.2:3b # 这是一个30亿参数模型对硬件要求较低 # 确保Ollama服务在后台运行 # 4. 安装LangChain的Ollama集成包 pip install langchain-ollama3.2 构建一个简单的“阅读-总结-存档”循环智能体这个智能体会模拟我们开头提到的场景定期读取一个文件夹下的新文本文件总结内容然后归档。首先创建项目结构my_ai_agent_project/ ├── main.py ├── agent_core.py ├── tools/ │ └── file_tools.py ├── workflows/ │ └── reading_loop.py ├── input_files/ # 监控的文件夹 └── processed_files/ # 归档的文件夹第一步定义工具Tools智能体的“手和脚”。tools/file_tools.pyimport os import shutil from datetime import datetime from typing import List class FileTools: 文件操作工具集 staticmethod def list_new_files(directory: str, processed_files: set) - List[str]: 列出指定目录中未处理过的新文件 if not os.path.exists(directory): return [] all_files [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))] new_files [f for f in all_files if f not in processed_files] return new_files staticmethod def read_file_content(file_path: str) - str: 读取文件内容 try: with open(file_path, r, encodingutf-8) as f: return f.read() except Exception as e: return fError reading file: {e} staticmethod def archive_file(original_path: str, archive_dir: str): 将文件移动到归档目录并重命名加上时间戳 if not os.path.exists(archive_dir): os.makedirs(archive_dir) filename os.path.basename(original_path) name, ext os.path.splitext(filename) timestamp datetime.now().strftime(%Y%m%d_%H%M%S) new_filename f{name}_{timestamp}{ext} dest_path os.path.join(archive_dir, new_filename) shutil.move(original_path, dest_path) return dest_path第二步构建智能体核心Agent Core集成LLM和工具。agent_core.pyfrom langchain.agents import AgentExecutor, create_react_agent from langchain_ollama import OllamaLLM from langchain_core.prompts import PromptTemplate from tools.file_tools import FileTools class ReadingSummarizerAgent: def __init__(self): # 1. 初始化本地LLM通过Ollama self.llm OllamaLLM(modelllama3.2:3b, temperature0.1) # 2. 定义工具 self.tools [FileTools.list_new_files, FileTools.read_file_content, FileTools.archive_file] # 注意这里需要将工具包装成LangChain的Tool对象为简化示例我们直接使用。 # 实际中应使用 from langchain.tools import tool 装饰器或 StructuredTool。 # 3. 定义提示词模板告诉智能体它的角色和可用工具 self.prompt PromptTemplate.from_template( 你是一个文件处理智能体。你的任务是持续监控文件夹中的新文件阅读并总结它们然后进行归档。 当前状态 - 监控文件夹{watch_dir} - 已处理文件集合{processed_set} (这是一个集合包含已处理过的文件名) 你可以使用的工具 1. list_new_files: 输入监控文件夹路径和已处理集合返回新文件列表。 2. read_file_content: 输入文件完整路径返回文件内容。 3. archive_file: 输入文件原始路径和归档目录移动文件并返回新路径。 请按照以下逻辑执行一个循环步骤 1. 检查是否有新文件。 2. 如果没有本次循环结束。 3. 如果有读取第一个新文件的内容。 4. 生成一段简洁的内容总结不超过100字。 5. 将该文件归档。 6. 更新已处理文件集合。 7. 输出总结结果和归档路径。 现在请开始执行一步。 输出格式 新文件[是/否] 文件名[文件名] 总结[内容总结] 归档位置[路径] ) # 4. 创建智能体这里简化了实际需使用create_react_agent正确组装 # 由于篇幅我们暂不展开完整的ReAct Agent构建而是用一个简化版的逻辑循环来演示。 def run_one_cycle(self, watch_dir: str, processed_files: set) - (str, set): 执行一个循环步骤 # 模拟智能体的决策与执行过程 tool FileTools() new_files tool.list_new_files(watch_dir, processed_files) if not new_files: return 新文件[否] 本次无新文件。, processed_files target_file new_files[0] file_path os.path.join(watch_dir, target_file) # 读取 content tool.read_file_content(file_path) # 这里本应由LLM生成总结为简化我们模拟一个固定总结 summary f文件{target_file}的主要内容是关于AI智能体开发的初步讨论。 # 归档 archive_path tool.archive_file(file_path, ./processed_files) # 更新已处理集合 processed_files.add(target_file) result f新文件[是] 文件名[{target_file}] 总结[{summary}] 归档位置[{archive_path}] return result, processed_files第三步创建主循环Main Loopmain.pyimport time from agent_core import ReadingSummarizerAgent def main(): print(启动文件监控总结智能体...) agent ReadingSummarizerAgent() watch_directory ./input_files processed set() # 用于记忆已处理文件 # 简单的无限循环模拟智能体的持续运行 cycle_count 0 max_cycles 10 # 防止无限循环实际运行可去掉或设很大 while cycle_count max_cycles: cycle_count 1 print(f\n 循环第 {cycle_count} 次开始 ) result, processed agent.run_one_cycle(watch_directory, processed) print(result) if 新文件[否] in result: print(未检测到新文件等待10秒后重试...) time.sleep(10) # 等待间隔 else: print(文件已处理准备下一次检查...) time.sleep(2) # 处理完一个文件后短暂间隔 print(f\n已完成 {max_cycles} 个循环周期。) if __name__ __main__: main()现在你可以在input_files文件夹里放几个.txt文件然后运行python main.py。你会看到智能体按周期检查、处理、归档文件。这就是一个最基础的、拥有固定循环架构的智能体。4. 从“固定循环”到“自我编写”引入动态规划与反思上面的例子架构是固定的、硬编码的。如何让它“编写自己”关键在于引入动态任务分解Planning和执行反思Reflection。我们将升级智能体让它能处理更模糊的指令。4.1 实现一个具备规划能力的智能体我们使用LangChain的Plan-and-Execute模式。这需要更复杂的设置但概念很直观智能体先制定一个计划一系列子任务然后执行它。首先安装额外依赖pip install langchain-experimental # 包含一些实验性功能如计划执行智能体我们修改核心创建一个能处理自然语言指令的智能体agent_core_advanced.pyfrom langchain.llms import Ollama from langchain_experimental.plan_and_execute import PlanAndExecute, load_agent_executor, load_chat_planner from langchain.agents import Tool from langchain.tools import BaseTool from pydantic import BaseModel, Field from typing import Type # 1. 将之前的文件工具包装成LangChain Tool class ListFilesInput(BaseModel): directory: str Field(description要监控的目录路径) processed_set: str Field(description已处理文件名的集合用逗号分隔) class ListFilesTool(BaseTool): name list_new_files description 列出指定目录中未处理过的新文件。需要提供目录路径和已处理文件集合。 args_schema: Type[BaseModel] ListFilesInput def _run(self, directory: str, processed_set: str): processed set(processed_set.split(,)) if processed_set else set() # ... 调用之前的FileTools.list_new_files逻辑 return str(new_files) # 返回字符串列表 # 类似地创建 read_file_tool, archive_file_tool ... # 2. 初始化LLM和工具列表 llm Ollama(modelllama3.2:3b, temperature0) tools [ListFilesTool(), ReadFileTool(), ArchiveFileTool()] # 3. 创建计划执行智能体 planner load_chat_planner(llm) executor load_agent_executor(llm, tools, verboseTrue) agent PlanAndExecute(plannerplanner, executorexecutor, verboseTrue) # 4. 运行一个复杂指令 instruction 请持续监控 ./input_files 文件夹。 对于每个新出现的 .txt 或 .md 文件执行以下操作 1. 读取其内容。 2. 判断内容主题是否与编程或AI相关。 3. 如果相关生成一段摘要并保存到 ./summaries 文件夹下文件名与原文件相同加 _summary.txt 后缀。 4. 无论是否相关都将原文件移动到 ./processed_files 文件夹归档。 5. 每处理完3个文件就在控制台输出一次简要报告。 请开始执行并持续运行直到我手动停止。 # 注意完全实现这个指令需要更复杂的工具和循环控制此处展示架构。 # agent.run(instruction)在这个架构下智能体接到指令后会先规划“我需要一个循环循环内包含检查文件、过滤、读取、判断、生成摘要、移动文件、计数、报告”。这个“规划”本身就是它为自己生成的临时循环架构。虽然这个架构可能不会持久化保存但每次执行复杂任务时都会动态生成这就是“编写”的雏形。4.2 添加反思Reflection机制优化架构智能体不能只执行还要从结果中学习。例如如果它发现“判断主题”工具经常出错它应该调整判断逻辑或改用其他工具。我们可以创建一个简单的反思步骤在每次循环或任务结束后执行def reflection_step(last_action: str, result: str, history: list) - str: 反思步骤分析上次行动结果给出调整建议 reflection_prompt f 你刚执行了以下操作{last_action} 得到的结果是{result} 历史执行记录最近3次{history[-3:]} 请分析 1. 结果是否成功达到预期 2. 如果失败或低效可能的原因是什么 3. 对下一步行动或未来的任务规划有什么建议 请给出简洁的反思和建议。 # 调用LLM生成反思 reflection llm.invoke(reflection_prompt) return reflection # 在主循环中集成反思 action_history [] for cycle in range(max_cycles): # ... 执行智能体的一个规划-执行周期 ... last_action 处理了文件X result 摘要生成成功但归档失败权限错误 reflection reflection_step(last_action, result, action_history) print(f反思结果{reflection}) # 根据反思结果可以动态调整工具使用顺序、参数或后续计划 # 例如如果反思说“归档失败是权限问题”下次可以尝试先检查权限。 action_history.append((last_action, result, reflection))通过持续的“行动-反思”循环智能体就能不断地优化其行为策略这相当于在微调其“运行架构”中的决策节点。这是“自我编写”更高级的形式。5. 生产环境考量稳定性、监控与架构持久化在实验环境跑通只是第一步。要让这样的智能体可靠运行必须考虑以下问题5.1 状态管理与持久化智能体的“记忆”如已处理文件集合、任务历史、学到的经验必须持久化否则重启后就会失忆。方案使用数据库SQLite/PostgreSQL或向量数据库Chroma/Weaviate存储任务状态、历史记录和反思结论。每次循环开始前加载状态结束后保存状态。5.2 错误处理与重试机制网络波动、工具调用失败、LLM输出格式错误是家常便饭。策略重试对暂时性错误如网络超时设置指数退避重试。降级主要工具失败时启用备用工具或简化流程。隔离单个任务失败不应导致整个智能体崩溃。使用任务队列失败任务进入死信队列待查。警报设置关键错误如连续失败的告警通知邮件、钉钉、Slack。5.3 循环控制与资源限制不能让它无限循环耗尽资源。控制点超时每个工具调用、每个LLM请求、每个任务循环设置超时。速率限制控制调用外部API的频率。循环终止条件明确停止条件如“处理完所有文件”、“达到最大循环次数”、“收到停止信号”。资源监控监控智能体进程的内存、CPU占用。5.4 架构的版本化与回滚如果智能体动态“编写”或调整了架构如何管理建议不要允许智能体直接修改核心生产架构。而是让它生成“架构调整建议”由人工或一个更高级的审核流程批准后再更新到版本化的配置文件中。每次架构变更都有记录可随时回滚。5.5 可观测性Observability你必须知道智能体在干什么、干得怎么样。必须记录的日志决策日志LLM接收的提示词和生成的决策/计划。工具调用日志调用了什么工具、输入输出是什么、耗时多少。状态变更日志关键状态如已处理列表的变化。反思日志每次反思的内容和建议。可视化考虑使用Grafana等工具展示智能体的任务吞吐量、成功率、耗时等指标。6. 常见问题与排查路径当你自己动手搭建时几乎一定会遇到下面这些问题。别急着改代码按这个顺序排查6.1 智能体不执行循环或只执行一次先看循环条件检查你的while循环或调度逻辑。是不是终止条件设错了是不是没加time.sleep导致CPU跑满但实际逻辑没推进再看状态更新智能体是否正确地更新了它的“记忆”如processed_files集合如果状态没更新下次循环会认为同一个任务还没做可能陷入死循环或跳过。检查阻塞点在循环内加入更详细的日志打印每个阶段检查、决策、执行、保存的开始和结束。看看卡在哪一步。6.2 LLM响应慢或不可用确认Ollama服务运行ollama list和ollama ps确认模型已下载且服务在运行。降低模型规格如果用的是7B、13B甚至更大的模型对硬件要求高。初次测试可换用更小的模型如llama3.2:3b或phi3:mini。检查提示词过长的提示词或复杂的上下文会导致生成变慢。优化提示词只保留必要信息。设置超时在LangChain调用LLM时务必设置request_timeout参数。6.3 工具调用失败路径问题这是最常见的问题。所有文件路径都使用绝对路径或者确保相对路径是基于正确的当前工作目录。在代码开头用os.path.abspath()打印一下关键路径确认。权限问题智能体进程是否有权读取输入文件夹、写入输出和归档文件夹在Linux/macOS上尤其注意。工具输入输出格式LangChain的Tool对输入参数格式有严格要求。确保你定义的args_schema和工具函数的参数匹配并且返回类型是字符串或字典。6.4 智能体决策“幻觉”或逻辑混乱约束提示词在给LLM的提示词中必须明确约束其输出格式和行动范围。使用类似“你必须从以下工具中选择...”、“你的输出必须是以下JSON格式...”这样的强指令。提供示例在提示词中加入一两个完整的思考过程示例Few-Shot Learning能极大提高智能体遵循逻辑的能力。降低“创造力”将LLM的temperature参数调低如0.1使其输出更确定、更可预测。6.5 如何扩展到更复杂的业务场景从简单循环开始不要一开始就设计一个万能智能体。先实现一个能稳定运行的最简单闭环如我们的文件监控例子。逐步添加工具每新增一个工具如调用数据库、发送HTTP请求都单独测试这个工具是否能被智能体正确调用。分阶段规划对于复杂目标让智能体先输出一个分阶段计划Phase 1: 收集数据 Phase 2: 分析 Phase 3: 报告然后分阶段执行并确认这比让它直接生成一个超长行动计划更可靠。人类在环在关键决策点如删除数据、发布内容设置人工审核环节让智能体将提案提交给人批准后再执行。7. 总结从概念到落地的关键认知最后抛开具体代码我想分享几个在实践“AI智能体编写自己的循环架构”时最重要的心得第一智能体不是魔法是工程。它的“智能”来源于清晰的规则、设计良好的工具、高质量的提示词和稳定的基础设施。LLM是强大的决策引擎但整个系统的可靠性取决于你如何搭建它。第二“自我编写”是程度问题。从完全硬编码的循环到能动态生成任务列表再到能根据反思调整策略这是一个光谱。大部分实用场景我们追求的是“有限的自我调整能力”即在预设框架内的灵活性和适应性而不是完全无约束的自我创造。第三先让循环转起来再让它变聪明。我见过太多项目一开始就陷入对“完美架构”的设计而忽略了最基本的“启动-执行-结束”循环能否跑通。你的首要目标是构建一个哪怕很笨、但能稳定完成一次任务循环的智能体。在这个基础上迭代加入规划、反思、多工具协作等能力。第四可观测性优先于功能性。一个你完全不知道内部状态的智能体是危险的。在开发早期就要投入精力建立日志、状态追踪和简单的仪表盘。当它行为异常时你能快速定位是提示词问题、工具错误还是状态混乱这比增加新功能重要得多。如果你正打算开始这类项目我的建议是选择一个你非常熟悉的、边界清晰的微小业务场景比如自动整理每日下载的文档使用LangChainOllama或其他本地LLM方案这个组合快速搭建原型。重点感受智能体“感知-决策-执行”的流程以及状态管理的重要性。当这个微小原型能稳定运行一周后你会对如何设计更复杂的、具备“自我编写”潜力的循环架构有完全不同的、来自实战的理解。