当前位置: 首页 > news >正文

Agent-study项目教程(06):AI智能写作与反思助手(LangGraph)

一、理论部分

1. 为什么写作任务更适合用“图(Graph)”而不是“线性链(Chain)”

传统的链式调用通常是单向的:Prompt → LLM → Output。它适合一次性生成类任务,但不擅长表达真实写作过程中的“循环改稿”:

  • 先构思大纲(Planner)
  • 再写初稿(Writer)
  • 再审阅并提出修改意见(Critique)
  • 如果不满意:回到写作节点继续修改,直到满意或达到修改上限

这种“写不好就重写”的结构本质上是一个循环(Loop)。LangGraph 的核心优势就是用图结构来描述可循环、可分支、可控终止的流程。

2. State(状态)是图编排的核心:把“过程记忆”显式化

在多轮节点执行中,系统必须持续携带关键上下文。LangGraph 通过 State 把这些数据显式建模并在节点间传递。

本项目使用的状态字段包括:

  • topic:写作主题
  • plan:写作大纲
  • draft:当前草稿
  • critique:审阅意见
  • revision_number:当前修改轮次
  • max_revisions:最大修改轮次(用于防止死循环)

与“聊天记忆”不同,这里 State 更像是一个明确的“工作流上下文对象”,每个节点只读写自己负责的字段,流程更可控。

3. 三类节点(Nodes):Planner / Writer / Critique 的职责分离

为了让系统可维护,我们将写作过程拆成三个职责清晰的节点:

  • Planner:根据主题生成写作大纲(结构与要点)
  • Writer:根据大纲生成初稿;或根据批评意见修改草稿
  • Critique:以“主编/审稿人”角色审阅草稿,指出问题与修改建议

这种职责分离的设计能有效减少 Prompt 混乱,便于后续加入更多节点(例如 Research 搜索、引用校验、风格统一等)。

4. 条件边(Conditional Edge):如何决定继续修改还是结束

图的关键不只是节点,还包括“边”的控制逻辑。本项目用一个should_continue函数作为条件路由:

  • revision_number >= max_revisions:强制结束(避免无限循环)
    几乎所有“可自我迭代”的 Agent 都必须有这种上限保护。

  • 若 Critique 返回PERFECT:提前结束(认为已经满意)

否则回到 Writer,进入下一轮“根据意见重写”。


二、实战部分

1. 项目目标

实现一个基于 LangGraph 的智能写作系统,具备:

  • 自动生成大纲(Planner)
  • 自动撰写初稿(Writer)
  • 自动审阅并提出修改意见(Critique)
  • 自动循环改稿(最多修改 N 次,或主编通过即停止)

2. 运行准备

请确保本地已安装依赖并配置环境变量(不要把真实密钥写进代码或公开仓库):

依赖安装(示例):

pipinstall-rrequirements.txt

环境变量(示例):

  • DEEPSEEK_API_KEY
  • DEEPSEEK_BASE_URL

说明:

  • 本项目使用langgraph构建图,使用langchain_openai.ChatOpenAI连接 DeepSeek(OpenAI 兼容接口)。
  • 若希望更稳定输出,可以适当降低temperature,或对 Planner/Writer/Critique 使用不同温度。

3. 项目代码(核心实现)

本项目代码集中在一个脚本中,包含:State 定义、三个节点函数、条件边逻辑、图构建与运行入口。下面给出完整核心代码(可直接运行):

importosfromtypingimportTypedDictfromdotenvimportload_dotenvfromlangchain_openaiimportChatOpenAIfromlangchain_core.messagesimportSystemMessage,HumanMessagefromlanggraph.graphimportStateGraph,END load_dotenv()classAgentState(TypedDict):topic:strplan:strdraft:strcritique:strrevision_number:intmax_revisions:intllm=ChatOpenAI(model="deepseek-chat",openai_api_key=os.getenv("DEEPSEEK_API_KEY"),openai_api_base="https://api.deepseek.com",temperature=0.7,)defplan_node(state:AgentState):print(f"--- [Planner] 正在为主题 '{state['topic']}' 生成大纲 ---")messages=[SystemMessage(content="你是一名专业的内容策略师。你的目标是为博客文章创建一个详细的大纲。"),HumanMessage(content=f"请为这个主题创建一个大纲:{state['topic']}"),]response=llm.invoke(messages)return{"plan":response.content}defwrite_node(state:AgentState):print(f"--- [Writer] 正在撰写草稿 (第{state['revision_number']+1}版) ---")ifstate["revision_number"]==0:content=f"根据这个大纲写一篇博客文章:\n\n{state['plan']}"else:content=(f"这是你之前的草稿:\n{state['draft']}\n\n"f"这是主编的修改意见:\n{state['critique']}\n\n""请根据意见修改并重写这篇文章。")messages=[SystemMessage(content="你是一名专业的技术作家。文风通俗易懂,逻辑严密。"),HumanMessage(content=content),]response=llm.invoke(messages)return{"draft":response.content,"revision_number":state["revision_number"]+1}defcritique_node(state:AgentState):print("--- [Critique] 正在审阅草稿 ---")messages=[SystemMessage(content="你是一名严格的主编。请指出文章中的逻辑漏洞、啰嗦的部分或缺失的信息。如果文章已经非常完美,只需回复 'PERFECT'。"),HumanMessage(content=f"请审阅这篇草稿:\n{state['draft']}"),]response=llm.invoke(messages)return{"critique":response.content}defshould_continue(state:AgentState):critique=state.get("critique","")ifstate["revision_number"]>=state["max_revisions"]:print("--- [System] 已达到最大修改次数,停止 ---")returnENDif"PERFECT"incritique.upper():print("--- [System] 主编已通过,停止 ---")returnENDprint("--- [System] 需要进一步修改 ---")return"writer"workflow=StateGraph(AgentState)workflow.add_node("planner",plan_node)workflow.add_node("writer",write_node)workflow.add_node("critique",critique_node)workflow.set_entry_point("planner")workflow.add_edge("planner","writer")workflow.add_edge("writer","critique")workflow.add_conditional_edges("critique",should_continue,{"writer":"writer",END:END,},)app=workflow.compile()if__name__=="__main__":print("="*50)print("🤖 AI 智能写作助手 (基于 LangGraph)")print("="*50)user_topic=input("请输入你要写作的主题 (直接回车使用默认主题): ").strip()ifnotuser_topic:user_topic="Agentic AI (智能体人工智能) 在 2025 年的发展趋势"print(f"⚠️ 未检测到输入,将使用默认主题:{user_topic}")initial_state={"topic":user_topic,"max_revisions":2,"revision_number":0,"plan":"","draft":"","critique":"",}print(f"\n🚀 开始策划与写作:{user_topic}...")final_state=app.invoke(initial_state)print("\n"+"="*50)print("✅ 最终完成的稿件:")print("="*50)print(final_state["draft"])print("="*50)

