(LangGraph教程)4. Building Your Assistant——Lesson 2:Sub-graphs子图(未索引)

发布时间:2026/10/1 10:32:33
(LangGraph教程)4. Building Your Assistant——Lesson 2:Sub-graphs子图(未索引) https://academy.langchain.com/courses/intro-to-langgraphhttps://github.com/shangxiang0907/langchain-academy文章目录Sub-graphs 子图Review 复习Goals 目标State 状态Input 输入Sub graphs 子图Adding sub graphs to our parent graph 将子图添加到父图LangSmithSub-graphs 子图Review 复习We’re building up to a multi-agent research assistant that ties together all of the modules from this course.我们正在构建一个多功能智能体研究助手该助手将本课程所有模块整合在一起。We just covered parallelization, which is one important LangGraph controllability topic.我们刚刚学习了并行化这是 LangGraph 可控性的一个重要主题。Goals 目标Now, we’re going to cover sub-graphs.接下来我们将学习子图。State 状态Sub-graphs allow you to create and manage different states in different parts of your graph.子图允许你在图的不同部分创建和管理不同的状态。This is particularly useful for multi-agent systems, with teams of agents that each have their own state.这对多智能体系统尤其有用——例如由多个智能体组成的团队每个智能体都拥有自己的状态。Let’s consider a toy example:我们来看一个简化示例I have a system that accepts logs我有一个接收日志的系统It performs two separate sub-tasks by different agents (summarize logs, find failure modes)它由不同智能体执行两项独立的子任务摘要日志、识别故障模式I want to perform these two operations in two different sub-graphs.我希望在这两个不同的子图中分别执行这两项操作。The most critical thing to understand is how the graphs communicate!最关键的是要理解图之间如何通信In short, communication isdone with over-lapping keys:简而言之通信是通过**重叠的键keys**实现的The sub-graphs can accessdocsfrom the parent子图可访问父图中的docsThe parent can accesssummary/failure_reportfrom the sub-graphs父图可访问子图中的summary/failure_reportInput 输入Let’s define a schema for the logs that will be input to our graph.我们来定义将输入到图中的日志的结构。%%capture--no-stderr%pip install-U langgraphWe’ll use LangSmith for tracing.我们将使用 LangSmith 进行追踪tracing。importos,getpassdef_set_env(var:str):ifnotos.environ.get(var):os.environ[var]getpass.getpass(f{var}: )_set_env(LANGSMITH_API_KEY)os.environ[LANGSMITH_TRACING]trueos.environ[LANGSMITH_PROJECT]langchain-academyfromoperatorimportaddfromtyping_extensionsimportTypedDictfromtypingimportList,Optional,Annotated# The structure of the logsclassLog(TypedDict):id:strquestion:strdocs:Optional[List]answer:strgrade:Optional[int]grader:Optional[str]feedback:Optional[str]Sub graphs 子图Here is the failure analysis sub-graph, which usesFailureAnalysisState.以下是故障分析子图它使用FailureAnalysisState。fromIPython.displayimportImage,displayfromlanggraph.graphimportStateGraph,START,END# Failure Analysis Sub-graphclassFailureAnalysisState(TypedDict):cleaned_logs:List[Log]failures:List[Log]fa_summary:strprocessed_logs:List[str]classFailureAnalysisOutputState(TypedDict):fa_summary:strprocessed_logs:List[str]defget_failures(state): Get logs that contain a failure cleaned_logsstate[cleaned_logs]failures[logforlogincleaned_logsifgradeinlog]return{failures:failures}defgenerate_summary(state): Generate summary of failures failuresstate[failures]# Add fxn: fa_summary summarize(failures)fa_summaryPoor quality retrieval of Chroma documentation.return{fa_summary:fa_summary,processed_logs:[ffailure-analysis-on-log-{failure[id]}forfailureinfailures]}fa_builderStateGraph(state_schemaFailureAnalysisState,output_schemaFailureAnalysisOutputState)fa_builder.add_node(get_failures,get_failures)fa_builder.add_node(generate_summary,generate_summary)fa_builder.add_edge(START,get_failures)fa_builder.add_edge(get_failures,generate_summary)fa_builder.add_edge(generate_summary,END)graphfa_builder.compile()display(Image(graph.get_graph().draw_mermaid_png()))Here is the question summarization sub-grap, which usesQuestionSummarizationState.以下是问题摘要子图它使用QuestionSummarizationState。# Summarization subgraphclassQuestionSummarizationState(TypedDict):cleaned_logs:List[Log]qs_summary:strreport:strprocessed_logs:List[str]classQuestionSummarizationOutputState(TypedDict):report:strprocessed_logs:List[str]defgenerate_summary(state):cleaned_logsstate[cleaned_logs]# Add fxn: summary summarize(generate_summary)summaryQuestions focused on usage of ChatOllama and Chroma vector store.return{qs_summary:summary,processed_logs:[fsummary-on-log-{log[id]}forlogincleaned_logs]}defsend_to_slack(state):qs_summarystate[qs_summary]# Add fxn: report report_generation(qs_summary)reportfoo bar bazreturn{report:report}qs_builderStateGraph(QuestionSummarizationState,output_schemaQuestionSummarizationOutputState)qs_builder.add_node(generate_summary,generate_summary)qs_builder.add_node(send_to_slack,send_to_slack)qs_builder.add_edge(START,generate_summary)qs_builder.add_edge(generate_summary,send_to_slack)qs_builder.add_edge(send_to_slack,END)graphqs_builder.compile()display(Image(graph.get_graph().draw_mermaid_png()))Adding sub graphs to our parent graph 将子图添加到父图Now, we can bring it all together.现在我们可以将所有内容整合起来。We create our parent graph withEntryGraphState.我们使用EntryGraphState创建父图。And we add our sub-graphs as nodes!并将我们的子图作为节点添加进去entry_builder.add_node(question_summarization, qs_builder.compile()) entry_builder.add_node(failure_analysis, fa_builder.compile())# Entry GraphclassEntryGraphState(TypedDict):raw_logs:List[Log]cleaned_logs:Annotated[List[Log],add]# This will be USED BY in BOTH sub-graphsfa_summary:str# This will only be generated in the FA sub-graphreport:str# This will only be generated in the QS sub-graphprocessed_logs:Annotated[List[int],add]# This will be generated in BOTH sub-graphsBut, why doescleaned_logshave a reducer if it only goesintoeach sub-graph as an input?但为什么cleaned_logs需要一个归约器reducer而它仅作为输入传入每个子图It is not modified.它并未被修改。cleaned_logs: Annotated[List[Log], add] # This will be USED BY in BOTH sub-graphsThis is because the output state of the subgraphs will containall keys, even if they are unmodified.这是因为子图的输出状态将包含所有键即使它们未被修改。The sub-graphs are run in parallel.子图是并行运行的。Because the parallel sub-graphs return the same key, it needs to have a reducer likeoperator.addto combine the incoming values from each sub-graph.由于并行子图返回相同的键因此需要一个类似operator.add的归约器以合并各子图传入的值。But, we can work around this by using another concept we talked about before.但我们可以借助之前讨论过的另一个概念来规避此问题。We can simply create an output state schema for each sub-graph and ensure that the output state schema contains different keys to publish as output.我们可以为每个子图简单地创建一个输出状态结构并确保该输出状态结构包含不同的键以便作为输出发布。We don’t actually need each sub-graph to outputcleaned_logs.我们实际上并不需要每个子图都输出cleaned_logs。# Entry GraphclassEntryGraphState(TypedDict):raw_logs:List[Log]cleaned_logs:List[Log]fa_summary:str# This will only be generated in the FA sub-graphreport:str# This will only be generated in the QS sub-graphprocessed_logs:Annotated[List[int],add]# This will be generated in BOTH sub-graphsdefclean_logs(state):# Get logsraw_logsstate[raw_logs]# Data cleaning raw_logs - docscleaned_logsraw_logsreturn{cleaned_logs:cleaned_logs}entry_builderStateGraph(EntryGraphState)entry_builder.add_node(clean_logs,clean_logs)entry_builder.add_node(question_summarization,qs_builder.compile())entry_builder.add_node(failure_analysis,fa_builder.compile())entry_builder.add_edge(START,clean_logs)entry_builder.add_edge(clean_logs,failure_analysis)entry_builder.add_edge(clean_logs,question_summarization)entry_builder.add_edge(failure_analysis,END)entry_builder.add_edge(question_summarization,END)graphentry_builder.compile()fromIPython.displayimportImage,display# Setting xray to 1 will show the internal structure of the nested graphdisplay(Image(graph.get_graph(xray1).draw_mermaid_png()))# Dummy logsquestion_answerLog(id1,questionHow can I import ChatOllama?,answerTo import ChatOllama, use: from langchain_community.chat_models import ChatOllama.,)question_answer_feedbackLog(id2,questionHow can I use Chroma vector store?,answerTo use Chroma, define: rag_chain create_retrieval_chain(retriever, question_answer_chain).,grade0,graderDocument Relevance Recall,feedbackThe retrieved documents discuss vector stores in general, but not Chroma specifically,)raw_logs[question_answer,question_answer_feedback]graph.invoke({raw_logs:raw_logs}){raw_logs: [{id: 1, question: How can I import ChatOllama?, answer: To import ChatOllama, use: from langchain_community.chat_models import ChatOllama.}, {id: 2, question: How can I use Chroma vector store?, answer: To use Chroma, define: rag_chain create_retrieval_chain(retriever, question_answer_chain)., grade: 0, grader: Document Relevance Recall, feedback: The retrieved documents discuss vector stores in general, but not Chroma specifically}], cleaned_logs: [{id: 1, question: How can I import ChatOllama?, answer: To import ChatOllama, use: from langchain_community.chat_models import ChatOllama.}, {id: 2, question: How can I use Chroma vector store?, answer: To use Chroma, define: rag_chain create_retrieval_chain(retriever, question_answer_chain)., grade: 0, grader: Document Relevance Recall, feedback: The retrieved documents discuss vector stores in general, but not Chroma specifically}], fa_summary: Poor quality retrieval of Chroma documentation., report: foo bar baz, processed_logs: [failure-analysis-on-log-2, summary-on-log-1, summary-on-log-2]}LangSmithLet’s look at the LangSmith trace:我们来看 LangSmith 追踪结果https://smith.langchain.com/public/f8f86f61-1b30-48cf-b055-3734dfceadf2/rhttps://smith.langchain.com/public/f8f86f61-1b30-48cf-b055-3734dfceadf2/r

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询