一、前言
在大模型应用落地中,单次生成的内容常常存在逻辑松散、表达生硬、内容不达标的问题。想要让 AI 产出高质量文本,单纯依靠提示词优化远远不够。
今天给大家分享一套基于 LangGraph 实现的反思迭代智能体(Agent) ,模仿人类 "写作→自查问题→修改优化" 的思考流程,让大模型自动循环打磨内容,直到质量达标或达到迭代上限。本文以通义千问大模型为例,完整实现生成 - 评估 - 反思 - 重写的闭环工作流。
二、整体设计思路
整个 Agent 核心是三段式循环工作流,搭配条件判断实现流程终止,完全复刻人工写作反思逻辑:
- 内容生成:首次产出初稿,后续根据反思建议迭代改写;
- 质量评估:从内容完整度、逻辑、语言三个维度,对文章打出 0~1 的量化分数;
- 反思优化:根据低分定位文章问题,输出具体修改建议;
- 条件路由:设置双重终止规则,分数≥0.9 或 达到最大迭代次数,自动停止循环。
整体流程拓扑: 启动 → 生成文稿 → 质量评估 → 【条件判断】
- 达标 / 迭代用尽 → 结束流程
- 不达标 → 反思提建议 → 回到生成环节,循环优化
三、技术栈说明
- LangGraph:LangChain 生态下的图编排框架,用于搭建有状态、可循环、带条件分支的 Agent 工作流;
- 通义千问(ChatTongyi):作为核心大模型,承担生成、评估、反思三大任务;
- python-dotenv:管理密钥等环境变量,保障接口安全;
- TypedDict:定义全局状态结构体,统一流转数据。
四、核心代码解析
1. 环境与状态定义
首先加载环境变量、初始化大模型,并使用TypedDict定义全局状态。状态是 LangGraph 的核心,所有节点共享同一份状态数据,实现信息流转。
python
运行
import os
from typing import TypedDict
from dotenv import load_dotenv
from langchain_community.chat_models import ChatTongyi
from langgraph.constants import START, END
from langgraph.graph import StateGraph
# 加载环境变量
load_dotenv()
# 初始化通义千问大模型
llm = ChatTongyi(
model="qwen-max",
api_key=os.getenv("DASHSCOPE_API_KEY"),
temperature=0.7
)
# 定义全局状态:整个流程共享的数据
class ReflectionState(TypedDict):
task:str # 原始写作任务
draft:str # 文章草稿
quality_score:float # 质量评分
reflection:str # 反思修改建议
iteration:int # 当前迭代次数
max_iterations:int # 最大迭代上限
2. 三大核心节点
LangGraph 中节点对应独立执行单元,我们拆分出三个功能节点,各司其职:
(1)文稿生成节点 generate_draft
区分首次生成 和迭代改写两种场景:迭代次数为 0 时直接根据任务写初稿;非 0 则结合上一轮反思建议重写内容。
python
运行
def generate_draft(state: ReflectionState):
task = state["task"]
iteration=state["iteration"]
if iteration==0:
prompt=f"生成一篇关于{task}的文章,大约150字"
else:
previous_draft=state["draft"]
reflection=state["reflection"]
prompt=f"根据以下建议重写文章,保持150字左右:原文{previous_draft},改进建议{reflection}"
response=llm.invoke(prompt)
return {"draft":response.content, "iteration":iteration+1}
(2)质量评估节点 evaluate_quality
设计统一评估标准,让大模型输出 0~1 的量化分数,同时做异常兜底,防止模型返回非数字内容导致程序报错。
python
运行
def evaluate_quality(state: ReflectionState):
draft=state["draft"]
task=state["task"]
prompt=f"""评估文章质量,按内容、逻辑、语言综合给出0-1分数(保留两位小数),仅输出数字:
任务:{task} 文章:{draft}"""
score_text = llm.invoke(prompt).content.strip()
try:
score = float(score_text)
score = max(0.0, min(1.0, score))
except ValueError:
score = 0.5
return {"quality_score":score}
(3)反思建议节点 reflect_and_improve
结合文稿、评分分析问题,输出简短、可落地的修改方向,为下一轮改写提供依据。
python
运行
def reflect_and_improve(state:ReflectionState):
draft=state["draft"]
task=state["task"]
score=state["quality_score"]
prompt=f"分析文章问题并给出简短改进建议(50字内):任务{task},评分{score},内容{draft}"
reflection = llm.invoke(prompt).content
return {"reflection":reflection}
3. 条件路由与图编排
这是实现循环 + 分支 的关键:通过路由函数判断流程走向,再用StateGraph拼接所有节点和边。
python
运行
# 路由函数:判断是否继续迭代
def should_continue(state:ReflectionState):
score=state["quality_score"]
iteration=state["iteration"]
max_iter=state["max_iterations"]
if score>=0.9 or iteration>=max_iter:
return "end"
return "reflect"
# 构建流程图
def build_graph():
builder=StateGraph(ReflectionState)
# 注册节点
builder.add_node("generate_draft",generate_draft)
builder.add_node("evaluate_quality",evaluate_quality)
builder.add_node("reflect_and_improve",reflect_and_improve)
# 连接普通边
builder.add_edge(START,"generate_draft")
builder.add_edge("generate_draft","evaluate_quality")
# 条件分支
builder.add_conditional_edges(
source="evaluate_quality",
path=should_continue,
path_map={"reflect":"reflect_and_improve", "end":END}
)
# 循环边:反思后回到生成节点
builder.add_edge("reflect_and_improve","generate_draft")
return builder.compile()
4. 入口函数与运行调用
封装执行逻辑,初始化状态并启动工作流,最终打印迭代次数、最终评分和成品内容。
python
运行
def run_reflection_loop(task,max_iterations):
graph=build_graph()
initial_state={
"task":task,"draft":"","quality_score":0.0,
"reflection":"","iteration":0,"max_iterations":max_iterations
}
final_state=graph.invoke(initial_state)
# 打印最终结果
print(f"总迭代次数: {final_state['iteration']}")
print(f"最终分数: {final_state['quality_score']:.2f}")
print("最终文章:\n", final_state['draft'])
return final_state
if __name__=="__main__":
# 测试:主题+最大迭代3次
run_reflection_loop(task="人工智能的发展历程", max_iterations=3)
五、完整代码
import os
from typing import TypedDict
from dotenv import load_dotenv
from langchain_community.chat_models import ChatTongyi
from langgraph.constants import START, END
from langgraph.graph import StateGraph
load_dotenv()
# 初始化 LLM
llm = ChatTongyi(
model="qwen-max",
api_key=os.getenv("DASHSCOPE_API_KEY"),
temperature=0.7
)
#定义state
class ReflectionState(TypedDict):
task:str #任务描述
draft:str #当前草稿
quality_score:float #质量分数
reflection:str #反思内容
iteration:int #当前得迭代次数
max_iterations:int #最大迭代次数
#定义node1:生成文章/改进文章
def generate_draft(state: ReflectionState):
"""
node1:生成初稿或改进内容
任务:使用llm生成内容
:param state:
:return:
"""
task = state["task"]
iteration=state["iteration"]
if iteration==0:
print(f"Node1:生成一篇关于{task}的文章,大约150字")
prompt=f"""
生成一篇关于{task}的文章,大约150字"
"""
else:
previous_draft=state["draft"]
reflection=state["reflection"]
prompt=f"""
请改进以下文章:
原文:{previous_draft}
改进建议:{reflection}
请根据改进建议重写文章,保持150字左右。
"""
print(f"提示词:根据反思改进第{iteration}次")
print(f"反思建议:{reflection}")
response=llm.invoke(prompt)
draft=response.content
print(f"生成结果:{draft}")
return {
"draft":draft,
"iteration":iteration+1
}
#定义node2:评估质量,获得分数
def evaluate_quality(state: ReflectionState):
"""
Node2:评估质量
任务:使用llm评估文章质量
:param state:
:return:
"""
draft=state["draft"]
task=state["task"]
prompt=f"""
请评估以下文章的质量:
任务要求:写一篇关于'{task}'的文章
文章内容:
{draft}
评估标准:
1. 内容完整性 (是否涵盖主题)
2. 逻辑清晰度 (结构是否合理)
3. 语言表达 (是否流畅准确)
请给出0-1的分数(保留两位小数),只输出数字,不要其他内容。
例如:0.75
"""
response=llm.invoke(prompt)
score_text=response.content.strip()
try:
#提取分数
score=float(score_text)
score=max(0.0,min(1.0,score)) #确保在0~1之间
except ValueError:
print(f"无法解析分数,使用默认值0.5")
score=0.5
print(f"\n质量分数:{score:.2f}")
return {"quality_score":score}
#定义node3:反思改进
def reflect_and_improve(state:ReflectionState):
"""
Node3:反思改进
任务:使用LLM分析问题并给出改进建议
:param state:
:return:
"""
draft=state["draft"]
task=state["task"]
score=state["quality_score"]
prompt=f"""
请分析以下文章存在的问题,并给出具体的改进建议。
任务要求: 写一篇关于'{task}'的文章
当前文章:
{draft}
当前评分: {score:.2f}
请简要指出1-2个主要问题,并给出改进方向(50字以内)。
"""
response=llm.invoke(prompt)
reflection=response.content
print(f"\n改进建议:")
print(f"{reflection}")
return {"reflection":reflection}
#定义路由函数/条件边
def should_continue(state:ReflectionState):
"""
决定是否继续改进
终止条件:
1、质量分数>=0.9
2、达到最大迭代次数
:param state:
:return:
"""
score=state["quality_score"]
iteration=state["iteration"]
max_iter=state["max_iterations"]
print(f"\n{'=' * 60}")
print(f"条件判断: 是否继续改进")
print(f"{'=' * 60}")
print(f"当前分数: {score:.2f}")
print(f"迭代次数: {iteration}/{max_iter}")
#终止条件1:
if score>=0.9:
print(f"✅ 决策: 质量达标 (>= 0.9),结束改进")
return "end"
#终止条件2:
if iteration>=max_iter:
print(f"⚠️ 决策: 达到最大迭代次数,停止改进")
return "end"
print(f"❌ 决策: 质量不足,继续改进")
return "reflect"
#构建图
def build_graph():
#创建图
builder=StateGraph(ReflectionState)
#添加节点
builder.add_node("generate_draft",generate_draft)
builder.add_node("evaluate_quality",evaluate_quality)
builder.add_node("reflect_and_improve",reflect_and_improve)
#添加边
#普通边
builder.add_edge(START,"generate_draft")
builder.add_edge("generate_draft","evaluate_quality")
#条件边
builder.add_conditional_edges(
source="evaluate_quality",
path=should_continue,
path_map={
"reflect":"reflect_and_improve", #不合格->反思
"end":END #合格->结束
}
)
#循环边
builder.add_edge("reflect_and_improve","generate_draft")
graph=builder.compile()
return graph
def run_reflection_loop(task,max_iterations):
"""
运行反思
:param task:
:param max_iterations:
:return:
"""
print("\n" + "=" * 60)
print("反思循环 Agent 启动")
print("=" * 60)
print(f"任务: {task}")
print(f"最大迭代次数: {max_iterations}")
#构建图
graph=build_graph()
#初始状态
initial_state={
"task":task,
"draft":"",
"quality_score":0.0,
"reflection":"",
"iteration":0,
"max_iterations":max_iterations
}
#执行图
final_state=graph.invoke(initial_state)
# 显示最终结果
print("\n" + "=" * 60)
print("最终结果")
print("=" * 60)
print(f"总迭代次数: {final_state['iteration']}")
print(f"最终质量分数: {final_state['quality_score']:.2f}")
print(f"\n最终文章:")
print("-" * 60)
print(final_state['draft'])
print("-" * 60)
return final_state
if __name__=="__main__":
result=run_reflection_loop(
task="人工智能的发展历程",
max_iterations=3
)