4. 如何运行

在项目根目录执行:

python stage_04_enterprise_frameworks/project_06_research_agent/main.py

启动后输入主题即可。如果直接回车,将使用默认主题并开始自动写作与迭代改稿。

5. 运行结果示例

运行过程的典型日志形态如下(内容会随模型生成有所变化):

================================================== 🤖 AI 智能写作助手 (基于 LangGraph) ================================================== 请输入你要写作的主题 (直接回车使用默认主题): ⚠️ 未检测到输入,将使用默认主题: Agentic AI (智能体人工智能) 在 2025 年的发展趋势 🚀 开始策划与写作: Agentic AI (智能体人工智能) 在 2025 年的发展趋势... --- [Planner] 正在为主题 'Agentic AI (智能体人工智能) 在 2025 年的发展趋势' 生成大纲 --- --- [Writer] 正在撰写草稿 (第 1 版) --- --- [Critique] 正在审阅草稿 --- --- [System] 需要进一步修改 --- --- [Writer] 正在撰写草稿 (第 2 版) --- --- [Critique] 正在审阅草稿 --- --- [System] 已达到最大修改次数,停止 --- ================================================== ✅ 最终完成的稿件: ================================================== (最终文章正文内容...) ==================================================

6. 项目总结

  • LangGraph 用图结构表达“循环改稿”的真实写作流程,比线性链更适配复杂可迭代任务。
  • State 将过程上下文显式化,使各节点职责清晰、数据流可控,便于扩展更多能力节点。
  • 通过条件边实现“满意即止 / 达上限即止”,是防止无限迭代的工程必需项。
  • 该模式可自然扩展:增加 Research 节点做资料检索、增加 Human-in-the-loop 节点做人工审核、增加引用校验节点提升事实性。
http://www.jsqmd.com/news/1391554/

相关文章:

  • 一行链接把B站视频变成可用播放地址:bilibili-parse 解析工具实战手记
  • 苹果说你 Mac“过时“了?OpenCore Legacy Patcher 让 2008 年旧机免费跑最新 macOS
  • mootdx 使用手记:把通达信数据变成几行 Python 代码
  • 159、Zephyr RTOS安全基础:密钥管理与存储
  • 2026户外移动烧烤房厂家哪家好?深度解析陕西振泰实业实力所在 - 深度智识库
  • dnSpy 从零快速上手:.NET 调试器与程序集编辑器的完整避坑指南
  • Python金融分析必备工具:Pyti库安装与环境配置指南
  • 啵哩打印机连接电脑全攻略:从蓝牙配遇到打印优化
  • SMUDebugTool完整使用指南:免费开源的AMD Ryzen调试工具,五个实战案例让你彻底掌控CPU性能
  • 让AI当你的办公室助理:WPS自动做PPT、Zotero管文献,上手只需三步
  • Python进阶 - re模块的finditer方法 返回迭代器对象节省内存
  • 基于FFmpeg与Python实现视频批量自动截图:从原理到工程实践
  • esprint高级技巧:自定义工作线程数与性能优化实战指南
  • CTF新手实战入门:从零搭建环境到掌握五大题型解题框架
  • IPXWrapper 协议转换终极指南:一招让星际争霸、红警2在Win10/11重获局域网联机
  • 从卡在 99% 到满速下载:我用 trackerslist 公共 Tracker 清单解决 BT 下载找不到源
  • 微服务架构设计模式-第二章
  • 蓝天空协议服务正式推出:Jetstream v2、SDK 等多项更新带来哪些新体验?
  • C++ decltype关键字详解:从类型推导到泛型编程实战
  • 从一首歌到整个歌库:163MusicLyrics 免费批量获取网易云与QQ音乐LRC歌词
  • 苹果的升级名单上没有它:OpenCore Legacy Patcher 让老 Mac 跑起新版 macOS
  • 探索型项目的合理开发顺序
  • 离谱!最弱小模型反向破解GPT、Claude,AI巨头护城河彻底崩塌
  • 番茄小说下载工具完整指南:5分钟批量下载整本小说并转EPUB
  • 163MusicLyrics 免费歌词下载完整指南:批量获取网易云与 QQ 音乐 LRC 歌词
  • 深耕用户体验与信任构建:详解企业级京东网站建设策略与实战指南
  • 从新手到专家:Mockito for Dart测试场景全攻略
  • 2026年8月14日广州市花都区移动500M宽带一篇说透 - 领卡园地
  • 微信聊天记录永久保存终极指南:WeChatMsg开源工具从零到精通
  • 同一个BT种子,为何有人5分钟下完、有人等3天?每天更新的Tracker列表让下载提速翻倍