从Prompt Engineering到Loop Engineering:构建具备闭环执行能力的AI Agent 你好我是CSDN的一名技术博主。在探索AI应用落地的过程中我发现很多开发者对如何构建一个真正能“自主思考”和“持续行动”的智能体AI Agent感到困惑。网上资料要么停留在基础的Prompt Engineering要么直接跳到复杂的框架缺少一个从“静态指令”到“动态循环”的完整学习路径。本文将为你系统梳理从Prompt Engineering到Loop Engineering的核心概念、实战方法与学习路线帮助你从零开始构建一个具备闭环执行能力的AI Agent。1. 背景与核心概念从静态指令到动态智能体在AI大模型应用开发的早期我们主要关注Prompt Engineering提示工程。它的核心是精心设计一段静态的文本指令Prompt引导大模型如GPT-4、Claude等生成符合预期的、高质量的回复。这就像给一个知识渊博但缺乏主动性的助手一份详尽的工作说明书。然而现实世界的问题往往是复杂、多步骤且动态变化的。例如“帮我分析这个GitHub仓库最近的活跃度并写一份报告”这涉及到克隆代码、解析提交历史、计算指标、生成图表和撰写文字等多个步骤。单一的、静态的Prompt无法胜任。这时我们就需要AI Agent智能体。一个AI Agent可以被理解为一个能感知环境、进行决策并执行行动以达成目标的软件实体。它不再是被动响应而是主动规划。而让Agent真正“活”起来能够处理复杂任务的关键就在于Loop Engineering循环工程。Loop Engineering指的是设计和实现AI Agent内部驱动其持续运作的循环逻辑。这个循环通常包含几个核心阶段感知Perception - 规划Planning - 执行Action- 观察Observation。Agent会在这个循环中不断迭代直到任务完成或达到终止条件。简单来说Prompt Engineering是让大模型“好好说话”的艺术。AI Agent是能“自己干活”的智能程序。Loop Engineering是驱动Agent“持续思考并行动”的引擎。理解这三者的演进关系是掌握AI Agent开发的第一课。2. 环境准备与版本说明在开始实战之前我们需要搭建开发环境。本文将以Python为主要语言使用目前较为流行且对初学者友好的LangChain和LangGraph框架来演示。你可以根据项目实际情况调整依赖版本。基础环境要求操作系统Windows 10/11, macOS, 或 Linux (Ubuntu 20.04)Python版本3.8 或更高版本 (推荐 3.10)包管理工具pip 或 conda核心依赖库我们将创建一个requirements.txt文件来管理依赖。关键库及其作用如下# requirements.txt langchain0.1.0 # AI应用开发框架提供Agent、Chain等高级抽象 langchain-openai0.0.5 # LangChain的OpenAI集成包 langgraph0.0.22 # 用于构建有状态、多步骤工作流的图框架 openai1.6.1 # OpenAI官方SDK python-dotenv1.0.0 # 用于加载环境变量管理API KeyAPI密钥准备你需要一个OpenAI的API密钥。请前往OpenAI平台注册并获取。切记不要将密钥直接硬编码在代码中在项目根目录创建.env文件。将你的API密钥写入该文件# .env OPENAI_API_KEY你的-api-key-here在代码中通过python-dotenv加载。项目结构一个清晰的项目结构有助于管理复杂度。ai_agent_guide/ ├── .env # 环境变量文件已加入.gitignore ├── requirements.txt # 项目依赖 ├── src/ # 源代码目录 │ ├── __init__.py │ ├── simple_agent.py # 基础Agent示例 │ ├── loop_agent.py # 带循环的Agent示例 │ └── tools/ # 自定义工具目录 │ └── __init__.py └── README.md使用以下命令安装依赖并验证环境# 创建虚拟环境可选但推荐 python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate # 安装依赖 pip install -r requirements.txt # 验证OpenAI连接确保.env已配置 python -c “from langchain_openai import ChatOpenAI; import os; llm ChatOpenAI(api_keyos.getenv(‘OPENAI_API_KEY’)); print(llm.invoke(‘Hello’).content)”3. 核心原理与架构拆解3.1 Prompt Engineering 的精髓Prompt Engineering不仅仅是“问问题”。一个优秀的Prompt通常包含以下元素角色Role 定义模型在对话中扮演的角色。任务Task 清晰、具体地描述需要完成的工作。上下文Context 提供必要的背景信息。示例Examples 提供少量示例Few-shot Learning来示范期望的输出格式。格式Format 明确指定输出的格式要求如JSON、Markdown、列表。约束Constraints 设定限制条件如长度、风格、禁止内容。示例一个结构化的Promptfrom langchain.prompts import ChatPromptTemplate prompt_template ChatPromptTemplate.from_messages([ (“system”, “你是一位资深Python代码审查专家。你的风格严谨、细致善于发现潜在的性能问题和安全隐患。”), (“human”, “请审查以下Python代码片段\n{code}\n\n请按以下格式输出\n1. **潜在问题**列出发现的问题。\n2. **风险等级**高/中/低。\n3. **改进建议**提供修改后的代码片段。”), ]) # 使用LLM调用这个Prompt from langchain_openai import ChatOpenAI llm ChatOpenAI(model“gpt-4-turbo-preview”) chain prompt_template | llm result chain.invoke({“code”: “def process_data(data):\n for item in data:\n result expensive_computation(item)\n return result”}) print(result.content)3.2 AI Agent 的核心组件一个典型的AI Agent由以下几个核心部分组成大脑LLM Core 通常是大语言模型负责理解、推理和决策。工具Tools Agent可以调用的外部函数或API扩展其能力边界如搜索网络、执行代码、查询数据库。记忆Memory 用于存储和回忆与当前任务相关的历史信息对话历史、中间结果等。分为短期记忆当前会话和长期记忆向量数据库。规划器Planner 负责将复杂目标分解为可执行的子任务序列。执行器Executor 负责调用工具并处理返回结果。在LangChain中Agent对象将这些组件整合在一起。3.3 Loop Engineering 的工作流这是Agent智能的体现。一个经典的ReActReason Act循环如下思考Think Agent根据当前目标、记忆和观察决定下一步该做什么。是调用工具还是直接给出最终答案行动Act 如果决定调用工具则选择正确的工具并传入合适的参数。观察Observe 获取工具执行的结果可能是成功的数据也可能是错误信息。循环Loop 将观察结果纳入记忆重新评估目标进入下一轮“思考”。直到任务完成或达到最大步数。LangGraph是专门为建模这种有状态、多步骤循环而设计的框架。它用“图Graph”来定义Agent的工作流节点Node代表步骤思考、行动边Edge代表步骤之间的流转条件。4. 完整实战案例构建一个研究助手Agent让我们构建一个“研究助手”Agent它能根据一个复杂主题自动进行多轮网络搜索收集信息并最终整理成一份结构化的报告。4.1 定义工具让Agent能“上网”首先我们需要为Agent提供“手”和“眼”。这里我们使用SerpAPI进行网络搜索需自行注册获取API KEY。同时我们定义一个简单的文本总结工具。# src/tools/search_tools.py import os from langchain_community.tools import Tool from langchain_community.utilities import SerpAPIWrapper from langchain_openai import ChatOpenAI # 初始化搜索工具 os.environ[“SERPAPI_API_KEY”] “your-serpapi-key” # 同样建议放入.env search SerpAPIWrapper() # 定义搜索工具 search_tool Tool( name“WebSearch”, funcsearch.run, description“””当你需要查找最新的、实时的、或未知的具体信息时使用此工具。 输入应该是一个明确的搜索查询字符串。””” ) # 定义一个文本总结工具模拟 llm ChatOpenAI(model“gpt-3.5-turbo”) def summarize_text(text: str) - str: “”“对长文本进行总结。”“” prompt f“请用中文简要总结以下内容的核心观点\n\n{text}” return llm.invoke(prompt).content summarize_tool Tool( name“TextSummarizer”, funcsummarize_text, description“当遇到很长、需要提炼核心内容的文本时使用此工具。输入是文本字符串。” ) # 工具列表 tools [search_tool, summarize_tool]4.2 构建基础Agent无循环我们先创建一个使用ReAct框架的基础Agent它只能执行一步或简单几步。# src/simple_agent.py import os from dotenv import load_dotenv from langchain import hub from langchain.agents import create_react_agent, AgentExecutor from langchain_openai import ChatOpenAI from tools.search_tools import tools # 加载环境变量 load_dotenv() # 初始化LLM llm ChatOpenAI(model“gpt-4-turbo-preview”, temperature0) # 从LangChain Hub拉取一个ReAct风格的Prompt prompt hub.pull(“hwchase17/react”) # 创建Agent agent create_react_agent(llm, tools, prompt) # 创建执行器 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) # 执行一个简单任务 if __name__ “__main__”: result agent_executor.invoke({ “input”: “用中文搜索一下‘LangGraph框架’是什么并简要介绍。” }) print(“\n 最终结果 ”) print(result[“output”])运行这个脚本你会看到Agent的思考过程verboseTrue它可能会先调用WebSearch然后直接输出结果。但对于“收集多篇资料并总结”的任务它可能在一轮内无法完成。4.3 使用LangGraph构建循环Agent现在我们使用LangGraph来构建一个具备明确循环能力的Agent。这个Agent会先规划搜索关键词然后执行搜索评估信息是否足够若不足则调整关键词继续搜索最后进行总结。# src/loop_agent.py import os from typing import TypedDict, Annotated, List from dotenv import load_dotenv from langgraph.graph import StateGraph, END from langgraph.graph.message import add_messages from langgraph.prebuilt import ToolNode from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, SystemMessage from tools.search_tools import tools, search_tool, summarize_tool load_dotenv() llm ChatOpenAI(model“gpt-4-turbo-preview”, temperature0) # 1. 定义状态State class AgentState(TypedDict): messages: Annotated[List, add_messages] # 对话消息历史 research_topic: str # 研究主题 collected_info: List[str] # 收集到的信息片段 search_query: str # 当前的搜索查询 iteration: int # 循环迭代次数 # 2. 定义节点Nodes def planner_node(state: AgentState) - AgentState: “”“规划节点决定搜索查询或结束研究。”“” system_msg SystemMessage(content“””你是一个研究规划员。根据当前的研究主题和已收集的信息决定下一步是继续搜索还是开始总结。 如果已收集的信息足够丰富超过3条不同来源的核心观点或者迭代超过3次就决定‘SUMMARIZE’。 否则生成一个新的、更深入的搜索查询来获取更多信息。只输出‘SEARCH: 查询内容’或‘SUMMARIZE’。”””) info_preview “\n”.join(state[“collected_info”][-3:]) if state[“collected_info”] else “无” user_msg HumanMessage(contentf””” 研究主题{state[‘research_topic’]} 已收集信息最近3条 {info_preview} 当前迭代次数{state[‘iteration’]} 请做出决定。 “””) response llm.invoke([system_msg, user_msg]) decision response.content.strip() if decision.startswith(“SEARCH:”): state[“search_query”] decision.replace(“SEARCH:”, “”).strip() print(f“[规划] 决定搜索{state[‘search_query’]}”) else: state[“search_query”] “” # 清空查询触发结束 print(f“[规划] 决定开始总结。”) return state def search_node(state: AgentState) - AgentState: “”“搜索节点执行网络搜索。”“” if not state[“search_query”]: return state print(f”[执行] 正在搜索{state[‘search_query’]}“) result search_tool.run(state[“search_query”]) # 简单处理实际中可能需要解析搜索结果 state[“collected_info”].append(f”搜索 ‘{state[‘search_query’]}’ 的结果摘要{result[:200]}...”) state[“iteration”] 1 return state def summarizer_node(state: AgentState) - AgentState: “”“总结节点生成最终报告。”“” if not state[“collected_info”]: state[“messages”].append(HumanMessage(content“未收集到任何信息。”)) return state all_info “\n---\n”.join(state[“collected_info”]) system_msg SystemMessage(content“你是一位专业的研究报告撰写员。请根据以下收集的信息撰写一份关于给定主题的简明中文报告。报告需包含概述、核心发现和结论。”) user_msg HumanMessage(contentf”研究主题{state[‘research_topic’]}\n\n收集到的信息\n{all_info}”) response llm.invoke([system_msg, user_msg]) final_report response.content state[“messages”].append(HumanMessage(contentf“研究报告\n{final_report}”)) print(“\n” “”*50) print(“【最终研究报告】”) print(final_report) print(“”*50) return state # 3. 定义边Edges的条件 def should_continue(state: AgentState) - str: “”“判断下一步是继续搜索还是结束。”“” # 如果规划节点没有设置新的搜索查询或者迭代超过3次则结束 if not state.get(“search_query”) or state[“iteration”] 3: return “summarize” return “search” # 4. 构建图Graph workflow StateGraph(AgentState) # 添加节点 workflow.add_node(“planner”, planner_node) workflow.add_node(“search”, search_node) workflow.add_node(“summarize”, summarizer_node) # 设置入口点 workflow.set_entry_point(“planner”) # 添加边 workflow.add_conditional_edges( “planner”, should_continue, { “search”: “search”, “summarize”: “summarize” } ) workflow.add_edge(“search”, “planner”) # 搜索完回到规划节点重新评估 workflow.add_edge(“summarize”, END) # 总结后结束 # 编译图 app workflow.compile() # 5. 运行Agent if __name__ “__main__”: # 初始化状态 initial_state: AgentState { “messages”: [], “research_topic”: “大语言模型LLM在软件开发中的最新应用趋势”, “collected_info”: [], “search_query”: “”, “iteration”: 0 } print(f“开始研究主题{initial_state[‘research_topic’]}”) print(“-” * 30) # 运行图 final_state app.invoke(initial_state) print(“\n研究流程完成。”)4.4 运行与结果分析运行python src/loop_agent.py。你会看到类似以下的输出清晰地展示了Agent的循环决策过程开始研究主题大语言模型LLM在软件开发中的最新应用趋势 ------------------------------ [规划] 决定搜索大语言模型 软件开发 应用趋势 2024 [执行] 正在搜索大语言模型 软件开发 应用趋势 2024 [规划] 决定搜索LLM 代码生成 自动化测试 应用案例 [执行] 正在搜索LLM 代码生成 自动化测试 应用案例 [规划] 决定开始总结。 【最终研究报告】 这里会输出一份由模型生成的、基于前两轮搜索信息的结构化报告... 研究流程完成。这个Agent展示了Loop Engineering的核心它能够根据中间结果收集的信息动态地规划下一步行动调整搜索词并在满足条件信息足够或迭代限制时自动转入总结阶段。5. 常见问题与排查思路在开发AI Agent过程中你可能会遇到以下典型问题问题现象可能原因排查思路与解决方案Agent陷入死循环终止条件定义不清晰LLM的决策逻辑有误。1. 在should_continue函数中添加更严格的终止条件如最大步数、时间限制。2. 优化规划节点planner_node的Prompt明确何时停止。3. 在状态中增加max_iterations字段并在循环中检查。工具调用失败或参数错误工具描述不清晰LLM未能正确理解工具用途和输入格式。1. 检查工具的description是否准确、具体最好包含输入示例。2. 使用ToolNode或create_react_agent等高级抽象它们能更好地处理工具调用格式。3. 在Agent执行器中设置handle_parsing_errorsTrue来捕获并重试解析错误。LLM输出不符合预期格式Prompt中格式指令不明确Temperature参数过高导致输出随机。1. 在System Prompt中严格要求输出格式例如“你必须只输出JSON...”。2. 使用LangChain的OutputParser如PydanticOutputParser来强制结构化输出。3. 将LLM的temperature参数调低如0.1以获得更确定性的结果。信息在循环中丢失状态State设计不合理关键中间结果未被传递。1. 仔细设计State的TypedDict确保所有需要跨节点传递的数据都有字段对应。2. 在每个节点中确保修改的是state的副本或正确更新state字典。3. 使用Annotated类型如add_messages来自动处理消息列表的追加。API调用超时或限速网络问题OpenAI或其他API的速率限制RPM/TPM。1. 为API调用添加重试机制和指数退避。2. 监控Token使用量对于长文本考虑使用更经济的模型如gpt-3.5-turbo。3. 考虑使用异步Async调用以提高效率。6. 最佳实践与工程建议要将AI Agent从实验原型推进到生产可用需要关注以下几点状态管理与记忆优化短期记忆对于简单会话LangChain的ConversationBufferMemory足够。对于复杂循环像上面例子中自定义的AgentState提供了更精细的控制。长期记忆对于需要从海量知识中回忆的场景必须引入向量数据库如Chroma, Pinecone, Weaviate。将历史对话、工具结果等编码为向量存储在需要时进行相似性检索。工具设计的鲁棒性清晰的描述与Schema为每个工具提供详尽、准确的name和description并利用Pydantic定义严格的输入参数Schema这能极大提升LLM调用工具的准确率。错误处理工具函数内部必须有完善的try-except返回结构化的结果如{‘success’: False, ‘error’: ‘...’}方便Agent处理失败情况。权限与安全工具能执行写操作如发邮件、改数据库或访问敏感信息。必须实施严格的权限控制和用户确认机制绝不能让Agent在未经明确授权的情况下执行危险操作。循环控制与超时强制终止在任何循环工作流中都必须设置最大迭代次数或最长运行时间这是防止无限循环和成本失控的生命线。检查点Checkpointing对于长时间运行的任务实现状态的持久化保存和恢复能力避免因意外中断导致任务完全失败。可观测性与调试结构化日志记录每个循环步骤的输入、输出、LLM的推理过程Chain of Thought、工具调用详情和耗时。这不仅是调试的利器也是优化Prompt和流程的依据。可视化利用LangGraph的get_graph().draw_mermaid()功能生成工作流图直观理解Agent的决策路径。Prompt的工程化管理模板化与版本控制不要将Prompt硬编码在代码中。使用LangChain Hub或外部文件如YAML来管理Prompt模板便于A/B测试和版本迭代。少样本Few-shot示例在Prompt中包含2-3个高质量的输入输出示例能显著提升LLM在复杂任务上的表现。7. 总结与学习路线通过本文你应该已经掌握了从静态Prompt Engineering到动态Loop Engineering构建AI Agent的核心路径。我们不仅介绍了概念更通过一个完整的研究助手Agent案例演示了如何用LangChain和LangGraph实现感知、规划、执行、观察的闭环。你的学习路线可以这样规划第一阶段掌握基础深入理解Prompt Engineering的各个要素能写出高质量的指令。熟练使用LangChain的LCELLangChain Expression Language构建简单的Chain。学会为Agent创建和调用简单的工具。第二阶段构建智能体使用create_react_agent等高级API构建基础Agent。理解AgentExecutor的工作原理和参数。为Agent集成不同类型的记忆缓冲记忆、摘要记忆。第三阶段实现循环与复杂工作流学习LangGraph的核心概念State、Node、Edge、Graph。动手实现一个包含条件分支和循环的定制化Agent。将向量数据库作为长期记忆集成到Agent中。第四阶段生产化与进阶关注Agent的稳定性错误处理、重试、超时。实现可观测性日志、监控、跟踪。探索多Agent协作Swarm和更高级的规划策略如ToT, CoT。AI Agent的开发是一场结合了软件工程、提示词艺术和产品思维的实践。最好的学习方式就是动手去构建。从一个能自动查天气的小助手开始逐步增加复杂度最终你将能创造出真正解决实际问题的智能体。如果在实践中遇到问题回到本文的“常见问题”和“最佳实践”部分或许能找到答案。