云计算百科
云计算领域专业知识百科平台

【LangGraph实战】《LangGraph实战》_154.[第8章 LangGraph平台] langgraph.json配置文件:应用程序格式定义详解

在这里插入图片描述

部署总报错?你可能连LangGraph的"身份证"都没写对!一文拆解langgraph.json所有暗坑,让你的Agent从本地跑通到云端丝滑上线。这篇内容把平台配置文件的每个字段掰开了、揉碎了讲,看完你就能明白:为什么代码在本地跑得欢,一上云就摆烂——问题八成出在这个小小的JSON里。

#mermaid-svg-YA4fSgmvom0NDjhf{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YA4fSgmvom0NDjhf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YA4fSgmvom0NDjhf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YA4fSgmvom0NDjhf .error-icon{fill:#552222;}#mermaid-svg-YA4fSgmvom0NDjhf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YA4fSgmvom0NDjhf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YA4fSgmvom0NDjhf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YA4fSgmvom0NDjhf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YA4fSgmvom0NDjhf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YA4fSgmvom0NDjhf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YA4fSgmvom0NDjhf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YA4fSgmvom0NDjhf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YA4fSgmvom0NDjhf .marker.cross{stroke:#333333;}#mermaid-svg-YA4fSgmvom0NDjhf svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YA4fSgmvom0NDjhf p{margin:0;}#mermaid-svg-YA4fSgmvom0NDjhf .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-YA4fSgmvom0NDjhf .cluster-label text{fill:#333;}#mermaid-svg-YA4fSgmvom0NDjhf .cluster-label span{color:#333;}#mermaid-svg-YA4fSgmvom0NDjhf .cluster-label span p{background-color:transparent;}#mermaid-svg-YA4fSgmvom0NDjhf .label text,#mermaid-svg-YA4fSgmvom0NDjhf span{fill:#333;color:#333;}#mermaid-svg-YA4fSgmvom0NDjhf .node rect,#mermaid-svg-YA4fSgmvom0NDjhf .node circle,#mermaid-svg-YA4fSgmvom0NDjhf .node ellipse,#mermaid-svg-YA4fSgmvom0NDjhf .node polygon,#mermaid-svg-YA4fSgmvom0NDjhf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YA4fSgmvom0NDjhf .rough-node .label text,#mermaid-svg-YA4fSgmvom0NDjhf .node .label text,#mermaid-svg-YA4fSgmvom0NDjhf .image-shape .label,#mermaid-svg-YA4fSgmvom0NDjhf .icon-shape .label{text-anchor:middle;}#mermaid-svg-YA4fSgmvom0NDjhf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YA4fSgmvom0NDjhf .rough-node .label,#mermaid-svg-YA4fSgmvom0NDjhf .node .label,#mermaid-svg-YA4fSgmvom0NDjhf .image-shape .label,#mermaid-svg-YA4fSgmvom0NDjhf .icon-shape .label{text-align:center;}#mermaid-svg-YA4fSgmvom0NDjhf .node.clickable{cursor:pointer;}#mermaid-svg-YA4fSgmvom0NDjhf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YA4fSgmvom0NDjhf .arrowheadPath{fill:#333333;}#mermaid-svg-YA4fSgmvom0NDjhf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YA4fSgmvom0NDjhf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YA4fSgmvom0NDjhf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YA4fSgmvom0NDjhf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YA4fSgmvom0NDjhf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YA4fSgmvom0NDjhf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YA4fSgmvom0NDjhf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YA4fSgmvom0NDjhf .cluster text{fill:#333;}#mermaid-svg-YA4fSgmvom0NDjhf .cluster span{color:#333;}#mermaid-svg-YA4fSgmvom0NDjhf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YA4fSgmvom0NDjhf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YA4fSgmvom0NDjhf rect.text{fill:none;stroke-width:0;}#mermaid-svg-YA4fSgmvom0NDjhf .icon-shape,#mermaid-svg-YA4fSgmvom0NDjhf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YA4fSgmvom0NDjhf .icon-shape p,#mermaid-svg-YA4fSgmvom0NDjhf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YA4fSgmvom0NDjhf .icon-shape .label rect,#mermaid-svg-YA4fSgmvom0NDjhf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YA4fSgmvom0NDjhf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YA4fSgmvom0NDjhf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YA4fSgmvom0NDjhf :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-YA4fSgmvom0NDjhf .root>*{fill:#ff9999!important;stroke:#cc0000!important;stroke-width:3px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .root span{fill:#ff9999!important;stroke:#cc0000!important;stroke-width:3px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .root tspan{fill:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .blue>*{fill:#99ccff!important;stroke:#0066cc!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .blue span{fill:#99ccff!important;stroke:#0066cc!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .blue tspan{fill:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .green>*{fill:#99ff99!important;stroke:#009900!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .green span{fill:#99ff99!important;stroke:#009900!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .green tspan{fill:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .yellow>*{fill:#ffff99!important;stroke:#cccc00!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .yellow span{fill:#ffff99!important;stroke:#cccc00!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .yellow tspan{fill:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .purple>*{fill:#cc99ff!important;stroke:#6600cc!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .purple span{fill:#cc99ff!important;stroke:#6600cc!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .purple tspan{fill:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .orange>*{fill:#ffcc99!important;stroke:#cc6600!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .orange span{fill:#ffcc99!important;stroke:#cc6600!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-YA4fSgmvom0NDjhf .orange tspan{fill:#000!important;}

