LangGraph 快速入门指南

发布时间:2026/7/29 16:38:57

LangGraph 快速入门指南 LangGraph 快速入门指南本文档是langgraph_demo/项目的配套学习笔记。目标从零开始理解 LangGraph Agent 的构建原理、项目架构和每一步的必要性。目录项目概览与目录结构三层架构设计理念快速入门六步骤详解运行项目常见问题与扩展建议1. 项目概览与目录结构1.1 项目目录树langgraph_demo/ # 项目根目录 ├── .env # 环境变量API 密钥等敏感信息 ├── .gitignore # Git 忽略规则 ├── requirements.txt # Python 依赖清单 ├── main.py # 【表现层】程序入口 ├── quickstart_guide.md # 本文档配套学习笔记 └── app/ # 应用核心三层架构 ├── __init__.py # Python 包标识 ├── config.py # 【配置层】环境变量与参数管理 ├── models.py # 【数据模型层】State 与 DTO 定义 ├── tools.py # 【数据访问层】外部工具/函数定义 └── agent_builder.py # 【业务逻辑层】Agent 构建与编排1.2 每个文件/文件夹的意义文件/文件夹职责类比 Java 项目.env存储 API 密钥等环境变量不提交到 Gitapplication-secret.ymlrequirements.txt声明 Python 依赖及其版本pom.xml/build.gradlemain.py程序入口处理用户交互调度各步骤Controller层app/核心业务代码包service/dao/model/app/__init__.py标识app/为 Python 包包声明app/config.py集中管理所有配置参数ConfigurationPropertiesapp/models.py定义数据结构和状态类型Entity/DTOapp/tools.py定义 Agent 可调用的工具函数DAO/Repositoryapp/agent_builder.py构建和编译 LangGraph AgentService层2. 三层架构设计理念2.1 为什么要分层一个没有架构的 Python 脚本所有代码堆在同一个文件中就像把 Controller、Service、DAO 全写在一个 Java 类里 —— 刚开始觉得方便但一旦需求变多就会陷入改一处动全身的困境。分层架构的核心原则每一层各司其职层与层之间通过明确的接口通信。2.2 我们的三层架构┌─────────────────────────────────────────────────────────┐ │ 表 现 层 (Presentation) │ │ main.py │ │ 职责处理用户交互、命令行参数解析、结果展示 │ │ 类比Java Controller / Spring MVC RestController │ └───────────────────────┬─────────────────────────────────┘ │ 调用 ▼ ┌─────────────────────────────────────────────────────────┐ │ 业 务 逻 辑 层 (Business Logic) │ │ agent_builder.py │ │ 职责构建 Agent、编排图节点、管理生命周期 │ │ 类比Java Service / Service │ │ 核心create_react_agent / StateGraph 组装 │ └───────────────────────┬─────────────────────────────────┘ ┌─────────────┼─────────────┐ │ │ │ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ 配置层 │ │ 数据模型层 │ │ 数据访问层 │ │ config.py │ │ models.py │ │ tools.py │ │ 读取 .env │ │ State/TypedDict│ │ 工具函数 │ │ 类比: │ │ Pydantic模型 │ │ 类比: DAO │ │ application │ │ 类比: Entity │ │ 类比: │ │ .yml │ │ / DTO │ │ Repository │ └──────────────┘ └──────────────┘ └──────────────┘2.3 各层的详细说明表现层main.py职责命令行参数解析、步骤调度、用户输入输出设计要点不包含任何 Agent 构建逻辑只调用 Service 层提供的方法结果展示与业务逻辑分离类比 JavaRestControllerRequestMapping业务逻辑层agent_builder.py职责Agent 的构建、配置、编译设计要点提供多个build_xxx()工厂方法不直接处理用户交互依赖下层配置/模型/工具但不依赖上层表现层类比 JavaService 工厂模式关键代码create_react_agent()是 LangGraph 提供的高阶 API内部封装了 StateGraph 的创建、节点连接、条件路由等数据访问层tools.py职责定义 Agent 可以调用的外部工具设计要点每个工具是一个独立的纯函数有明确的类型注解和 docstringLLM 通过 docstring 理解工具用途新增工具只需在此文件添加函数类比 JavaRepository/DAO接口配置层config.py职责集中管理所有外部配置设计要点从.env文件读取配置提供配置校验函数Fail-Fast所有配置常量集中定义一处修改全局生效类比 Javaapplication.ymlConfigurationProperties数据模型层models.py职责定义状态类型、结构化输出模型设计要点AgentState是 LangGraph 图中的数据总线WeatherResponse定义输出格式规范利用 Pydantic 做运行时数据校验类比 JavaEntity/DTO/POJO3. 快速入门六步骤详解步骤 1安装依赖pipinstall-rrequirements.txt安装了什么包名作用类比 JavalanggraphLangGraph 核心框架提供 StateGraph、预构建 Agent 等Spring Frameworklangchain-coreLangChain 核心库提供消息模型、工具接口等Spring Corelangchain-openaiOpenAI 兼容 API 客户端用于调用 DeepSeekHTTP Clientpython-dotenv从.env文件加载环境变量Spring Cloud Configpydantic数据校验和序列化定义结构化输出模型Jakarta Validation为什么需要没有这些依赖我们就无法调用 LLM、无法构建 Agent、无法管理配置。它们是项目运行的基础。步骤 2创建基础 Agent核心代码对应app/agent_builder.py中的build_basic_agent()fromlanggraph.prebuiltimportcreate_react_agent agentcreate_react_agent(modelllm,tools[get_weather],)这段代码做了什么create_react_agent是 LangGraph 提供的预构建 Agent 工厂函数。它在内部完成了以下工作创建StateGraph—— 定义一个状态机添加chatbot节点—— 节点内部调用 LLM处理用户消息添加tools节点—— 节点负责执行 LLM 请求的工具调用添加条件边—— 如果 LLM 生成tool_calls路由到 tools 节点否则直接回复用户编译图—— 将图结构编译为可调用的CompiledGraph整个流程形成一个循环用户输入 → chatbot(LLM) → 需要工具→ 是 → tools → chatbot(LLM) → ... → 否 → 直接回复用户为什么需要这一步这是 LangGraph Agent 的最小可行单元。没有它我们只有孤立的 LLM 调用没有Agent 循环思考→行动→观察→思考…的能力。类比 Java就像 Spring Boot 的SpringBootApplication—— 一行注解背后做了大量的自动配置。步骤 3配置 LLM核心代码对应app/agent_builder.py中的create_default_llm()fromlangchain_openaiimportChatOpenAI llmChatOpenAI(modeldeepseek-v4-flash,api_keysk-...,base_urlhttps://api.deepseek.com,temperature0.0,)关键参数说明参数作用建议值temperature控制输出随机性。0.0 最确定1.0 有创造性Agent 场景用 0.0~0.3model使用的模型名称deepseek-v4-flash / gpt-4 等为什么 DeepSeek 可以用ChatOpenAI因为 DeepSeek 提供了完全兼容 OpenAI 格式的 API 接口所以 LangChain 的ChatOpenAI客户端可以直接使用只需修改base_url即可。为什么需要这一步步骤 2 中的create_react_agent(model...)接受任何符合 LangChain 标准的 LLM 实例。通过单独配置 LLM我们可以精细控制模型参数temperature、max_tokens 等而不用修改 Agent 构建代码。步骤 4添加自定义提示Prompt核心代码对应build_agent_with_prompt()agentcreate_react_agent(modelllm,tools[get_weather],prompt你是一位专业的天气播报员请用中文回复。)prompt 参数的本质传给prompt的字符串会被自动作为System Message插入到对话的开头。System Message 是设定 LLM 行为的最核心手段。为什么需要这一步没有自定义提示LLM 的行为完全由训练数据决定不可控。通过提示我们可以设定角色让 Agent 扮演特定角色天气播报员、客服、导师等约束行为规定回复的语言、长度、风格设定规则规定 Agent 何时调用工具、如何处理特定情况注入知识提供业务上下文和领域知识类比 Java就像在 Spring 中通过Value或application.yml注入配置 —— 把变化的部分从代码中抽离出来让行为可配置。步骤 5添加记忆Memory核心代码对应build_agent_with_memory()fromlanggraph.checkpoint.memoryimportMemorySaver checkpointerMemorySaver()agentcreate_react_agent(modelllm,tools[get_weather],checkpointercheckpointer,)# 调用时传入 thread_idconfig{configurable:{thread_id:user-session-1}}agent.invoke({messages:[...]},config)记忆的工作原理┌──────────────────┐ │ Agent 调用 1 │ │ thread_id1 │──→ 状态自动保存到检查点 └──────────────────┘ │ ┌──────────────────┐ │ Agent 调用 2 │ │ thread_id1 │──→ 加载调用 1 的状态 │ │ 新的用户输入 └──────────────────┘ │ ┌──────────────────┐ │ Agent 调用 3 │ │ thread_id2 │──→ 全新的对话 │ │ 看不到 thread_id1 └──────────────────┘为什么需要这一步没有记忆Agent 每次调用都是失忆的。它无法记住用户之前说过什么多轮对话无法进行。有了记忆Agent 可以记住用户的名字、偏好、上下文可以实现连贯的多轮对话检查点机制不仅存消息还存完整的 Agent 状态包括中间变量类比 Java就像 Web 应用的HttpSession——通过 sessionId即 thread_id在不同请求间共享用户状态。步骤 6配置结构化输出核心代码对应build_structured_agent()# 方式一推荐兼容所有模型通过 Prompt 引导structured_prompt(请严格按以下 JSON 格式返回结果\n{city: 城市名, conditions: 天气状况, temperature: 温度})agentcreate_react_agent(modelllm,tools[get_weather],promptstructured_prompt,)responseagent.invoke({messages:[...]})rawresponse[messages][-1].content datajson.loads(raw)# 解析 JSONprint(data[conditions])# 程序化访问关于response_format参数LangGraph 内置的response_format参数基于 Pydantic 模型依赖于 LLM 提供商对response_format的原生支持。DeepSeek 目前不支持此参数。因此本项目采用Prompt 引导的替代方案兼容所有模型。为什么需要这一步在很多实际场景中Agent 的回复需要被程序而非人类消费需要从回复中提取结构化的数据字段需要将回复传递给下游 API 或数据库需要确保回复格式稳定不随模型版本变化类比 Java就像 Controller 方法上标注ResponseBody—— 明确指定返回的数据格式客户端可以按约定解析。六步骤总览步骤核心概念新增组件解决什么问题1. 安装依赖环境准备requirements.txt没有任何依赖无法运行2. 基础 Agentcreate_react_agentAgent Tool让 LLM 具备思考→行动→观察循环3. 配置 LLM模型参数temperature 等精细控制模型行为4. 自定义提示System Messageprompt 参数设定 Agent 的角色和规则5. 添加记忆CheckpointerMemorySaver实现多轮对话记住用户上下文6. 结构化输出Prompt 引导 JSONSystem Prompt 格式示例让输出格式可控、可解析每个步骤都在前一步的基础上增加了一个新的能力维度从最简单的 LLM 调用逐步演进为一个功能完备的 Agent 系统。3.7 附录关于 DeepSeek JSON Output 的深度解析本节内容补充说明结构化输出在 DeepSeek 模型上的实现细节解释为什么早期步骤4代码会报错以及如何正确使用 DeepSeek 的 JSON Output 功能。3.7.1 报错复现发生了什么当我们最初尝试使用 LangGraph 内置的response_format参数时传入 Pydantic 模型frompydanticimportBaseModelclassWeatherResponse(BaseModel):conditions:stragentcreate_react_agent(modelllm,tools[get_weather],response_formatWeatherResponse,# ← 这行导致了报错)运行后得到如下错误openai.BadRequestError: Error code: 400 {error: {message: This response_format type is unavailable now, type: invalid_request_error, ...}}3.7.2 根本原因分析层面详情直接原因DeepSeek API 返回 HTTP 400提示response_format type不可用技术原因LangGraph 的response_format参数内部调用model.with_structured_output()该方法向 API 发送response_format: {type: json_schema, json_schema: {...}}。DeepSeek 不支持json_schema类型深层原因DeepSeek 的response_format只支持{type: json_object}格式确保输出合法 JSON不支持 OpenAI 的 JSON Schema 格式定义具体字段结构LangGraphresponse_format的调用链路create_react_agent(response_formatWeatherResponse) → model.with_structured_output(WeatherResponse) → 向 API 发送 response_format{type: json_schema, json_schema: {...}} → DeepSeek 不支持 → HTTP 400 ❌3.7.3 解决方案对比我们评估了以下三种方案最终选择了方案一方案原理优点缺点本项目选择① Prompt 引导System Prompt 中要求输出 JSON给出格式示例兼容所有模型零依赖依赖 Prompt 质量偶有格式偏差✅采用② DeepSeek JSON Outputresponse_format{type: json_object}API 参数输出格式可靠与 LangChain 工具 strict 校验冲突⚠ 需配合纯 API 调用③ LangGraph 原生参数传入 Pydantic 模型类型安全自动校验仅部分模型支持❌ DeepSeek 不支持3.7.4 DeepSeek JSON Output 的正确打开方式DeepSeek 官方推荐的 JSON Output 方式是通过 OpenAI 兼容 API 直接调用不通过 LangChain 封装fromopenaiimportOpenAI clientOpenAI(api_keyyour api key,base_urlhttps://api.deepseek.com,)responseclient.chat.completions.create(modeldeepseek-v4-flash,messages[{role:system,content:请以 JSON 格式输出天气信息。},{role:user,content:北京的天气怎么样},],response_format{type:json_object},# ← DeepSeek 原生支持)print(response.choices[0].message.content)# 输出{city: 北京, conditions: 晴朗, temperature: 25°C}关键注意事项Prompt 中必须包含 “json” 字样— DeepSeek API 要求 prompt 中显式出现 “json” 关键字否则可能不会触发 JSON 模式给出格式示例— 提供 Few-shot 示例可以显著提高格式遵从度设置合理的 max_tokens— 防止长 JSON 被截断处理空 content— API 有概率返回空 content需在代码中做防御性处理3.7.5 为什么本项目不直接使用 DeepSeek JSON Output当我们在create_json_llm()中通过model_kwargs启用 JSON Output 时遇到了新的错误ValueError: get_weather is not strict. Only strict function tools can be auto-parsed原因OpenAI Python 客户端在启用response_format后会自动启用工具调用的strict 模式严格参数校验。这要求所有工具函数必须声明为 strict否则客户端拒绝调用。影响在 LangGraph 的create_react_agent框架内工具是通过 LangChain 的 Tool 对象传入的无法简单地为工具标记strictTrue。结论对于 LangGraph DeepSeek 的组合使用场景推荐方式在 LangGraph Agent 内部Prompt 引导方案①直接 API 调用不经过 Agent 框架DeepSeek JSON Output方案②使用 OpenAI / Anthropic 等模型LangGraph 原生response_format方案③3.7.6 代码变更记录版本变更结果初始实现使用response_formatWeatherResponsePydantic 模型❌ HTTP 400第一次修复改用纯 Prompt 引导无 API 参数✅ 可工作但格式偶有不稳第二次尝试启用model_kwargs{response_format: {type: json_object}}❌ strict 工具校验冲突最终方案保留 Prompt 引导 笔记中附 DeepSeek JSON Output 示例✅稳定可靠4. 运行项目4.1 前提条件Python 3.10已配置 API 密钥已填入.env文件4.2 安装依赖cdlanggraph_demo pipinstall-rrequirements.txt4.3 运行全部步骤python main.py程序会按顺序执行四个步骤每步之间会暂停按回车继续。4.4 运行单个步骤python main.py1# 仅运行步骤 1基础 Agentpython main.py2# 仅运行步骤 2自定义提示python main.py3# 仅运行步骤 3带记忆python main.py4# 仅运行步骤 4结构化输出4.5 预期输出示例步骤 1基础 Agent 用户: what is the weather in San Francisco? Agent: ☀️ Its always sunny in San Francisco!步骤 2自定义提示将用户输入进行修改再执行user_messagewhat is the weather in Tokyo?# 修改为user_messagewhat is the weather ?步骤 3带记忆的多轮对话 [第1轮] 用户: 你好我叫张三是一名软件工程师。 [第1轮] Agent: 你好张三很高兴认识你作为一名软件工程师... [第2轮] 用户: 还记得我的名字和职业吗 [第2轮] Agent: 当然记得你是张三是一名软件工程师。...步骤 4结构化输出 JSON Output5. 常见问题与扩展建议5.1 常见问题Q: 为什么用 DeepSeek 而不是 OpenAI/AnthropicA: DeepSeek 提供兼容 OpenAI 格式的 API且在中国大陆可直接访问无需特殊网络环境。使用ChatOpenAI客户端设置base_url即可调用。Q: 如何切换其他模型A: 只需修改.env文件中的三个配置DEEPSEEK_API_KEYyour_new_key DEEPSEEK_BASE_URLhttps://api.another-provider.com DEEPSEEK_MODELmodel-nameQ:create_react_agent和StateGraph有什么区别A:create_react_agent是预构建的高级 API适合标准场景StateGraph是底层 API允许完全自定义图结构。本项目使用前者快速入门进阶后可学习后者。Q: 记忆只能在内存中吗A: 不。本项目使用MemorySaver内存存储方便演示生产环境应使用SqliteSaver、PostgresSaver或自定义检查点器实现持久化存储。5.2 扩展建议从一个快速入门项目到一个可投入生产的系统以下是可以逐步添加的能力更多工具添加搜索工具Tavily、Bing Search添加数据库查询工具添加 API 调用工具更复杂的状态在State中添加自定义字段如用户名、会话元数据使用自定义 reducer 处理状态更新人工在环Human-in-the-Loop使用interrupt()在关键步骤暂停 Agent等待人工审批后再继续执行流式输出使用stream()替代invoke()实现逐 token 输出提供更好的用户体验多 Agent 协作多个 Specialist Agent 各司其职Supervisor Agent 负责任务分发和结果汇总监控与可观测性集成 LangSmith 跟踪调用链监控 token 消耗和响应延迟5.3 安全提醒⚠ API 密钥是敏感信息永远不要提交到 Git 仓库⚠ 本项目使用的 DeepSeek Key 已在对话中明文展示建议使用后立即在 DeepSeek 控制台重置⚠ 生产环境中应使用密钥管理服务如 AWS Secrets Manager、Vault 等总结通过本项目和配套笔记我们完成了一个从零开始的 LangGraph Agent 学习之旅维度从…到…项目结构零散脚本三层架构工程代码组织一个文件配置/模型/工具/业务逻辑分离Agent 能力简单 LLM 调用工具调用 记忆 结构化输出理解深度只知道 create_react_agent知道每一步的原理和必要性这不仅是一个 Demo更是一个可扩展的工程模板。当你需要添加新功能时遵循在哪一层做什么事的原则代码自然保持清晰和可维护。

相关新闻