基于LangGraph与Ollama构建自我改进型AI智能体:从原理到实战

发布时间:2026/10/25 22:53:24

基于LangGraph与Ollama构建自我改进型AI智能体:从原理到实战 你好我是专注于AI与软件开发实战的技术博主。最近斯坦福大学的CS329A课程《自我改进型AI智能体》引起了广泛关注它系统性地揭示了AI智能体如何通过自我迭代变得越来越“聪明”。这不仅是前沿学术课题更是当下企业招聘如“智能体工程师”岗位和开发者构建自动化系统的核心技能。本文将为你深入拆解这门课程的精髓并结合LangGraph、Ollama等热门工具手把手带你从零构建一个具备自我改进能力的本地AI智能体覆盖从核心概念到项目落地的全流程。1. 背景与核心概念什么是自我改进型AI智能体在传统编程中系统的行为由开发者预先定义的规则完全决定。而AI智能体AI Agent则是一个能够感知环境、自主决策并执行行动以实现目标的软件实体。它通常由大型语言模型LLM驱动具备理解、规划和工具使用的能力。那么“自我改进型”智能体又意味着什么简单来说它是一个能够根据历史经验包括成功和失败自动优化自身策略、提示词Prompt甚至代码的智能体。其核心思想是模仿人类“吃一堑长一智”的学习过程让AI在循环中不断变得更强。为什么它如此重要降低维护成本无需开发者手动为每一个边缘案例编写规则智能体可以自行发现并修复问题。适应动态环境在需求频繁变化或环境复杂的场景如自动化测试、网络运维、交易策略中自我改进能力至关重要。迈向更高级的AI这是实现“持续学习”和“通用人工智能”AGI道路上的关键一步。核心组件与流程 一个典型的自我改进循环通常包含以下几个阶段任务执行智能体根据当前策略如一组指令或一段代码去执行任务。结果评估通过预定义的评估器Evaluator或环境反馈如测试用例是否通过、用户评分来判断任务完成的质量。反思与诊断智能体分析失败或未达最优的原因。例如“我之所以失败是因为在代码中没有处理输入为空的边界情况。”策略更新基于反思智能体生成一个改进后的新策略如修复bug后的代码、优化后的提示词。验证与迭代将新策略应用于同一任务或类似任务开启新一轮循环。2. 环境准备与版本说明我们将使用Python作为主要开发语言并借助LangChain生态的LangGraph来构建智能体的工作流使用Ollama在本地运行开源大模型。这套方案完全本地化无需API密钥适合学习和原型开发。基础环境要求操作系统macOS / Linux / Windows (WSL2推荐)Python版本 3.10包管理工具pip 或 conda核心工具与版本 本文示例将基于以下工具版本请注意依赖的快速迭代特性实际安装时建议关注官方文档。LangChain LangGraph用于编排智能体工作流。langchain-core,langchain-community,langgraph。Ollama用于在本地拉取和运行大模型。我们将使用llama3.2:1b或qwen2.5:0.5b这类较小的模型进行演示以保证运行速度。其他辅助库pydantic数据验证、typing类型提示。安装命令# 1. 首先安装并启动Ollama请根据Ollama官网指引安装 # 安装后拉取一个轻量级模型 ollama pull llama3.2:1b # 2. 创建Python虚拟环境并激活可选但推荐 python -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows # 3. 安装Python依赖 pip install langchain langchain-community langgraph pydantic示例项目结构self_improving_agent/ ├── main.py # 主程序入口 ├── agent_graph.py # LangGraph智能体图定义 ├── evaluators.py # 评估器模块 ├── prompts.py # 提示词模板管理 └── tasks/ # 任务定义与存储 └── sample_task.py3. 核心原理与架构拆解在动手之前理解LangGraph如何实现自我改进循环至关重要。LangGraph通过“图”Graph的概念来定义智能体的状态流转。3.1 状态State设计状态是一个Pydantic模型它贯穿整个工作流保存所有必要信息。# 在 agent_graph.py 中 from typing import TypedDict, List, Annotated from langgraph.graph.message import add_messages import operator class AgentState(TypedDict): # 消息历史用于记录智能体与模型的对话 messages: Annotated[List, add_messages] # 当前迭代轮次 iteration: int # 当前的任务描述 task_description: str # 智能体生成的解决方案如代码 current_solution: str # 评估结果如PASS/FAIL 或分数 evaluation_result: str # 反思内容分析上轮失败原因 reflection: str # 是否已完成任务的标志 task_complete: bool3.2 节点Nodes与边Edges一个节点代表一个功能单元如“生成代码”、“评估代码”边代表节点间的流转路径由条件逻辑conditional_edges控制。自我改进循环的关键路径生成节点根据任务描述和反思让LLM生成解决方案。评估节点调用评估器检验解决方案的有效性。判断条件如果评估通过task_completeTrue则结束否则进入“反思节点”。反思节点让LLM分析评估失败的原因生成“反思”文本。循环将“反思”带回“生成节点”开始下一轮迭代。这个过程完美对应了“执行 - 评估 - 反思 - 更新”的自我改进核心逻辑。4. 完整实战构建一个自我改进的代码生成智能体让我们构建一个能为自己编写Python函数的智能体。任务目标是“编写一个函数计算斐波那契数列的第n项并处理无效输入。”4.1 定义评估器评估器是自我改进的“裁判”。我们设计一个简单的单元测试评估器。# evaluators.py import subprocess import sys import os from typing import Tuple def evaluate_python_code(solution: str, task_desc: str) - Tuple[str, bool]: 评估生成的Python代码。 返回: (评估结果描述, 是否通过) # 提取函数代码。这里简单假设solution包含函数定义。 # 在实际中你可能需要用更复杂的方法从LLM输出中提取代码块。 code_to_test solution “\n\n” “”” # 测试用例 if __name__ “__main__”: errors [] # 测试正常输入 try: assert fib(0) 0 except Exception as e: errors.append(f“fib(0) failed: {e}”) try: assert fib(1) 1 except Exception as e: errors.append(f“fib(1) failed: {e}”) try: assert fib(10) 55 except Exception as e: errors.append(f“fib(10) failed: {e}”) # 测试无效输入应抛出异常或返回特定值 try: fib(-5) errors.append(“fib(-5) should raise an error but did not.”) except ValueError: pass # 期望的行为 except Exception as e: errors.append(f“fib(-5) raised unexpected error: {e}”) if errors: print(“FAILED: ” “; “.join(errors)) sys.exit(1) else: print(“ALL TESTS PASSED”) sys.exit(0) “”” # 写入临时文件并运行 with open(“temp_test.py”, “w”) as f: f.write(code_to_test) try: result subprocess.run([sys.executable, “temp_test.py”], capture_outputTrue, textTrue, timeout10) os.remove(“temp_test.py”) if result.returncode 0: return (“所有测试用例通过。”, True) else: return (f“测试失败。错误输出{result.stderr}”, False) except subprocess.TimeoutExpired: os.remove(“temp_test.py”) return (“代码执行超时可能存在死循环。”, False) except Exception as e: return (f“评估过程发生异常{e}”, False)4.2 构建LangGraph工作流这是最核心的部分我们将定义各个节点并将其连接成图。# agent_graph.py from langchain_community.chat_models import ChatOllama from langchain_core.prompts import ChatPromptTemplate from langgraph.graph import StateGraph, END from .evaluators import evaluate_python_code from .prompts import GENERATION_PROMPT, REFLECTION_PROMPT # 提示词模板后文给出 from .state import AgentState # 即前面定义的TypedDict # 1. 初始化LLM llm ChatOllama(model“llama3.2:1b”, temperature0.2) # 2. 定义节点函数 def generation_node(state: AgentState): “”“根据任务和反思生成解决方案。”“” messages [] if state[“reflection”]: # 如果不是第一轮将反思作为上下文 messages.append((“user”, f“之前的尝试失败了原因分析是{state[‘reflection’]}\n请基于这个反思重新解决以下任务{state[‘task_description’]}”)) else: messages.append((“user”, f“请解决以下任务{state[‘task_description’]}”)) prompt ChatPromptTemplate.from_messages(messages) chain prompt | llm response chain.invoke({}) # 更新状态 new_state { “current_solution”: response.content, “iteration”: state[“iteration”] 1, “reflection”: state[“reflection”], # 保留将在评估后可能被覆盖 “messages”: state[“messages”] [response] } return new_state def evaluation_node(state: AgentState): “”“评估当前解决方案。”“” eval_result, is_success evaluate_python_code(state[“current_solution”], state[“task_description”]) new_state { “evaluation_result”: eval_result, “task_complete”: is_success } return new_state def reflection_node(state: AgentState): “”“基于失败结果进行反思。”“” prompt ChatPromptTemplate.from_template(REFLECTION_PROMPT) chain prompt | llm response chain.invoke({ “task”: state[“task_description”], “solution”: state[“current_solution”], “error”: state[“evaluation_result”] }) return {“reflection”: response.content} # 3. 构建图 workflow StateGraph(AgentState) # 添加节点 workflow.add_node(“generate”, generation_node) workflow.add_node(“evaluate”, evaluation_node) workflow.add_node(“reflect”, reflection_node) # 设置入口点 workflow.set_entry_point(“generate”) # 添加边条件逻辑 workflow.add_edge(“generate”, “evaluate”) workflow.add_conditional_edges( “evaluate”, # 判断函数根据评估结果决定下一步 lambda state: “end” if state[“task_complete”] else “reflect”, { “end”: END, # 成功则结束 “reflect”: “reflect” # 失败则进入反思 } ) workflow.add_edge(“reflect”, “generate”) # 反思后重新生成 # 编译图 self_improving_agent workflow.compile()4.3 定义提示词模板提示词的质量直接影响LLM的输出。# prompts.py GENERATION_PROMPT “”” 你是一个资深的Python程序员。你的任务是根据用户要求编写代码。 要求 1. 代码必须健壮包含必要的输入验证和异常处理。 2. 代码必须高效、可读。 3. 只返回最终的代码块无需解释。 任务{task_description} “”” REFLECTION_PROMPT “”” 你刚刚尝试解决以下任务 任务{task} 你提交的解决方案是 python {solution}但是它未能通过评估。评估反馈的错误是 {error}请深入分析你的代码失败的根本原因。是逻辑错误、边界条件未处理、异常类型不对还是其他问题 请给出清晰、具体的反思用于指导下一轮代码生成。 反思 “””**4.4 运行与验证** 现在我们可以运行这个自我改进的智能体了。 python # main.py from agent_graph import self_improving_agent # 初始化状态 initial_state { “messages”: [], “iteration”: 0, “task_description”: “编写一个函数fib(n)计算斐波那契数列的第n项从0开始fib(0)0, fib(1)1。函数必须对非负整数输入返回正确结果对负整数输入抛出ValueError异常。”, “current_solution”: “”, “evaluation_result”: “”, “reflection”: “”, “task_complete”: False } # 运行智能体并设置最大迭代次数防止无限循环 max_iterations 5 for i in range(max_iterations): print(f“\n 迭代第 {initial_state[‘iteration’]} 轮 ”) result self_improving_agent.invoke(initial_state) print(f“生成的解决方案\n{result[‘current_solution’][:500]}...”) # 打印前500字符 print(f“评估结果{result[‘evaluation_result’]}”) if result[“task_complete”]: print(“ 任务成功完成”) break print(f“反思{result[‘reflection’]}”) # 更新状态进入下一轮 initial_state result else: print(“⚠️ 达到最大迭代次数任务未完成。”) # 打印最终的成功代码 if result[“task_complete”]: print(“\n 最终生成的正确代码 ) print(result[“current_solution”])4.5 预期结果与过程分析当你运行上述程序可能会观察到类似以下的输出 迭代第 0 轮 生成的解决方案 def fib(n): if n 0: raise ValueError(“Input must be a non-negative integer”) if n 0: return 0 elif n 1: return 1 else: return fib(n-1) fib(n-2) 评估结果测试失败。错误输出...递归导致超时或栈溢出 反思我使用了递归但没有考虑性能对于较大的n会导致栈溢出或超时。应该使用迭代法或缓存来优化。 迭代第 1 轮 生成的解决方案 def fib(n): if n 0: raise ValueError(“Input must be a non-negative integer”) a, b 0, 1 for _ in range(n): a, b b, a b return a 评估结果ALL TESTS PASSED 任务成功完成这个过程清晰地展示了智能体的自我改进第一轮生成了逻辑正确但效率低下的递归版本评估失败后它反思出“性能问题”第二轮便生成了高效的迭代版本并通过测试。5. 常见问题与排查思路在构建和运行自我改进型智能体时你可能会遇到以下典型问题问题现象常见原因解决思路智能体陷入无限循环1. 评估条件永远无法满足。2. 反思节点未能提供有效改进方向。3. 最大迭代次数设置过高或未设置。1. 检查评估器逻辑确保有明确、可达成的成功标准。2. 优化反思提示词要求LLM提供具体、可操作的修改建议。3.务必在调用时设置最大迭代次数如max_iterations10。LLM生成质量不稳定1. 模型能力不足如参数过小。2. 提示词Prompt不够清晰、具体。3. Temperature参数过高导致输出随机性大。1. 尝试更大、更专精的模型如llama3.1:8b,qwen2.5:7b。2. 使用思维链Chain-of-Thought或更结构化的输出要求如“请先分析再写代码”。3. 降低Temperature如0.1-0.3以获得更确定性的输出。评估结果不准确1. 评估器本身有bug。2. 评估标准与任务目标不对齐。3. 从LLM输出中提取代码的方式不可靠。1. 为评估器编写单元测试。2. 重新审视任务描述确保评估器检验的是核心目标。3. 使用更稳健的代码提取方法如正则表达式匹配python ... 块。运行速度慢1. 本地模型推理速度慢。2. 每轮迭代都进行耗时评估如运行复杂测试。3. 图结构复杂节点过多。1. 使用量化版本模型或更小尺寸的模型进行开发调试。2. 简化评估器或先进行快速静态检查如语法检查再进行完整评估。3. 优化工作流合并不必要的节点。状态管理混乱1. State设计不合理信息冗余或缺失。2. 节点之间状态更新覆盖了不该覆盖的数据。1. 遵循最小化原则设计State只保留必要字段。2. 在每个节点的返回值中明确列出要更新的字段其他字段会自动保留。6. 最佳实践与工程建议将自我改进型智能体从Demo推向生产级应用需要考虑更多工程化因素。1. 设计稳健的评估体系评估器是改进循环的“指挥棒”。一个坏的评估器会导致智能体学到错误的东西。多维度评估不要只用一个“通过/失败”信号。可以结合代码风格检查如pylint、性能基准测试、安全性扫描如bandit等多维度评分。人类反馈介入对于关键任务可以引入“人在回路”Human-in-the-loop机制在关键迭代轮次由人工审核评估结果或提供反馈。奖励模型对于复杂任务可以训练一个奖励模型Reward Model来替代规则化的评估器为智能体的输出提供连续分数。2. 提示词工程与模板管理模块化提示词像管理代码一样管理提示词。将系统指令、任务描述、反思模板等分开放置在配置文件中便于迭代和A/B测试。提供高质量示例在提示词中加入少量1-3个高质量的示例Few-shot Learning能显著提升LLM输出的规范性和质量。结构化输出要求LLM以JSON、XML或特定标记格式输出便于后续程序化解析。例如要求输出{“analysis”: “…”, “code”: “…”}。3. 安全与合规性这是企业级应用的生命线。沙箱环境绝对不要让智能体生成的代码直接在宿主机器或生产环境中执行。必须在一个隔离的沙箱如Docker容器、安全沙盒中运行评估。输入/输出过滤对智能体接收的任务描述和其生成的解决方案进行严格的过滤和审查防止注入攻击、恶意代码或数据泄露。审计日志完整记录每一轮迭代的输入State、输出LLM响应、评估结果和反思。这对于调试、复现问题和合规审计至关重要。4. 性能与可观测性设置超时与熔断为每个LLM调用和评估步骤设置超时并为整个工作流设置熔断机制防止资源耗尽。监控与指标监控关键指标如平均迭代次数、任务成功率、单轮耗时、Token消耗等。使用LangSmith等工具进行可视化追踪。版本控制对智能体的工作流定义、提示词模板、评估器代码进行严格的版本控制。5. 定义清晰的改进边界自我改进不是无限制的。必须明确智能体可以修改什么不能修改什么。核心逻辑不可变例如智能体可以优化算法实现但不能改变函数的输入输出接口规范。依赖约束明确声明允许使用的库和版本禁止引入未授权的依赖。回滚机制如果改进后的版本在更广泛的测试集上表现更差应有机制自动回滚到上一个稳定版本。构建自我改进型AI智能体是一个激动人心的领域它结合了提示词工程、程序合成、强化学习等多个前沿方向。斯坦福CS329A课程为我们提供了坚实的理论基础而LangGraph、Ollama等工具让实践变得触手可及。从本文的简单代码生成案例出发你可以尝试将其应用到更复杂的场景如自动化测试用例生成、SQL查询优化、运维脚本修复等。记住成功的关键在于设计一个清晰、可衡量的任务目标一个可靠的评估体系以及一个引导LLM有效反思的提示机制。
延伸阅读

