尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

LangChain 1.x 快速上手:从核心概念到智能体实战开发指南

LangChain 1.x 快速上手:从核心概念到智能体实战开发指南 1. 项目概述为什么是 LangChain 1.x如果你最近在折腾大语言模型应用开发大概率绕不开 LangChain 这个名字。它就像一个乐高积木箱把 LLM、外部工具、记忆、数据检索这些零散的部件用一套标准化的接口和流程串了起来让你能快速搭建出功能复杂的 AI 应用。从去年开始LangChain 的版本迭代速度飞快社区生态也日益庞大。而 LangChain 1.x 版本在我看来是一个重要的分水岭——它标志着这个框架从早期的“概念验证”阶段正式迈入了“生产就绪”的稳定期。我刚开始接触 LangChain 时还在用 0.0.x 的版本那时 API 变动频繁今天能跑的代码明天可能就报错了文档也常常跟不上代码的变化。这种体验对于想快速上手的开发者来说确实不太友好。但 LangChain 1.x 带来了巨大的改变API 设计更加清晰和一致模块化程度更高官方文档的质量和完整性也大幅提升。更重要的是它引入了像LangGraph这样的新组件来处理更复杂的、有状态的 Agent 工作流这让构建真正智能的、能自主决策的 AI 体成为了可能。所以这篇“快速上手”的目的不是带你通读一遍官方文档而是以一个过来人的视角帮你跳过那些我踩过的坑直接抓住 LangChain 1.x 的核心脉络。我们会从最基础的安装和环境配置开始一步步搭建起一个能实际运行的、具备基础对话和工具调用能力的智能体并在这个过程中理解其背后的设计哲学和关键组件。无论你是想做一个自动化的客服机器人、一个能联网搜索的问答助手还是一个能分析私有文档的知识库应用LangChain 1.x 都是你目前最值得投入时间学习的工具之一。2. 环境准备与核心概念扫盲在动手写代码之前把环境搭好、把核心概念理清能让你后续的学习事半功倍。很多人一上来就复制粘贴代码结果遇到各种依赖报错或者概念混淆反而浪费了更多时间。2.1 Python 环境与依赖安装首先确保你有一个干净的 Python 环境。我强烈建议使用conda或venv创建独立的虚拟环境这能避免不同项目间的包版本冲突。这里以venv为例# 创建并激活虚拟环境 python -m venv langchain-env # Windows langchain-env\Scripts\activate # macOS/Linux source langchain-env/bin/activate激活环境后安装 LangChain。注意我们安装的是langchain核心包以及langchain-community后者包含了大量由社区维护的第三方集成如各种数据库、工具等。pip install langchain langchain-community一个关键的注意事项LangChain 本身不包含大语言模型。你需要额外安装对应模型供应商的 SDK。例如如果你想使用 OpenAI 的模型需要安装openai如果想用 Anthropic 的 Claude需要安装anthropic。这里我们以 OpenAI 为例因为它目前生态最成熟示例也最多pip install openai安装完成后别忘了设置你的 API 密钥。永远不要将密钥硬编码在代码中提交到版本控制系统。最佳实践是使用环境变量# 在终端中设置临时 export OPENAI_API_KEYyour-api-key-here # 或者在代码中读取环境变量推荐 import os from langchain_openai import ChatOpenAI llm ChatOpenAI(api_keyos.getenv(OPENAI_API_KEY))2.2 理解 LangChain 1.x 的核心抽象LangChain 1.x 的架构围绕几个核心抽象构建理解它们就等于拿到了框架的“地图”。模型 I/O (Model I/O)这是与 LLM 交互的基础层。主要包括LLMs纯文本补全模型如text-davinci-003输入文本输出文本。Chat Models对话模型如gpt-4,gpt-3.5-turbo输入的是消息列表SystemMessage,HumanMessage,AIMessage输出的是AIMessage。这是目前最主流的交互方式。Embeddings将文本转换为向量数字列表的模型用于检索、聚类等任务。提示词 (Prompts)管理 LLM 输入的模板。LangChain 提供了PromptTemplate、ChatPromptTemplate等工具让你能动态地构建提示词比如把用户问题、上下文信息填充到预设的模板里。输出解析器 (Output Parsers)将 LLM 的非结构化文本输出解析成你程序里可以使用的结构化数据比如 JSON、Pydantic 模型对象或者一个简单的列表。链 (Chains)这是 LangChain 早期的核心。一个“链”将多个组件模型、提示词、工具等按预定顺序组合在一起完成一个特定任务。例如一个检索问答链RetrievalQA会先检索相关文档然后把文档和问题一起塞给 LLM 生成答案。在 1.x 版本中虽然Agent和LangGraph更强大但Chain对于简单的线性流程依然简单有效。检索器 (Retrievers)从知识库如向量数据库中获取相关文档的组件。它是构建 RAG检索增强生成应用的核心。智能体 (Agents)这是 LangChain 1.x 的亮点。一个智能体包含一个 LLM 核心和一个它可用的工具列表Tools。LLM 根据用户的目标自主决定是否调用工具、调用哪个工具、以及如何解释工具的返回结果。智能体让应用从“被动回答”变成了“主动执行”。工具 (Tools)智能体可以调用的函数。它可以是一个简单的计算器一个搜索引擎的封装一个数据库查询接口或者任何你能用 Python 函数定义的操作。tool装饰器让创建工具变得极其简单。记忆 (Memory)让链或智能体在多次交互中记住上下文。可以是简单的对话缓冲区也可以是更复杂的、基于向量存储的长期记忆。LangGraph这是 1.x 版本引入的、用于构建有状态、多步骤工作流的新库。它用“图”的概念来定义节点步骤和边流转条件特别适合构建复杂的、需要循环或分支的智能体。你可以把它看作是Chain和Agent的超级升级版用于处理更复杂的业务逻辑。理清了这些概念我们就能明白学习 LangChain 1.x本质上就是学习如何将这些“乐高积木”以不同的方式组合起来解决实际问题。接下来我们就从最简单的“链”开始逐步搭建更复杂的智能体。3. 从链到智能体核心组件实战理论说再多不如一行代码。让我们通过三个逐渐进阶的示例来感受 LangChain 1.x 的威力。我们会从最简单的对话链开始然后创建一个能使用工具的智能体最后再窥探一下更强大的LangGraph。3.1 构建你的第一个对话链我们先来实现一个最简单的功能让 LLM 用指定的风格回答问题。这需要用到Chat Model、Prompt Template和Chain。from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser # 1. 定义模型 llm ChatOpenAI(modelgpt-3.5-turbo) # 2. 定义提示词模板 prompt ChatPromptTemplate.from_messages([ (system, 你是一个{style}风格的助手。), (user, {input}) ]) # 3. 定义输出解析器这里简单地将 AIMessage 转为字符串 output_parser StrOutputParser() # 4. 组装成链prompt - llm - output_parser chain prompt | llm | output_parser # 5. 调用链 response chain.invoke({style: 莎士比亚戏剧, input: 今天的天气怎么样}) print(response)运行这段代码你可能会得到类似这样的回答“尊贵的先生今日之苍穹乃一幅由阳光与云朵共绘的画卷微风轻拂恰似自然之和鸣...”这里发生了什么|操作符是 LangChain 1.x 引入的、用于连接组件的语法糖非常直观。它表示数据流的方向。invoke方法是触发链执行的标准方式输入一个字典字典的键对应提示词模板中的变量。这个链是线性的、确定的模板填充 - 调用模型 - 解析输出。实操心得一开始你可能会觉得多此一举直接用openaiSDK 调用不更简单吗但在复杂应用中这种模块化的优势就体现出来了。当你需要切换模型比如从 OpenAI 换成 Claude只需要换掉llm这一行当你需要修改提示词也只需要改动prompt部分。这种解耦让代码更易维护和测试。3.2 创建你的第一个智能体链是线性的而智能体是“有大脑”的。它能根据你的指令自己决定要不要用工具、用什么工具。我们来创建一个能进行简单数学计算和查询当前日期的智能体。首先我们需要定义几个工具from langchain.agents import tool from datetime import datetime # 使用 tool 装饰器快速创建工具 tool def multiply(a: int, b: int) - int: 将两个数字相乘。 return a * b tool def get_current_date() - str: 获取当前日期年-月-日。 return datetime.now().strftime(%Y-%m-%d) # 将工具放入列表 tools [multiply, get_current_date]接下来我们需要一个“大脑”即 LLM并且要让它知道这些工具的存在。LangChain 提供了create_react_agent这个高级函数来简化智能体的创建。ReAct 是一种经典的智能体推理框架让模型能进行“思考Reason”和“行动Act”的循环。from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain_core.prompts import PromptTemplate # 1. 定义模型 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 2. 使用 ReAct 框架的默认提示词 # LangChain 内置了针对不同 Agent 类型的提示词这里我们使用一个通用的 ReAct 提示词作为示例基础。 # 在实际项目中你可能需要根据工具描述微调提示词。 react_prompt PromptTemplate.from_template( 请回答以下问题。你可以使用以下工具 {tools} 使用以下格式 问题你需要回答的问题 思考你需要思考做什么以及是否使用工具 行动要使用的工具必须是以下之一[{tool_names}] 行动输入工具的输入必须是一个有效的JSON字符串 观察工具返回的结果 ...这个思考/行动/观察循环可以重复多次 最终答案当你知道了最终答案时用它来回答原始问题 开始 问题{input} 思考 ) # 3. 创建智能体 agent create_react_agent(llm, tools, react_prompt) # 4. 创建执行器它负责运行智能体的思考循环并处理工具调用 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) # 5. 运行智能体 result agent_executor.invoke({input: 请问123乘以456等于多少另外今天是几号}) print(result[output])当你运行这段代码并将verbose设为True时你会在控制台看到智能体完整的思考过程 进入新的 AgentExecutor 链... 思考用户问了两个问题一个乘法计算一个查询日期。我有乘法工具和获取日期工具。我应该先回答乘法问题。 行动multiply 行动输入{a: 123, b: 456} 观察56088 思考我已经得到了乘法的结果。现在需要回答日期问题。 行动get_current_date 行动输入{} 观察2024-05-27 思考我现在有了所有答案。 最终答案123乘以456等于56088。今天是2024年5月27日。这个过程的精妙之处在于模型并没有被直接编程去调用某个工具。它“阅读”了工具的描述将两个数字相乘。理解了你的问题然后自主生成了一个符合格式的“行动”指令multiply和输入参数{a: 123, b: 456}。AgentExecutor捕获到这个指令就去调用对应的multiply函数并将结果作为“观察”返回给模型。模型根据观察结果决定下一步是继续行动还是给出最终答案。注意事项temperature0对于工具调用这类需要精确性的任务通常将温度设为0以减少随机性使智能体的行为更可预测。handle_parsing_errorsTrue这很重要。当模型输出的“行动”指令格式不对无法解析时这个参数会让执行器尝试修复错误而不是直接崩溃。工具描述至关重要模型完全依靠函数文档字符串...来理解工具的功能。清晰、准确的描述是智能体正确使用工具的前提。你可以把工具描述写得非常详细包括参数的格式和示例。3.3 初探 LangGraph构建有状态的工作流Chain和基础Agent对于许多任务已经足够但当你需要处理需要循环、条件分支或多角色协作的复杂流程时LangGraph就派上用场了。它让你能用“图”来可视化你的应用逻辑。假设我们要构建一个简单的“审批智能体”用户提交一个请求智能体先判断请求类型如果是“请假”则模拟一个审批流程可能需要多次修改如果是“查询”则直接回答。from typing import Literal from langgraph.graph import StateGraph, END from langchain_core.messages import HumanMessage from langchain_openai import ChatOpenAI # 1. 定义状态State # 在LangGraph中状态是一个字典在节点间传递。我们定义一个简单的状态类。 from typing import TypedDict, Annotated import operator class AgentState(TypedDict): messages: Annotated[list, operator.add] # 消息历史会自动追加 request_type: str # 请求类型 request_detail: str # 请求详情 approved: bool # 是否批准 # 2. 定义节点函数Nodes def router(state: AgentState) - Literal[leave_process, query_process]: 路由节点根据用户输入判断流程分支 user_input state[messages][-1].content if 请假 in user_input: state[request_type] leave state[request_detail] user_input return leave_process else: state[request_type] query return query_process def leave_approval_node(state: AgentState) - AgentState: 请假审批节点简化版直接模拟审批 # 这里可以接入真正的审批逻辑或工具 print(f正在处理请假申请{state[request_detail]}) # 模拟一个简单的审批规则如果请假天数小于3天则批准 if 3天 in state[request_detail] or 两天 in state[request_detail] or 1天 in state[request_detail]: state[approved] True response 您的请假申请已自动批准。 else: state[approved] False response 您的请假申请超过3天需要人工审批已转交主管。 state[messages].append(HumanMessage(contentresponse)) return state def query_node(state: AgentState) - AgentState: 查询处理节点 llm ChatOpenAI(modelgpt-3.5-turbo) user_query state[messages][-1].content # 这里简单调用LLM回答 ai_response llm.invoke([HumanMessage(contentf请回答以下问题{user_query})]) state[messages].append(ai_response) return state # 3. 构建图Graph workflow StateGraph(AgentState) # 添加节点 workflow.add_node(router, router) workflow.add_node(leave_approval, leave_approval_node) workflow.add_node(answer_query, query_node) # 设置入口点 workflow.set_entry_point(router) # 根据路由结果创建边 workflow.add_conditional_edges( router, lambda x: x, # 返回 router 函数的结果 { leave_process: leave_approval, query_process: answer_query, } ) # 从处理节点连接到结束 workflow.add_edge(leave_approval, END) workflow.add_edge(answer_query, END) # 编译图 app workflow.compile() # 4. 运行图 # 模拟一个请假请求 initial_state AgentState(messages[HumanMessage(content我想请假2天因为家里有事。)], request_type, request_detail, approvedNone) result app.invoke(initial_state) print(最终消息:, result[messages][-1].content) print(审批结果:, result.get(approved))这个例子虽然简单但展示了LangGraph的核心思想状态和可控流。整个工作流的状态消息、请求类型、审批结果在图中的节点间传递和修改。router节点像一个调度中心根据输入决定下一步走哪条分支。这使得构建复杂的、非线性的业务逻辑变得清晰和可维护。实操心得对于简单的线性任务用Chain对于需要LLM自主决定调用工具的用Agent而对于业务流程清晰、包含多个步骤和分支的复杂应用如客服工单处理、复杂数据分析流水线LangGraph是更好的选择。它把“业务逻辑”从“提示词工程”中部分分离了出来让代码更易于调试和扩展。4. 避坑指南与性能优化在实际项目中直接使用上面的示例代码可能会遇到各种问题。下面分享一些我踩过坑后总结的经验。4.1 智能体不按预期调用工具这是新手最常见的问题。智能体要么乱调用工具要么死活不调用。问题根因提示词Prompt不匹配你使用的提示词模板可能与你选择的 Agent 类型如 ReAct, OpenAI Tools不兼容。不同的 Agent 类型期望不同的输入输出格式。工具描述不清LLM 完全依赖工具函数的文档字符串docstring来理解工具。模糊的描述如“处理数据”会导致模型困惑。LLM 能力不足过于简单的模型如某些小参数模型可能无法很好地理解复杂指令和工具描述导致推理错误。温度Temperature过高过高的temperature会增加输出的随机性可能导致工具调用指令格式错误或逻辑混乱。排查与解决开启详细日志创建AgentExecutor时务必设置verboseTrue。这是最重要的调试手段你能看到模型完整的“思考”和“行动”过程。检查并优化工具描述将工具描述写得像给一个新手程序员看的 API 文档。明确功能、输入参数的类型和含义、输出是什么。例如将“处理数据”改为“根据用户ID从数据库查询该用户最近30天的订单总额并返回一个浮点数”。使用正确的 Agent 类型LangChain 提供了多种预设的 Agent 类型。对于工具调用create_openai_tools_agent如果使用 GPT 系列通常是兼容性最好的因为它直接使用 OpenAI 的 Function Calling 功能。create_react_agent更通用但提示词需要精心设计。调整温度和模型对于工具调用任务将temperature设为 0 或接近 0如 0.1。如果问题依旧考虑升级到更强大的模型如从gpt-3.5-turbo切换到gpt-4。提供少量示例Few-Shot在提示词中提供一两个工具调用的成功示例能极大地引导模型的行为。这可以通过自定义PromptTemplate来实现。4.2 处理解析错误和超时智能体在运行中可能会因为模型输出格式错误、网络问题或工具执行时间过长而失败。解析错误当模型输出的“行动”指令不是合法的 JSON 或格式不对时AgentExecutor会抛出解析错误。解决方案在创建AgentExecutor时设置handle_parsing_errorsTrue。这个参数会让执行器尝试用 LLM 去修复格式错误的输出通常能挽救大多数情况。你也可以定义一个自定义的错误处理回调函数。超时问题LLM 调用超时网络不稳定或模型响应慢。可以在初始化ChatOpenAI时设置timeout和max_retries参数。llm ChatOpenAI(modelgpt-3.5-turbo, timeout30.0, max_retries2)工具执行超时如果某个工具如一个网络请求执行时间过长会拖垮整个智能体。解决方案为工具函数内部添加超时逻辑或者使用asyncio等异步机制。对于AgentExecutor目前没有全局的工具超时设置需要在工具实现层面自己控制。4.3 管理上下文与记忆在多轮对话中智能体需要记住之前的交流内容。简单记忆ConversationBufferMemory可以将之前的对话历史全部保存在内存中并作为上下文传递给下一轮。但注意这可能会很快耗尽模型的上下文窗口。from langchain.memory import ConversationBufferMemory memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # 在创建 AgentExecutor 时传入 memory 参数 agent_executor AgentExecutor(agentagent, toolstools, memorymemory, verboseTrue)更优策略摘要记忆使用ConversationSummaryMemory它让 LLM 定期总结之前的对话只保留摘要从而节省令牌。向量存储记忆使用ConversationVectorStoreMemory将历史对话存入向量数据库每次只检索与当前问题最相关的几条历史记录。这适合长期、大量的对话历史管理。自定义记忆逻辑对于复杂场景你可能需要自己管理记忆。例如只记住工具调用的结果而不记住所有的闲聊。一个重要的经验不是所有对话都需要记忆。对于一次性的任务型智能体如数据分析助手关闭记忆可能更合适避免无关历史信息的干扰。仔细设计你的记忆策略是构建稳定智能体的关键一步。4.4 成本与性能优化频繁调用 LLM 和工具会产生成本尤其是使用 GPT-4和延迟。缓存对相同的提示词进行缓存可以大幅减少重复调用。LangChain 支持InMemoryCache、SQLiteCache等。from langchain.globals import set_llm_cache from langchain.cache import InMemoryCache set_llm_cache(InMemoryCache())流式传输对于生成长文本的环节使用流式响应stream可以提升用户体验让用户看到逐步生成的过程而不是长时间等待。for chunk in agent_executor.stream({input: 请写一篇短文}): print(chunk, end, flushTrue)限制工具调用次数防止智能体陷入无休止的“思考-行动”循环。可以在AgentExecutor中设置max_iterations和max_execution_time参数。agent_executor AgentExecutor(agentagent, toolstools, max_iterations5, max_execution_time30.0, verboseTrue)选择性价比模型在原型阶段或处理简单任务时使用gpt-3.5-turbo。仅在需要更强推理和指令遵循能力时如复杂规划、代码生成才使用gpt-4。也可以评估 Claude、DeepSeek 等替代模型。5. 项目实战构建一个联网搜索智能体让我们综合运用所学构建一个真正有用的智能体一个可以联网搜索最新信息并综合回答的助手。我们将使用SerpAPI一个搜索引擎 API作为工具。5.1 准备工作首先安装必要的包并获取 API 密钥注册SerpAPI或其他搜索引擎 API如 Tavily并获取密钥。安装集成包pip install langchain-community5.2 代码实现import os from langchain.agents import create_react_agent, AgentExecutor from langchain_openai import ChatOpenAI from langchain_community.tools import SerpAPIWrapper from langchain_core.prompts import PromptTemplate # 设置API密钥 os.environ[SERPAPI_API_KEY] your-serpapi-key os.environ[OPENAI_API_KEY] your-openai-key # 1. 初始化工具 # SerpAPIWrapper 已经是一个封装好的 Tool 对象 search SerpAPIWrapper() tools [search] # 2. 初始化LLM llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 3. 设计提示词 - 这里我们创建一个更强调搜索的提示词 agent_prompt PromptTemplate.from_template( 你是一个有帮助的助手可以访问互联网来获取最新信息。当你被问到需要实时或最新数据的问题时例如新闻、股价、天气、体育比分、特定事件你应该使用搜索工具。 对于其他常识性或不需要最新信息的问题请直接回答。 你有权使用以下工具 {tools} 严格使用以下格式 问题用户输入的问题 思考你需要思考是否需要搜索。如果需要解释为什么。 行动要使用的工具名必须是以下之一[{tool_names}]。如果不需要搜索就写“无”。 行动输入工具的输入。如果行动是“无”就写“无”。 观察工具返回的结果或者你的直接回答。 ... (这个循环可以重复) 最终答案基于所有观察给出最终的回答。 开始 问题{input} 思考 ) # 4. 创建智能体和执行器 agent create_react_agent(llm, tools, agent_prompt) agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue, max_iterations3) # 5. 运行测试 questions [ 2024年巴黎奥运会开幕式是哪一天, 请解释一下量子计算的基本原理。, 特斯拉TSLA股票现在的价格是多少 ] for q in questions: print(f\n\n用户问题{q}) print(- * 50) try: result agent_executor.invoke({input: q}) print(f\n助手回答{result[output]}) except Exception as e: print(f执行出错{e})5.3 代码解析与优化点工具集成SerpAPIWrapper是langchain-community提供的预封装工具开箱即用。这展示了 LangChain 生态的优势很多常用服务都有现成的集成。提示词工程我们修改了提示词明确指令智能体在需要“实时或最新数据”时才进行搜索对于常识问题则直接回答。这可以减少不必要的 API 调用节省成本和时间。迭代限制设置了max_iterations3防止智能体因为一个模糊的问题而陷入搜索循环。错误处理用try-except包裹执行过程避免单个问题导致整个程序崩溃。可能遇到的问题与进阶优化搜索结果质量SerpAPI 返回的是原始搜索结果片段可能信息冗余或不准确。你可以编写一个后处理工具让另一个 LLM 调用去总结和提炼搜索结果再将精炼后的信息交给主智能体。这就构成了一个多步骤的LangGraph工作流。多工具协作除了搜索你还可以加入计算器、维基百科查询、数据库查询等工具。智能体会根据问题自主选择组合使用。记忆集成为这个智能体加上ConversationBufferWindowMemory只保留最近 K 轮对话它就能进行连贯的多轮对话比如“刚才你提到的那个新闻具体发生在哪里”构建这个联网搜索智能体你已经摸到了 AI 应用开发的门道LLM 作为“大脑”负责理解和规划外部工具作为“手脚”负责获取信息和执行操作而 LangChain 则是协调这一切的“神经系统”。从这里的起点出发你可以继续扩展工具集设计更复杂的工作流最终打造出能够解决特定领域复杂问题的强大 AI 应用。记住迭代和测试是关键不断根据智能体的实际表现去调整提示词、工具描述和工作流程才能让它越来越聪明、越来越可靠。
返回列表