💻 源码
from langgraph.graph import StateGraph, START, END
from langchain_ollama import ChatOllama
from langgraph.types import Send
from typing_extensions import TypedDict
from typing import Annotated
from pydantic import BaseModel, Field
import operator


class Section(BaseModel):
    num: int = Field(description="章节序号")
    name: str = Field(description="章节标题,采用“【第三章】 迷雾重现”的形式")
    description: str = Field(
        description="章节描述,最前面是章节标题,后面是章节内容。章节标题采用“【第三章】 迷雾重现”的形式,单独一行")


class Sections(BaseModel):
    sections: list[Section] = Field(description="文章的各个子章节")


class State(TypedDict):
    storyLine: str
    sections: list[Section]
    completedSections: Annotated[list, operator.add]
    novel: str


class WorkerState(TypedDict):
    section: Section
    completedSections: Annotated[list, operator.add]


llm = ChatOllama(model="qwen2.5:7b")


def getWholeStory(state):
    prompt = "你是一位著名小说家,正在创作一部精彩的侦探小说,首先给出故事梗概,1000字左右。"
    state["storyLine"] = llm.invoke(prompt).content
    print("storyLine  " + "*" * 80)
    print(state["storyLine"])
    return state


def orchestrate(state):
    planner = llm.with_structured_output(Sections)
    result = planner.invoke("""你是一位著名小说家,正在创作一部精彩的侦探小说,根据下面的【故事梗概】,将小说分成10个章节,并给出章节的剧情发展。1000字左右。
                            【故事梗概】
                            """ + state["storyLine"])
    state["sections"] = result.sections
    print("sections  " + "*" * 80)
    for section in state["sections"]:
        print(str(section.name + '        ' + section.description))
    return state

def buildGraph():
    graphBuilder = StateGraph(State)

    graphBuilder.add_node("getWholeStory", getWholeStory)
    graphBuilder.add_node("orchestrate", orchestrate)

    graphBuilder.add_edge(START, "getWholeStory")
    graphBuilder.add_edge("getWholeStory", "orchestrate")

    graph = graphBuilder.compile()
    return graph


if __name__ == "__main__":
    graph = buildGraph()

    #from tools import showGraph

    #showGraph.showGraphInCode(graph, "graph.jpg")

    state: State = {}
    result = graph.invoke(state)