更多相关文章

2026/10/26 16:59:45

POJ 3530(A Modular Arithmetic Challenge-类欧几里得)

Given four positive integers M, D, L, R, your task is to find the minimal non-negative integer x which satisfies L ≤ ( D x mod M ) ≤ R, where mod is the remainder operation 类欧几里得&#xff0c;复杂度log #include<cstdio> #include<cstring> #…

2026/10/26 16:59:45

PyTorch实现gPINN求解Allen-Cahn方程的梯度增强技术

1. 项目背景与核心挑战Allen-Cahn方程作为描述相变过程的经典非线性偏微分方程&#xff0c;在材料科学、生物膜动力学等领域有广泛应用。传统数值方法在处理具有多非常陡峭区域的Allen-Cahn方程时&#xff0c;往往面临网格划分困难、计算量爆炸等问题。我们团队在PyTorch框架下…

2026/10/26 16:59:45

C语言中前置++与后置++的底层原理与最佳实践

1. 前置与后置的本质区别 在C语言中&#xff0c;运算符的前置&#xff08;i&#xff09;和后置&#xff08;i&#xff09;形式虽然都能实现变量自增1的效果&#xff0c;但它们的底层机制和编译行为存在本质差异。理解这个差异是正确使用它们的关键。 1.1 运算符的返回值差异 …

