精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖

锐英源精品原创文章,禁止转载和任何形式的非法内容使用,违者必究
图Graph通俗说法是串起来的线,有开始有结束,让数据在这条线上流动处理,最终有结果。把代码翻看一遍后,我用编程新手角度理解是里面合适地使用了类似函数指针技术,调度了一系列函数。当然这只是通俗易懂的比喻,让大家建立记忆印象入口,并不是说图Graph就是简单的如此,图Graph是智能体Agent核心模块,技术有质的突破,非常复杂,理论术语理解有困难,请联系锐英源软件。
智能体Agent的项目包含模块比较多,本文是系列文章,系列里介绍各个模块,希望看到的IT类朋友关注下锐英源软件,收藏本文,关注系列。
代码摘自liquid-quality-agent,liquid-quality-agent把工业视觉检测和Agent结合,项目经典,语言是Python语言。
Agent中的Graph(图)是其执行核心,它将传统Agent的线性或简单循环逻辑,升级为一个高度可控、有状态、可灵活编排的智能工作流。
它的核心思想是,将Agent的思考与行动过程,拆解为一张由节点(Nodes)、边(Edges) 和状态(State) 构成的有向状态图(StateGraph)。
🎯 Graph要实现什么?
Graph的核心目标是让Agent的决策过程变得可控、可观测且可追溯。与传统的线性链(Chain)相比,Graph通过状态图模型,能实现更复杂的逻辑:
🏗️ 一般架构:三大核心组件
一个LangGraph Agent的架构由以下三个核心组件构成:
一个Graph在运行前需要先编译(Compile),这个过程会检查图结构合法性,并配置检查点(Checkpointer)等运行时参数。
🔄 输入与输出
Graph的输入输出由其定义的State结构决定。
💡 一个典型的工作流示例
一个基于LangGraph的Agent工作流可能如下:
总的来说,Graph提供了一种结构化的方式,将复杂的决策过程拆解为清晰、可控的步骤,是实现可靠、可解释Agent的关键。
api.py里应该是接口代码,但是Graph怎么和其它模块结合的?应该是在http请求调用上下文里。
get_analysis_graph是图的生成函数,搜索get_analysis_graph,出现在下面位置:
@app.post("/agent/analyze", tags=["Agent"])
async def analyze(request: AgentRequest) -> dict:
try:
return await run_in_threadpool(
lambda: get_analysis_graph().invoke(
request.record_id,
request.request,
)
)
except Exception as exc:
raise HTTPException(
status_code=500,
detail=f"{type(exc).__name__}: {exc}",
) from exc
上面是函数代码,下面介绍一个重点细节:
lambda: get_analysis_graph().invoke(
加 lambda 的核心目的只有一个:将“立即执行”转变为“延迟执行”(惰性求值)。
如果没有 lambda,get_analysis_graph().invoke(...) 会在定义时(传参时)立即被执行,并把执行结果(返回值)传给外层函数。加上 lambda 后,这段代码变成了一个可调用的函数对象,只有在外层函数内部主动调用这个 lambda 时,.invoke() 才会真正运行。
具体来说,这行代码通常出现在以下典型场景中:
1. 异步任务/线程池提交(最常见)
在使用 ThreadPoolExecutor 或 Celery 时,提交任务不能立即执行,而是要交给调度器。
python
# 错误:立即执行,submit 拿到的是执行后的结果(而非任务)
executor.submit(get_analysis_graph().invoke(request.record_id, request.request))
# 正确:延迟执行,submit 拿到的是任务函数,调度器决定何时调用 lambda
executor.submit(lambda: get_analysis_graph().invoke(request.record_id, request.request))
2. 重试机制或条件触发
如果你正在使用 tenacity 重试库,或是某些工作流引擎(如 LangGraph 的 Command 或节点回调),框架需要传入一个“动作”而不是“结果”,以便在失败时重新执行。加 lambda 使得每次调用都会重新获取 get_analysis_graph() 实例,确保每次尝试都是全新的执行上下文。
3. 闭包捕获变量(按值引用)
虽然代码里直接用了 request,但加上 lambda 形成了一个闭包。这在循环或异步回调中特别重要——它保证执行时能正确拿到当前的 request 对象,而不会因为外部变量变化导致预期外的结果(虽然在当前单行调用中这不是主因,但这是 lambda 的通用特性)。
4. 避免无谓的资源开销
如果 get_analysis_graph() 初始化开销很大(例如加载模型权重),直接执行会立即占用资源。用 lambda 包装后,只有在真正需要分析时(例如用户点击按钮或满足特定业务条件)才会创建 Graph 对象并调用 invoke,实现了按需加载。
简单对比:
analysis_graph: QualityAnalysisGraph | None = None
record.record_id,
request.request,
_authoritative_decision_basis分析关键信息
D:\liquid-quality-agent\py311_env\Lib\site-packages\langgraph\graph,基类库提供的,在Anaconda环境里,是前辈们实现过的。
def _build(self):
builder = StateGraph(AgentState)
builder.add_node("load_record", self._load_record)
builder.add_node("retrieve_knowledge", self._retrieve_knowledge)
builder.add_node("generate_analysis", self._generate_analysis)
builder.add_node("validate_output", self._validate_output)
builder.add_edge(START, "load_record")
builder.add_conditional_edges(
"load_record",
self._record_route,
{"found": "retrieve_knowledge", "missing": END},
)
builder.add_edge("retrieve_knowledge", "generate_analysis")
builder.add_edge("generate_analysis", "validate_output")
builder.add_edge("validate_output", END)
return builder.compile()
def invoke(self, record_id: str, request: str) -> dict:
state = self.graph.invoke(
{"record_id": record_id, "request": request}
)
return state["result"]
对图概念理解下,实现不困难。调用是调用build里构造的链条上的各类函数,从load_record开始,到validate_output结束。
1. with_structured_output 方法
structured_model = self.model.with_structured_output(
AgentAnalysis,
method="function_calling",
include_raw=True,
)
经过包装后,structured_model 的 invoke 方法将自动处理输出解析。
2. 调用模型:structured_model.invoke(...)
response = structured_model.invoke(
[
SystemMessage(content=SYSTEM_PROMPT),
HumanMessage(
content=json.dumps(
{
"request": state["request"],
"record": self._compact_record(record),
"knowledge": knowledge,
},
ensure_ascii=False,
)
),
]
)
3. 返回值 response
由于设置了 include_raw=True,response 通常是一个字典或对象,包含:
后续代码可以从 response.parsed 中提取结构化分析结论,用于决策或进一步处理。
整体作用
这段代码是智能体(Agent)工作流中的一个核心环节:将用户请求、压缩后的记录和外部知识融合,交由 LLM 进行结构化分析,并以可编程的方式获得分析结果。这种方式避免了从自由文本中人工解析的麻烦,保证了输出的可靠性和一致性,非常适合用于质量检测、分类、决策等自动化任务。
潜在上下文补充