langgraph.json配置文件全景图

graphs字段

dependencies字段

env字段

docker与node字段

http字段

避坑与最佳实践

Agent注册与入口

pip包与本地包

环境变量注入

自定义Dockerfile

FastAPI扩展

六脉神剑检查法

本文目录:

  • graphs字段:给你的Agent办一张"云端身份证"
  • dependencies字段:依赖管理的"生死簿"
  • env字段:环境变量的"暗号本"
  • docker与node字段:运行环境的"私人订制"
  • http字段:API门面的"装修手册"
  • 避坑急诊室:配置检查的"六脉神剑"
  • 嗨,大家好呀,我是你的老朋友精通代码大仙。接下来我们一起学习 《LangChain核心技术与LLM项目实践》。


    “饭要一口一口吃,代码要一行一行敲,但配置文件要是写错一行,前面一千行代码全白干。”

    这话搁在LangGraph平台上,简直不能再贴切了。你是不是也这样?本地Jupyter里Agent跑得虎虎生风,多轮对话、工具调用、条件边跳转,逻辑丝滑得像德芙。结果信心满满地往LangGraph平台上一推,报错信息密密麻麻,看得人头皮发麻。回去查了半天业务代码,没问题啊!最后发现,原来是 langgraph.json 里一个路径写歪了,或者一个逗号多余了,或者依赖忘声明了。

    别笑,这种"配置刺客"坑过的新手,能从北京排到广州。今天咱就把这个 langgraph.json 的底裤给扒了,把它每个字段的脾气、喜好、雷区,都聊个明明白白。争取让你看完这篇,以后写配置跟写Python一样顺手。


    1. graphs字段:给你的Agent办一张"云端身份证"

    点题

    graphs 是整个 langgraph.json 的灵魂,没有它,平台根本不知道该把你的哪个Agent挂出去提供服务。它是一个字典,key是你给这个图起的名字(这个名字会直接影响你后续调用API时的路径),value是一个字符串,格式必须是 "模块导入路径:变量名"。这个变量名指向的,必须是一个已经编译好的 CompiledGraph 实例。

    换句话说,这就是你的Agent在LangGraph云平台上的"身份证号码"。你代码里写得再天花乱坠,平台只认这个字段指明的入口。

    #mermaid-svg-P9JSxEAjqVHzwOHE{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-P9JSxEAjqVHzwOHE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-P9JSxEAjqVHzwOHE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-P9JSxEAjqVHzwOHE .error-icon{fill:#552222;}#mermaid-svg-P9JSxEAjqVHzwOHE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-P9JSxEAjqVHzwOHE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-P9JSxEAjqVHzwOHE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-P9JSxEAjqVHzwOHE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-P9JSxEAjqVHzwOHE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-P9JSxEAjqVHzwOHE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-P9JSxEAjqVHzwOHE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-P9JSxEAjqVHzwOHE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-P9JSxEAjqVHzwOHE .marker.cross{stroke:#333333;}#mermaid-svg-P9JSxEAjqVHzwOHE svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-P9JSxEAjqVHzwOHE p{margin:0;}#mermaid-svg-P9JSxEAjqVHzwOHE .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-P9JSxEAjqVHzwOHE .cluster-label text{fill:#333;}#mermaid-svg-P9JSxEAjqVHzwOHE .cluster-label span{color:#333;}#mermaid-svg-P9JSxEAjqVHzwOHE .cluster-label span p{background-color:transparent;}#mermaid-svg-P9JSxEAjqVHzwOHE .label text,#mermaid-svg-P9JSxEAjqVHzwOHE span{fill:#333;color:#333;}#mermaid-svg-P9JSxEAjqVHzwOHE .node rect,#mermaid-svg-P9JSxEAjqVHzwOHE .node circle,#mermaid-svg-P9JSxEAjqVHzwOHE .node ellipse,#mermaid-svg-P9JSxEAjqVHzwOHE .node polygon,#mermaid-svg-P9JSxEAjqVHzwOHE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-P9JSxEAjqVHzwOHE .rough-node .label text,#mermaid-svg-P9JSxEAjqVHzwOHE .node .label text,#mermaid-svg-P9JSxEAjqVHzwOHE .image-shape .label,#mermaid-svg-P9JSxEAjqVHzwOHE .icon-shape .label{text-anchor:middle;}#mermaid-svg-P9JSxEAjqVHzwOHE .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-P9JSxEAjqVHzwOHE .rough-node .label,#mermaid-svg-P9JSxEAjqVHzwOHE .node .label,#mermaid-svg-P9JSxEAjqVHzwOHE .image-shape .label,#mermaid-svg-P9JSxEAjqVHzwOHE .icon-shape .label{text-align:center;}#mermaid-svg-P9JSxEAjqVHzwOHE .node.clickable{cursor:pointer;}#mermaid-svg-P9JSxEAjqVHzwOHE .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-P9JSxEAjqVHzwOHE .arrowheadPath{fill:#333333;}#mermaid-svg-P9JSxEAjqVHzwOHE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-P9JSxEAjqVHzwOHE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-P9JSxEAjqVHzwOHE .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-P9JSxEAjqVHzwOHE .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-P9JSxEAjqVHzwOHE .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-P9JSxEAjqVHzwOHE .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-P9JSxEAjqVHzwOHE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-P9JSxEAjqVHzwOHE .cluster text{fill:#333;}#mermaid-svg-P9JSxEAjqVHzwOHE .cluster span{color:#333;}#mermaid-svg-P9JSxEAjqVHzwOHE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-P9JSxEAjqVHzwOHE .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-P9JSxEAjqVHzwOHE rect.text{fill:none;stroke-width:0;}#mermaid-svg-P9JSxEAjqVHzwOHE .icon-shape,#mermaid-svg-P9JSxEAjqVHzwOHE .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-P9JSxEAjqVHzwOHE .icon-shape p,#mermaid-svg-P9JSxEAjqVHzwOHE .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-P9JSxEAjqVHzwOHE .icon-shape .label rect,#mermaid-svg-P9JSxEAjqVHzwOHE .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-P9JSxEAjqVHzwOHE .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-P9JSxEAjqVHzwOHE .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-P9JSxEAjqVHzwOHE :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-P9JSxEAjqVHzwOHE .blue>*{fill:#99ccff!important;stroke:#0066cc!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-P9JSxEAjqVHzwOHE .blue span{fill:#99ccff!important;stroke:#0066cc!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-P9JSxEAjqVHzwOHE .blue tspan{fill:#000!important;}#mermaid-svg-P9JSxEAjqVHzwOHE .green>*{fill:#99ff99!important;stroke:#009900!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-P9JSxEAjqVHzwOHE .green span{fill:#99ff99!important;stroke:#009900!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-P9JSxEAjqVHzwOHE .green tspan{fill:#000!important;}

    graphs字段

    key: customer_support

    key: data_analyst

    ./src/support.py:graph

    ./src/analyst.py:workflow

    痛点分析

    新手在这个字段上栽的跟头,主要集中在三个地方。

    第一,路径写错。很多人本地开发习惯直接 python agent.py 跑,文件放哪儿都无所谓。但LangGraph平台的加载机制,本质上是从项目根目录做模块导入。你写 "./agent.py:graph",结果文件实际是 ./src/agent.py,平台一启动就给你抛一个找不到模块的错误。还有人在Windows上开发,路径大小写不敏感,写成 "./Agent.py:graph",本地跑得欢,一上Linux服务器,直接挂。

    第二,变量名对不上。你在代码里可能写的是 workflow = StateGraph(…),然后 app = workflow.compile(),结果配置文件里心血来潮写了个 "agent.py:graph"。平台会去 agent.py 里找一个叫 graph 的变量,找不到就傻眼了。更隐蔽的是,有人返回的是 StateGraph 构建器,忘了调用 compile(),平台拿到一个未编译的图,运行时各种诡异行为。

    第三,相对导入搞崩心态。你的 agent.py 里如果用了 from .utils import some_tool,那整个文件必须处于一个合法的Python包结构里。平台在导入 ./agent.py 时,如果周围缺少 __init__.py 或者包根目录没处理好,相对导入会直接炸。

    看看这个典型的错误配置:

    {
    "graphs": {
    "my_agent": "agent.py:graph"
    }
    }

    发现问题了吗?路径没加 ./,在某些解析场景下,平台可能把它当成一个第三方包名去import,而不是本地文件。再看代码里:

    from langgraph.graph import StateGraph
    from .utils import tool # 相对导入!

    builder = StateGraph(...)
    builder.add_node("node1", tool)
    app = builder.compile()

    配置里写的是 agent.py:graph,但代码里变量叫 app,而且用了相对导入。这部署上去,报错信息能让你怀疑人生。

    解决方案/正确做法

    首先,命名要老实。图编译完了,变量名就规范一点,叫 graph 挺好,别整那些 app、workflow_final_v2 之类的花活,除非你记得住。

    其次,路径要用从 langgraph.json 所在目录出发的相对路径,并且建议明确加上 ./。项目结构要清晰:

    my_project/
    ├── langgraph.json
    ├── .env
    └── src/
    ├── __init__.py
    ├── agent.py
    └── utils.py

    agent.py 里的代码:

    from langgraph.graph import StateGraph
    from .utils import tool # 包内相对导入,合法

    builder = StateGraph(...)
    builder.add_node("node1", tool)
    builder.add_edge("node1", "end")
    graph = builder.compile() # 明确编译,变量名对齐

    对应的 langgraph.json:

    {
    "graphs": {
    "my_agent": "./src/agent.py:graph"
    }
    }

    如果项目简单,不想搞包结构,那就全放根目录,用平级导入,避免相对导入的麻烦:

    from langgraph.graph import StateGraph
    from utils import tool # 同级导入

    builder = StateGraph(...)
    graph = builder.compile()

    {
    "graphs": {
    "my_agent": "./agent.py:graph"
    }
    }

    这样做的好处是,平台导入机制和你本地 python agent.py 的行为高度一致,排查问题时脑子不用切换上下文。而且一个项目完全可以注册多个图,比如一个客服Agent、一个数据分析Agent,各自独立升级:

    {
    "graphs": {
    "customer_support": "./src/support.py:graph",
    "data_analyst": "./src/analyst.py:graph"
    }
    }

    小结

    graphs 字段是LangGraph平台认识你的唯一入口。路径要对,变量名要准,图一定要是编译后的实例。这就像给Agent办身份证,照片和姓名错一个,安检都过不了。


    2. dependencies字段:依赖管理的"生死簿"

    点题

    代码再牛,缺少依赖包,跑到云端就是一个光杆司令。dependencies 字段就是告诉LangGraph平台:"我这个项目需要这些第三方库,麻烦你在容器里给我装上。"这个字段支持多种形式,最常见的是字符串数组,每个元素可以是一个具体的包名加版本号,也可以是一个依赖文件(如 requirements.txt)。

    痛点分析

    新手在这个字段上的迷惑行为,堪称人类多样性观察样本。

    第一种,重复造轮子式手动搬运。本地明明有 requirements.txt,里面写得整整齐齐,新手愣是把每个包重新手打到 langgraph.json 里。结果两边版本对不上,本地跑版本A,云端装版本B,行为不一致,排查到吐血。

    第二种,格式乱炖。有人把 requirements.txt 的内容原样粘贴进JSON数组:

    {
    "dependencies": [
    "langgraph==0.1.0\\nopenai==1.0.0\\npandas==2.0.0"
    ]
    }

    平台一看,这是一个包含换行符的字符串,当成一个包名去装,怎么可能成功?

    第三种,本地包引用一脸懵。你写了一个自定义工具包放在 ./packages/my_tools,主项目依赖它。结果你在 dependencies 里写 "./packages/my_tools",平台不认识,因为它需要特定的对象格式来声明本地路径依赖。

    第四种,开发依赖生产依赖不分。把 pytest、black、jupyter 全塞进去,构建镜像时慢得像乌龟爬,还可能因为某些开发包的子依赖冲突导致安装失败。

    解决方案/正确做法

    简单项目,直接用字符串数组最稳。平台支持在数组里直接引用 requirements.txt,这是我最推荐的写法,避免维护两份依赖清单:

    {
    "dependencies": [
    "-r requirements.txt"
    ]
    }

    你的 requirements.txt 就按老规矩写:

    langgraph>=0.1.0,<0.2.0
    langchain-openai>=0.1.0
    pandas>=2.0.0
    python-dotenv>=1.0.0

    如果你不想用文件,或者需要更精细的控制,直接写数组也行,但记得锁版本号,别裸写 langgraph,要写成 langgraph>=0.1.0 这种形式,防止未来版本 breaking change 把你埋了:

    {
    "dependencies": [
    "langgraph>=0.1.0",
    "langchain-openai>=0.1.0",
    "pandas>=2.0.0"
    ]
    }

    对于有本地包的场景,可以使用对象形式(具体取决于你使用的LangGraph平台版本,但核心思路一致):

    {
    "dependencies": {
    "pip": [
    "langgraph>=0.1.0",
    "openai>=1.0.0"
    ],
    "local": [
    "./packages/my_tools"
    ]
    }
    }

    这里的关键是,local 指向的目录里,必须有一个合法的 setup.py 或 pyproject.toml,让 pip 能以 editable 或普通模式安装它。别只是一个光秃秃的 .py 文件。

    另外,检查一下,你的依赖里真的需要 pytest 吗?不需要就删掉。云端运行只关心能让你的Agent活起来的包,其他的都是噪音。

    小结

    依赖声明是部署的粮草。能用 requirements.txt 统一管理就别手抄,版本号该锁就锁,本地包确保是可安装的合法包。粮草不足,再好的Agent也得饿死在半路。


    3. env字段:环境变量的"暗号本"

    点题

    大模型应用离不开API Key、数据库连接串、第三方服务令牌。这些东西打死都不能硬编码进代码里。env 字段就是告诉LangGraph平台:“去这个文件里找环境变量,然后注入到运行环境里。” 通常它指向项目根目录下的一个 .env 文件。

    痛点分析

    这个字段看似简单,但新手在这里犯的错,往往带着一种"我以为这样就行"的自信。

    第一种错误,路径对不上。你明明把环境变量写在了 .env.local 里,结果 langgraph.json 里写的是 "env": ".env"。平台找不到文件,自然注入了个寂寞,你的代码里 os.getenv("OPENAI_API_KEY") 返回 None,调用模型时直接401。

    第二种错误,格式带引号。有些同学习惯在 .env 文件里这样写:

    OPENAI_API_KEY="sk-1234567890"

    这在某些解析器眼里,那对英文双引号会被当成值的一部分。结果你拿到的Key变成了 "sk-1234567890"(带引号),发给OpenAI,人家不认。

    第三种错误,也是最严重的错误——硬编码。本地测试图省事,直接把Key写在代码里:

    import os
    # 千万别这样!!!
    api_key = "sk-abcdef123456"

    这要是提交到Git,再部署到平台,等于把你的密钥贴在电线杆上。

    还有一种情况:以为写了 env 字段,本地开发就不用管了。结果本地直接跑 python agent.py,发现 os.getenv 啥也读不到,因为本地并没有自动加载 .env 文件,那是平台部署时的行为。

    解决方案/正确做法

    首先,.env 文件的格式要干净,不要加引号:

    OPENAI_API_KEY=sk-1234567890
    DATABASE_URL=postgresql://user:pass@host/db
    LANGCHAIN_TRACING_V2=true

    然后,langgraph.json 里明确指向它:

    {
    "env": ".env"
    }

    如果你的环境文件放在子目录里,比如 config/.env,那就写 "env": "config/.env",但通常建议放根目录,简单直接。

    代码里要做兼容处理,让本地开发和云端部署都能跑通:

    import os
    from dotenv import load_dotenv

    # 本地开发时加载.env文件
    # 云端平台会自动注入环境变量,这行有则加载,无则跳过
    load_dotenv()

    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
    raise ValueError("OPENAI_API_KEY 没设置!检查一下.env文件和langgraph.json配置。")

    # 后续正常使用

    最后,也是最关键的一步:确保 .env 文件在你的 .gitignore 里!这是底线,红线,高压线!

    .env
    .env.local

    这样做的好处是,你的代码仓库永远是干净的,密钥只在本地和云端运行时存在。平台通过 env 字段读取并注入,代码通过 os.getenv 读取,两边配合天衣无缝。

    小结

    env 字段是你的保险箱,.env 文件是暗号本。路径要对,格式要纯,代码要读,Git要 ignore。密钥安全无小事,一次泄露,全家桶换Key换到你手软。


    4. docker与node字段:运行环境的"私人订制"

    点题

    LangGraph平台默认会给你一个容器环境跑你的Agent。但有时候,默认环境不够用。比如你的某个Python库需要系统级的 gcc 编译器,或者你需要用 playwright 调浏览器,又或者你的团队对Python版本有硬性要求(必须是3.11)。这时候,docker 字段允许你指定一个自定义的 Dockerfile,而 node 字段则用于指定Node.js运行时版本(如果你的项目涉及JS/TS前端或自定义服务)。

    痛点分析

    很多新手对这个字段的态度是两个极端:要么完全无视,遇到环境报错就抓瞎;要么过度定制,写一个巨复杂的 Dockerfile,把平台原本帮你做好的事也抢了。

    典型的错误案例一:基于一个不合适的镜像从头造轮子。

    FROM python:3.9-slim
    WORKDIR /app
    COPY . .
    RUN pip install -r requirements.txt
    CMD ["python", "agent.py"]

    这里面有几个问题。首先,CMD 完全是多余的,LangGraph平台有自己的进程管理和启动逻辑,不需要你指定容器启动命令。其次,如果你代码里用了Python 3.10的 match-case 语法,3.9的环境会直接语法错误。再者,slim 镜像缺少很多系统库,某些依赖(比如含C扩展的包)编译不过。

    典型的错误案例二:乱加 node 字段。明明是一个纯Python后端项目,看了某篇教程里有个 node 配置,也跟着写:

    {
    "node": {
    "version": "18"
    }
    }

    这不会让你的Python跑得更欢,反而可能让平台误解你的项目类型,增加不必要的构建步骤。

    还有一种痛:路径问题。dockerfile 的路径是相对于 langgraph.json 的,有人写成绝对路径 "dockerfile": "/home/user/project/Dockerfile",或者文件放在 ./docker/Dockerfile,配置里却写 "./Dockerfile",构建时找不到文件。

    解决方案/正确做法

    如果你不需要特殊系统依赖,最好的做法就是:不写 docker 字段。默认环境通常基于较新的Python版本,对LangGraph生态支持最好。

    但如果你确实需要自定义,比如要装一个系统依赖,那就基于官方推荐的基础镜像来写:

    FROM langchain/langgraph-api:latest
    # 或者明确指定python版本:FROM python:3.11-slim

    WORKDIR /app

    # 安装系统级依赖(按需)
    RUN apt-get update && apt-get install -y gcc libpq-dev

    COPY . .

    # 如果langgraph.json里没有完全声明依赖,可以在这里补装
    # 但推荐统一在langgraph.json里管理
    RUN pip install –no-cache-dir -e .

    对应的 langgraph.json:

    {
    "docker": {
    "dockerfile": "./Dockerfile"
    }
    }

    注意,这里没有 CMD,没有 ENTRYPOINT,平台会接管启动。你的职责只是准备好环境、把代码放进去。

    对于 node 字段,纯Python项目请直接忽略它。只有当你确实需要Node.js运行时(比如你的项目包含一个需要编译的React前端,或者你的自定义HTTP服务是基于Node的),才考虑配置。别让配置文件变成"大杂烩"。

    小结

    运行环境是地基。默认够用就别折腾,折腾就要把 Dockerfile 写扎实。记住,平台才是房东,你只需要把房子装修好,别抢房东的钥匙。


    5. http字段:API门面的"装修手册"

    点题

    LangGraph平台部署成功后,会自动暴露一套REST API,让你能通过HTTP请求触发你的Agent。但有时候,你想在这个基础上扩展一些东西,比如加一个 /health 健康检查接口,或者加一个业务相关的 /webhook 接收第三方回调。http 字段就是干这个的,它允许你挂载一个自定义的FastAPI应用(或其他ASGI兼容应用),与LangGraph的原生接口共存。

    痛点分析

    新手对这个字段最大的误解,是以为不写它就没有API,于是拼命在代码里自己起一个HTTP服务器。

    看看这个令人窒息的操作:

    # agent.py 的末尾
    if __name__ == "__main__":
    import uvicorn
    from fastapi import FastAPI

    app = FastAPI()
    uvicorn.run(app, host="0.0.0.0", port=8000)

    然后配上这样的 langgraph.json:

    {
    "graphs": {
    "agent": "./agent.py:graph"
    },
    "http": {
    "app": "./agent.py:app"
    }
    }

    这会导致什么?平台本身已经是一个HTTP服务器了,它去导入你的模块时,一碰到 uvicorn.run() 就试图绑定端口。端口冲突、启动失败、容器崩溃,一条龙服务。

    还有一种错误:挂载的应用类型不对。http.app 需要的是一个ASGI应用实例(通常是FastAPI)。有人写了一个Flask应用传进去:

    from flask import Flask
    app = Flask(__name__)

    Flask是WSGI,不是ASGI,平台挂载时会直接报错。

    另外,assistant_id 等子字段如果用错了场景,也会导致默认路由行为异常。比如你想指定默认助手,但拼写错误写成 assistand_id,平台无视,你调用时还得显式传ID。

    解决方案/正确做法

    先在心里默念三遍:平台本身就是服务器,我不需要再起一个!

    如果你不需要自定义接口,那么 langgraph.json 里完全可以不出现 http 字段。原生REST API足够你用了。

    如果你确实需要扩展,单独写一个API文件,保持职责清晰:

    # custom_api.py
    from fastapi import FastAPI

    app = FastAPI()

    @app.get("/health")
    async def health_check():
    return {"status": "healthy", "service": "langgraph-agent"}

    @app.post("/webhook")
    async def receive_webhook(payload: dict):
    # 处理第三方回调
    return {"received": True}

    然后在 langgraph.json 里引用:

    {
    "graphs": {
    "agent": "./agent.py:graph"
    },
    "http": {
    "app": "./custom_api.py:app"
    }
    }

    这样,你的Agent接口(如 /threads/{thread_id}/runs)和自定义接口(/health、/webhook)就能在同一个域名下共存,互不影响。

    如果你的配置里还需要指定默认的 assistant_id,确保拼写正确:

    {
    "http": {
    "app": "./custom_api.py:app",
    "assistant_id": "my-default-agent"
    }
    }

    但大多数情况下,新手先别碰这个字段,把默认API用熟再说。

    小结

    http 字段是高级装修,没需求就留空,有需求就确保你的 app 是标准FastAPI实例,千万别在代码里重复启动服务器。门面要大气,但不能把承重墙砸了。


    6. 避坑急诊室:配置检查的"六脉神剑"

    点题

    前面我们把五个核心字段单独拉出来聊了,但在实战中,真正的失败往往不是某一个字段的锅,而是各种细节凑在一起引发的"复合型雪崩"。这一节,我把新手最容易忽略的六个综合陷阱集中曝光,并给你一份可直接落地的检查清单。

    #mermaid-svg-LNH850SPnTVuEIGU{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LNH850SPnTVuEIGU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LNH850SPnTVuEIGU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LNH850SPnTVuEIGU .error-icon{fill:#552222;}#mermaid-svg-LNH850SPnTVuEIGU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LNH850SPnTVuEIGU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LNH850SPnTVuEIGU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LNH850SPnTVuEIGU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LNH850SPnTVuEIGU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LNH850SPnTVuEIGU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LNH850SPnTVuEIGU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LNH850SPnTVuEIGU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LNH850SPnTVuEIGU .marker.cross{stroke:#333333;}#mermaid-svg-LNH850SPnTVuEIGU svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LNH850SPnTVuEIGU p{margin:0;}#mermaid-svg-LNH850SPnTVuEIGU .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-LNH850SPnTVuEIGU .cluster-label text{fill:#333;}#mermaid-svg-LNH850SPnTVuEIGU .cluster-label span{color:#333;}#mermaid-svg-LNH850SPnTVuEIGU .cluster-label span p{background-color:transparent;}#mermaid-svg-LNH850SPnTVuEIGU .label text,#mermaid-svg-LNH850SPnTVuEIGU span{fill:#333;color:#333;}#mermaid-svg-LNH850SPnTVuEIGU .node rect,#mermaid-svg-LNH850SPnTVuEIGU .node circle,#mermaid-svg-LNH850SPnTVuEIGU .node ellipse,#mermaid-svg-LNH850SPnTVuEIGU .node polygon,#mermaid-svg-LNH850SPnTVuEIGU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LNH850SPnTVuEIGU .rough-node .label text,#mermaid-svg-LNH850SPnTVuEIGU .node .label text,#mermaid-svg-LNH850SPnTVuEIGU .image-shape .label,#mermaid-svg-LNH850SPnTVuEIGU .icon-shape .label{text-anchor:middle;}#mermaid-svg-LNH850SPnTVuEIGU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LNH850SPnTVuEIGU .rough-node .label,#mermaid-svg-LNH850SPnTVuEIGU .node .label,#mermaid-svg-LNH850SPnTVuEIGU .image-shape .label,#mermaid-svg-LNH850SPnTVuEIGU .icon-shape .label{text-align:center;}#mermaid-svg-LNH850SPnTVuEIGU .node.clickable{cursor:pointer;}#mermaid-svg-LNH850SPnTVuEIGU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LNH850SPnTVuEIGU .arrowheadPath{fill:#333333;}#mermaid-svg-LNH850SPnTVuEIGU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LNH850SPnTVuEIGU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LNH850SPnTVuEIGU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LNH850SPnTVuEIGU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LNH850SPnTVuEIGU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LNH850SPnTVuEIGU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LNH850SPnTVuEIGU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LNH850SPnTVuEIGU .cluster text{fill:#333;}#mermaid-svg-LNH850SPnTVuEIGU .cluster span{color:#333;}#mermaid-svg-LNH850SPnTVuEIGU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LNH850SPnTVuEIGU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LNH850SPnTVuEIGU rect.text{fill:none;stroke-width:0;}#mermaid-svg-LNH850SPnTVuEIGU .icon-shape,#mermaid-svg-LNH850SPnTVuEIGU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LNH850SPnTVuEIGU .icon-shape p,#mermaid-svg-LNH850SPnTVuEIGU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LNH850SPnTVuEIGU .icon-shape .label rect,#mermaid-svg-LNH850SPnTVuEIGU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LNH850SPnTVuEIGU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LNH850SPnTVuEIGU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LNH850SPnTVuEIGU :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-LNH850SPnTVuEIGU .blue>*{fill:#99ccff!important;stroke:#0066cc!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-LNH850SPnTVuEIGU .blue span{fill:#99ccff!important;stroke:#0066cc!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-LNH850SPnTVuEIGU .blue tspan{fill:#000!important;}#mermaid-svg-LNH850SPnTVuEIGU .green>*{fill:#99ff99!important;stroke:#009900!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-LNH850SPnTVuEIGU .green span{fill:#99ff99!important;stroke:#009900!important;stroke-width:2px!important;color:#000!important;}#mermaid-svg-LNH850SPnTVuEIGU .green tspan{fill:#000!important;}

    写完langgraph.json

    JSON格式校验

    路径大小写检查

    依赖版本锁定

    环境变量核对

    Gitignore确认

    云端部署

    痛点分析

    第一剑:JSON的尾随逗号(Trailing Comma)

    这是史诗级巨坑。写Python写习惯了,末尾加个逗号觉得无所谓,但JSON标准不允许!

    {
    "graphs": {
    "agent": "./agent.py:graph",
    },
    "dependencies": [
    "langgraph",
    ]
    }

    看到那两个逗号了吗?在VS Code里可能都高亮得不明显,但平台一解析,直接抛 JSONDecodeError。而且报错位置往往指得模棱两可,让你以为是文件编码问题。

    第二剑:大小写与路径幻觉

    Windows开发者特别容易中招。你的文件叫 ./Agent.py(大写A),Windows本地不区分大小写,跑得飞起。平台容器多半是Linux,大小写敏感,直接 FileNotFoundError。

    第三剑:依赖版本裸奔

    写 "langgraph" 而不带版本号,平台默认装最新版。今天部署成功,下个月LangGraph发了个大版本,新特性改了API,你的代码没动,但重新构建时装上了新版,直接挂掉。这叫"时间炸弹"。

    第四剑:.env裸奔进Git

    代码里明明用了 .env,但忘记写进 .gitignore,一提交,密钥全剧透。更惨的是,如果仓库是公开的,爬虫几秒钟就能扫到你的OpenAI Key,账单直接飞天。

    第五剑:包结构残缺

    你用了 from .utils import …,但目录下没有 __init__.py。虽然Python 3.3+支持隐式命名空间包,但某些构建工具链或旧版平台运行时可能不买账,导入时报 attempted relative import with no known parent package。

    第六剑:环境变量只在本地,忘了云端

    本地 .env 里填得满满当当,但部署到平台时,忘了把 .env 的内容同步到平台的Secrets管理面板,或者 langgraph.json 里的 env 路径指向错误。结果本地能调OpenAI,云端报401。

    解决方案/正确做法

    来,给你一个可以直接抄作业的、相对完整的 langgraph.json 模板,对照着检查:

    {
    "graphs": {
    "customer_support": "./src/support_agent.py:graph",
    "research_bot": "./src/research_agent.py:graph"
    },
    "dependencies": [
    "langgraph>=0.1.0,<0.2.0",
    "langchain-openai>=0.1.0",
    "pandas>=2.0.0",
    "python-dotenv>=1.0.0"
    ],
    "env": ".env",
    "docker": {
    "dockerfile": "./Dockerfile"
    }
    }

    逐行解释:

    • graphs:两个Agent,路径明确,变量名 graph 与代码对齐。
    • dependencies:版本号锁区间,不裸奔;只装运行必要的包。
    • env:指向根目录 .env。
    • docker:按需启用,不需要时整段删掉。

    检查清单(建议保存):

  • JSON校验:复制到在线JSON校验工具,或Python里 json.loads() 跑一下,确保无尾随逗号。
  • 路径核对:Linux下跑一遍 ls 你的路径,确认大小写完全匹配。
  • 版本锁定:每个依赖都有版本号,格式为 包名>=x.x.x,<y.y.y。
  • Gitignore确认:.gitignore 里包含 .env、.env.local、__pycache__、.DS_Store。
  • 本地预演:在项目根目录执行 python -c "from src.support_agent import graph; print(type(graph))",确认导入无报错且类型是 CompiledGraph。
  • 环境变量双检:本地读 .env,云端平台也要检查Secrets面板或确保 .env 随部署上传且路径正确。
  • 小结

    魔鬼藏在细节里。一个逗号、一个大小写、一个版本号、一次Git提交,都能让云端部署变成灾难。写完配置,请像Code Review一样审视它,六脉神剑走一遍,基本能挡住九成血案。


    写在最后

    兄弟,咱们写代码的人,天生喜欢折腾逻辑、搞算法、调模型,总觉得配置文件这种"体力活"不值得花心思。但LangGraph平台不吃这一套,它只认你白纸黑字写进 langgraph.json 的规则。你可以把Agent调得比诸葛亮还聪明,但配置表填错了,上云那一刻,它就是个黑户。

    这篇文章把 langgraph.json 从 graphs 到 http,从依赖到环境,再到各种新手坟场,都捋了一遍。核心就一句话:平台不会读心术,你写的每一个字符,都是给它的指令。 把路径写对,把依赖锁死,把密钥藏好,把JSON校验完,你就已经击败了百分之八十的同级选手。

    编程之路不易,但每一步成长都算数。别害怕那些在配置里摔过的跤,它们都是你往后排查问题的肌肉记忆。保持好奇,持续学习,下次部署时,愿你的容器一路绿灯,Agent秒级响应。你只管写好业务,配置这关,咱已经拿下了。

    关注私信备注:“资料代找获取”,全网计算机学习资料代找:例如: 《课程:AI 大模型工程师系统课程 (22 章完整版 持续更新)》 《课程:AI 大模型系统实战课第四期 (2026 年开课 持续更新)》 《课程:2026 年 AGI 大模型系统课 23 期》 《课程:2026 年 AGI 大模型系统课 21 期》 《课程:AI 大模型实战课 8 期 (2026 年 2 月最新完结版)》 《课程:AI 大模型系统实战课三期》 《课程:AI 大模型系统课程 (2026 年 2 月开课 持续更新)》 《课程:AI 大模型全阶课程 (2025 年 12 月开课 2026 年 6 月结课)》 《课程:AI 大模型工程师全阶课程 (2025 年 10 月开课 2026 年 4 月结课)》 《课程:2026 年最新大模型 Agent 开发系统课 (持续更新)》 《课程:LLM 多模态视觉大模型系统课》 《课程:大模型 AI 应用开发企业级项目实战课 (2026 年 1 月开课)》 《课程:大模型智能体线上速成班 V2.0》 《课程:Java+AI 大模型智能应用开发全阶课》 《课程:Python+AI 大模型实战视频教程》 《书籍:软件工程 3.0: 大模型驱动的研发新范式.pdf》 《课程:人工智能大模型系统课 (2026 年 1 月底完结版)》 《课程:AI 大模型零基础到商业实战全栈课第五期》 《课程:Vue3.5+Electron + 大模型跨平台 AI 桌面聊天应用实战 (2025)》 《课程:AI 大模型实战训练营 从入门到实战轻松上手》 《课程:2026 年 AI 大模型 RAG 与 Agent 智能体项目实战开发课》 《课程:大模型训练营配套补充资料》

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 【LangGraph实战】《LangGraph实战》_154.[第8章 LangGraph平台] langgraph.json配置文件:应用程序格式定义详解
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!