2026/10/26 16:59:45

Python爬虫实战:安居客租房数据抓取、清洗与分析全链路

简介&#xff1a;这份资源围绕安居客武汉地区出租房信息展开&#xff0c;完整覆盖从数据爬取、清洗到分析可视化的全流程&#xff0c;适合正在学习Python爬虫、需要完成课程设计或毕业设计的学生&#xff0c;以及想了解真实数据采集项目如何落地的人群。压缩包共14个文件&#…

2026/10/26 16:59:45

马尾扎法进阶指南:从高颅顶到发际线守护的实用技巧

1. 马尾贴头皮的真相&#xff1a;为什么别人扎的是氛围感&#xff0c;你扎的是紧箍咒1.1 时间差、手感差和“反光发缝”先说不客气的大实话&#xff1a;马尾人人会扎&#xff0c;但扎得好看是另一门手艺。我翻自己过去一年的照片&#xff0c;发现十个造型里至少有六个是马尾出镜…

2026/10/26 16:54:45

cc-safety-net:前端运行时风险的CLI守门员

1. 这不是又一个 CLI 工具介绍——cc-safety-net 是什么&#xff0c;为什么它值得你花 5 分钟认真读完“cc-safety-net”这个名字乍看像某个内部代号&#xff0c;甚至容易被误读成“CC 安全网”或“Code Coverage Safety Net”。但实际它是一个轻量、专注、不依赖全局环境的前端…

2026/10/26 0:20:20

全国计算机二级C语言真题PDF高效刷题指南

简介&#xff1a;这份PDF是全国计算机二级C语言考试的试题与答案解析&#xff0c;专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/26 1:53:47

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介&#xff1a;一份以实战为导向的Python爬虫入门资源&#xff0c;面向具备基本编程基础、希望快速掌握网络数据抓取的初学者&#xff0c;可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档&#xff0c;完整演示从网页中提取 标题…

2026/10/26 0:20:17

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介&#xff1a;这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档&#xff0c;压缩包大小七十八KB&#xff0c;内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开&#xff1a;先构造一个极点位于单位圆内…

2026/10/26 0:00:48

Nested Learning:解决AI灾难性遗忘的分层记忆架构

1. 为什么AI需要"记忆"能力&#xff1f;在传统深度学习模型中&#xff0c;我们常遇到一个根本性问题&#xff1a;模型在处理新任务时&#xff0c;往往会完全遗忘之前学到的知识。这种现象被业界称为"灾难性遗忘"(Catastrophic Forgetting)。想象一下&#…

2026/10/26 0:00:48

企业级大模型应用:OCR预处理、Dify编排与DeepSeek落地实战

1. 这不是“用大模型”&#xff0c;而是重构工作流的起点“大模型的应用和工具”——这八个字现在被贴在无数技术分享、招聘JD、内部立项书的标题栏里&#xff0c;但绝大多数人点进去后看到的&#xff0c;是零散的API调用示例、几个开源UI截图、或者一句“接入LLM就能降本增效”…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