拓冰建站拓冰建站
首页 / 资讯中心 / 正文

LangChain与通义千问实战:从零构建AI智能体完整指南

1. 项目概述为什么选择LangChain与通义千问最近在折腾AI应用开发的朋友估计没少被“如何让大模型干点实际的、复杂的活儿”这个问题困扰。直接调用模型API写个简单的问答对话还行一旦涉及到多步骤推理、工具调用、或者处理长文档代码复杂度就直线上升维护起来更是头疼。这正是我当初决定深入使用LangChain的原因——它本质上是一个为大型语言模型LLM应用设计的开发框架把那些繁琐的流程比如对话记忆管理、工具集成、文档检索增强生成RAG等都抽象成了可复用的模块。你可以像搭积木一样快速构建出功能强大的AI智能体Agent而不用从零开始造轮子。而通义千问作为国内顶尖的大模型之一其API服务在效果、稳定性和性价比上对于很多中文场景的开发者和企业来说是一个极具吸引力的选择。它不像一些开源模型需要自己准备昂贵的算力去部署也不像某些国外API存在网络延迟或合规风险。将LangChain的灵活框架与通义千问的强大模型能力结合起来就成了一个非常自然且高效的技术选型。这个组合能让你快速搭建起一个具备复杂任务处理能力的智能体无论是做数据分析助手、智能客服还是自动化流程引擎都有了坚实的技术底座。所以这篇内容就是一次彻底的“踩坑”实录。我会手把手带你完成从零开始用LangChain调用通义千问API并构建一个基础智能体的全过程。过程中你会遇到API密钥配置的坑、依赖版本冲突的坑、以及让智能体正确理解和使用工具的坑。别担心我会把每个步骤掰开揉碎不仅告诉你“怎么做”更重点解释“为什么这么做”以及“如果出错了该怎么排查”。目标很简单让你看完就能动手跑通第一个属于你自己的LangChain 通义千问智能体。2. 环境准备与核心依赖安装2.1 Python环境与虚拟环境管理一切开始之前一个干净、独立的Python环境是避免未来无数依赖冲突噩梦的前提。我强烈建议使用conda或venv来创建虚拟环境。如果你使用conda适合管理复杂科学计算环境# 创建一个名为qwen-langchain的新环境指定Python 3.9或3.10LangChain兼容性好 conda create -n qwen-langchain python3.10 conda activate qwen-langchain如果你使用Python自带的venv轻量简洁# 在项目目录下 python -m venv venv # 激活环境 # Windows: venv\Scripts\activate # Linux/Mac: source venv/bin/activate为什么强调Python版本LangChain社区活跃更新快某些新特性可能对Python版本有要求。3.9或3.10是目前最稳定的选择能兼容绝大多数库。激活环境后你的命令行提示符前应该会出现环境名这表示后续的所有操作都隔离在这个“沙箱”里了。2.2 安装LangChain及相关库接下来安装核心的LangChain包。这里有个关键点LangChain的生态分为核心包langchain和社区包langchain-community。从某个版本开始很多第三方集成比如与通义千问的对接被移到了langchain-community中以提高核心包的稳定性。pip install langchain langchain-community仅安装这两个还不够。我们要调用模型需要HTTP客户端要构建智能体需要定义工具。因此我们还需要安装requests虽然langchain-community里可能带了但显式安装更稳妥和langchainhub可选用于拉取预置的智能体配置。pip install requests langchainhub实操心得版本锁定与冲突解决安装后强烈建议执行pip list查看一下关键库的版本例如langchain-core、langchain等。有时最新版可能存在未预见的兼容性问题。如果你在后续步骤中遇到奇怪的错误可以尝试指定稍早的稳定版本安装例如pip install langchain0.1.0 langchain-community0.0.10版本号需要你根据当时的官方发布情况调整。我个人的经验是关注LangChain官方GitHub的Release页面如果当前最新版是“x.y.z”那么“x.y.(z-1)”或“x.(y-1)”的末尾版本通常是相对最稳定的。2.3 获取通义千问API密钥模型能力来自通义千问所以我们需要一个通行证——API Key。你需要前往阿里云官网在“灵积平台”DashScope进行注册和实名认证。这个过程和开通其他云服务类似通常会有免费的额度供开发者试用。登录阿里云进入“灵积模型服务”控制台。在“API-KEY管理”页面你可以创建新的API Key。务必妥善保管这个Key它就像你的密码一旦泄露他人就可以用你的额度调用服务。开通你想要使用的模型服务。对于通义千问常见的有qwen-turbo快速、成本低、qwen-plus能力更强、qwen-max最新最强版本。在控制台找到相应模型点击开通即可。通常免费额度足够完成本篇的所有实验。重要注意事项环境变量存储永远不要将API Key硬编码在脚本中并上传到GitHub等公开平台。最佳实践是使用环境变量。Linux/Mac:export DASHSCOPE_API_KEYyour-api-key-hereWindows (CMD):set DASHSCOPE_API_KEYyour-api-key-hereWindows (PowerShell):$env:DASHSCOPE_API_KEYyour-api-key-here额度监控在控制台定期查看调用量和剩余额度避免意外超支。3. 核心模块解析从模型调用到智能体构建3.1 LangChain的ChatModels与LLMs在LangChain中与模型交互有两个主要抽象LLM和ChatModel。LLM对应基础的文本补全模型输入一段文本输出续写的文本。接口相对简单。ChatModel对应更现代的对话模型如通义千问、GPT输入是一个消息列表List[BaseMessage]每条消息有角色如HumanMessage用户消息AIMessageAI消息SystemMessage系统消息。这更贴合聊天应用的场景。通义千问显然属于ChatModel。在langchain-community中会有对应的ChatDashScope或ChatTongyi类来封装其API调用。我们需要做的就是正确初始化这个类并传入API Key。为什么是消息列表这种设计让多轮对话的管理变得非常直观。你可以轻松构建一个包含系统指令、历史对话和当前问题的消息列表然后交给模型处理模型能基于完整的上下文生成回复。3.2 智能体Agent的核心概念智能体是LangChain中最令人兴奋的部分。你可以把它理解为一个“具备使用工具能力的大模型”。它不再只是回答问题而是可以理解你的复杂指令如“查一下北京今天天气然后告诉我该穿什么衣服”。规划执行步骤先调用天气查询工具再根据温度结果进行穿衣建议推理。调用你为它定义的工具如搜索、计算、数据库查询等。根据工具返回的结果继续思考或给出最终答案。其核心工作流是“思考-行动-观察”的循环。智能体内部有一个“大脑”通常是LLM负责决定每一步该做什么而“工具”就是它的手脚。LangChain提供了多种智能体类型比如ZERO_SHOT_REACT_DESCRIPTION零样本推理最常用、OPENAI_FUNCTIONS适配OpenAI函数调用格式等我们需要选择适合通义千问的一种。3.3 工具Tools的定义与封装工具是智能体能力的扩展。一个工具本质上是一个函数加上一段清晰的描述告诉模型这个工具是干什么的。LangChain提供了Tool类来封装它。例如我们可以定义一个获取当前时间的工具from datetime import datetime from langchain.tools import Tool def get_current_time(format: str %Y-%m-%d %H:%M:%S) - str: 获取当前的日期和时间。 return datetime.now().strftime(format) time_tool Tool( nameget_current_time, funcget_current_time, description当用户询问当前时间、今天日期或类似问题时使用此工具。输入应为空字符串。 )关键点在于description它需要清晰、无歧义因为模型就是靠这段描述来判断在什么情况下该调用这个工具。描述写得好智能体调用工具的准确率会大幅提升。4. 实战步骤构建你的第一个智能体4.1 初始化通义千问ChatModel首先我们导入必要的模块并初始化模型。假设你的API Key已存储在环境变量DASHSCOPE_API_KEY中。import os from langchain_community.chat_models import ChatTongyi from langchain.agents import AgentExecutor, create_react_agent from langchain.tools import Tool from langchain import hub # 从环境变量读取API Key api_key os.getenv(DASHSCOPE_API_KEY) if not api_key: raise ValueError(请设置环境变量 DASHSCOPE_API_KEY) # 初始化通义千问ChatModel # model参数指定模型名称如qwen-turbo, qwen-plus, qwen-max # temperature控制创造性越高回答越随机一般任务设为0.1或0 chat_model ChatTongyi( dashscope_api_keyapi_key, modelqwen-plus, temperature0.1, )这里我们选择了qwen-plus模型并在temperature上设置了较低的值0.1目的是让模型的输出更加确定和稳定适合执行逻辑性强的任务。如果是创意写作可以调高。4.2 创建自定义工具集一个只会对话的模型不是智能体。让我们给它装上“手”和“脚”。我们创建两个简单的工具一个时间工具一个计算器工具。from datetime import datetime import math # 工具1获取当前时间 def get_current_time(format: str %Y-%m-%d %H:%M:%S) - str: 获取当前的日期和时间。输入应为空字符串。 return datetime.now().strftime(format) # 工具2简单计算器支持加、减、乘、除、幂、平方根 def calculator(expression: str) - str: 执行数学计算。支持加减乘除(,-,*,/)、幂运算(**)、平方根(sqrt)。 例如3 5 * 2, sqrt(16), 2 ** 10。 输入是一个数学表达式字符串。 # 安全警告在生产环境中直接eval是危险的此处仅用于演示。 # 真实场景应使用ast.literal_eval或专用数学解析库。 try: # 将sqrt替换为math.sqrt expression expression.replace(sqrt, math.sqrt) # 使用eval计算注意安全性 result eval(expression, {__builtins__: None}, {math: math}) return str(result) except Exception as e: return f计算错误{e} # 使用Tool类封装工具 time_tool Tool( nameCurrentTime, funcget_current_time, description当用户询问当前时间、今天日期、现在几点钟或类似问题时使用此工具。输入参数应为空字符串。 ) calc_tool Tool( nameCalculator, funccalculator, description当用户需要进行数学计算、算术运算或求解数学表达式时使用此工具。输入是一个数学表达式字符串如3 5 * 2或sqrt(25)。 ) # 将工具放入列表供智能体使用 tools [time_tool, calc_tool]注意事项calculator工具中的eval使用在演示代码中为了极简我们使用了eval来解析数学表达式。这在实际生产环境中是极其危险的因为它会执行传入的任何Python代码。如果智能体接收的用户输入不可控恶意用户可能通过精心构造的输入表达式来执行系统命令。安全的做法是使用ast.literal_eval但只能处理常量表达式。使用专门的数学表达式解析库如numexpr。严格限制表达式中允许的字符和函数白名单机制。 本例为了聚焦LangChain集成简化了安全处理你在实际项目中必须重视这一点。4.3 构建ReAct智能体并执行有了模型和工具现在可以组装智能体了。我们将使用ReActReasoning Acting范式这是最经典和通用的智能体类型之一。# 从LangChain Hub拉取一个适用于ReAct范式的提示词模板 # 这个模板定义了智能体如何思考、如何选择工具、如何格式化输出 prompt hub.pull(hwchase17/react-chat) # 创建ReAct智能体 agent create_react_agent( llmchat_model, # 使用我们初始化的通义千问模型 toolstools, # 传入工具列表 promptprompt # 使用ReAct提示模板 ) # 创建智能体执行器它负责运行智能体的循环 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 设为True可以看到智能体详细的思考过程非常重要 handle_parsing_errorsTrue, # 优雅处理模型输出解析错误 max_iterations5, # 限制最大循环次数防止死循环 early_stopping_methodgenerate # 当模型认为该给出最终答案时停止 ) # 现在让我们问智能体一个问题 question “现在几点了顺便帮我计算一下15的平方加上20除以4等于多少。” result agent_executor.invoke({input: question, chat_history: []}) print(result[output])当你运行这段代码并将verbose设为True时你会在控制台看到类似以下的精彩输出 进入新的AgentExecutor链... 思考用户问了两个问题。第一个是当前时间我需要使用CurrentTime工具。第二个是一个数学计算我需要使用Calculator工具。 行动CurrentTime 行动输入 观察2023-10-27 14:30:15 思考我已经得到了当前时间。现在需要计算第二个表达式“15的平方加上20除以4”。这需要Calculator工具。 行动Calculator 行动输入15**2 20/4 观察225 5.0 230.0 思考我得到了两个结果。现在需要将两个信息组合起来回答用户。 最终答案当前时间是2023-10-27 14:30:15。您要求的计算15的平方225加上20除以45结果是230.0。 链结束。这个输出完美展示了智能体的“思考-行动-观察”循环。它先分解问题然后依次调用正确的工具最后综合信息给出答案。4.4 深入解析提示词模板与系统消息智能体的表现很大程度上受提示词Prompt控制。我们上面从Hub拉取的react-chat模板内部已经预设了指导模型如何扮演一个“能使用工具的助手”的指令。但有时我们需要自定义系统指令。你可以直接查看和修改这个提示词print(prompt.template)你会发现模板里包含了类似You are a helpful assistant that can use tools.的系统指令以及如何格式化工具描述、如何展示思考过程的说明。如果你想注入更强的角色设定或规则可以在初始化模型时通过system_message参数传递或者直接修改prompt.template。例如让模型更简洁from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain.schema import SystemMessage system_message SystemMessage(content你是一个高效、精准的助手。请严格使用工具获取信息回答要简洁不要添加额外解释。) human_message {input} prompt ChatPromptTemplate.from_messages([ system_message, MessagesPlaceholder(variable_namechat_history), human_message, ]) # 然后使用这个自定义的prompt去创建agent实操心得提示词工程是关键智能体不按预期调用工具可能是工具描述不够清晰。智能体总在最后啰嗦可能是系统指令没设好。把verboseTrue打开仔细观察模型的“思考”步骤是调试智能体行为最有效的方法。你可以看到模型是如何解读你的问题以及它为什么选择或不选择某个工具。根据观察结果反复调整工具描述description和系统提示直到智能体的行为符合你的预期。5. 高级应用与性能调优5.1 处理复杂任务与多轮对话上面的例子是单次查询。真实的智能体需要支持多轮对话即记住之前的聊天历史。AgentExecutor的invoke方法中的chat_history参数就是用于此目的。你需要将历史消息列表维护起来并每次传入。from langchain.schema import HumanMessage, AIMessage chat_history [] while True: user_input input(你: ) if user_input.lower() in [quit, exit]: break # 调用智能体传入当前输入和历史记录 result agent_executor.invoke({ input: user_input, chat_history: chat_history }) ai_response result[output] print(f助手: {ai_response}) # 更新历史记录 chat_history.append(HumanMessage(contentuser_input)) chat_history.append(AIMessage(contentai_response)) # 可选限制历史记录长度避免上下文过长 if len(chat_history) 10: # 保留最近5轮对话 chat_history chat_history[-10:]这样你就可以和智能体进行连续对话了。它会记住之前的上下文比如你之前问过时间后面再问“那明天这个时候呢”虽然我们没有直接提供“明天”的工具但模型可以利用历史中的“当前时间”信息进行推理和回答尽管可能不精确因为它没有日历工具。5.2 错误处理与智能体稳定性在实际运行中智能体可能会“卡住”或出错。AgentExecutor提供了几个关键参数来提升稳定性max_iterations如前所述限制最大循环次数防止无限思考。handle_parsing_errors当模型输出不符合工具调用格式时这个参数决定是报错还是尝试修复。设为True通常更安全。early_stopping_method设置为generate时当模型输出以“Final Answer:”开头的文本时就会停止循环直接将该文本作为最终答案输出。这依赖于提示词模板的设计。此外你还需要在自己的代码层面对agent_executor.invoke()进行try-except包装捕获可能发生的网络超时、API限额、或意料之外的解析错误并给出友好的用户提示。5.3 扩展工具集连接外部世界两个内置工具显然不够。LangChain-Community提供了大量预构建的工具比如WikipediaQueryRun查询维基百科。ArxivQueryRun搜索学术论文。PubmedQueryRun搜索生物医学文献。RequestsGetTool发送HTTP GET请求谨慎使用有安全风险。你还可以轻松集成任何Python函数。例如连接数据库import sqlite3 from langchain.tools import Tool def query_database(sql_query: str) - str: conn sqlite3.connect(mydatabase.db) cursor conn.cursor() try: cursor.execute(sql_query) results cursor.fetchall() return str(results) except Exception as e: return f查询错误{e} finally: conn.close() db_tool Tool( nameCustomerDatabase, funcquery_database, description用于查询客户订单数据库。输入是一个合法的SQL SELECT查询语句。 )注意事项工具权限管理当你给智能体装上RequestsGetTool或ShellTool执行系统命令这类强大但危险的工具时必须极度谨慎。最好只在完全可控的内部环境中使用并且要对工具的调用进行严格的输入验证和权限控制避免智能体被诱导执行有害操作。5.4 性能优化与成本控制模型选择qwen-turbo响应最快、成本最低适合对实时性要求高、任务简单的场景。qwen-max能力最强但延迟和成本也更高适合需要深度推理的复杂任务。根据业务场景做权衡。缓存对于重复性查询可以使用LangChain的缓存功能如InMemoryCache,SQLiteCache来存储模型响应显著降低API调用次数和成本。from langchain.cache import InMemoryCache from langchain.globals import set_llm_cache set_llm_cache(InMemoryCache())批量处理如果需要处理大量独立问题可以考虑将问题批量发送但注意通义千问API可能对批量调用有特定规范和限制需查阅最新文档。超时与重试网络不稳定时配置合理的超时和重试机制是必须的。这通常在初始化ChatTongyi时通过底层HTTP客户端的参数来设置。6. 常见问题排查与调试技巧即使按照步骤操作你也可能会遇到一些问题。这里记录了几个我踩过的坑和解决方法。问题1导入错误No module named ‘langchain_community’或ChatTongyinot found原因langchain-community包没有安装或者版本太旧。解决确保已正确安装最新版。有时类名可能有变化查阅langchain-community官方文档确认导入路径是否正确。可能是from langchain_community.chat_models.tongyi import ChatTongyi。问题2API调用返回认证错误如Invalid API Key原因API Key未正确设置到环境变量。环境变量未在当前终端生效需要重启终端或source。API Key对应的模型服务未开通。解决在Python代码中直接print(os.getenv(“DASHSCOPE_API_KEY”))检查是否为None。在阿里云控制台确认API Key有效且对应模型如qwen-plus已开通服务。检查代码中初始化ChatTongyi时传入的参数名是否正确可能是api_key而非dashscope_api_key以文档为准。问题3智能体陷入循环不断重复同一个工具调用原因工具描述不清晰模型无法理解工具的作用或输出。工具函数返回的结果格式混乱模型无法解析。max_iterations设置过高且模型无法自行判断任务完成。解决开启verboseTrue这是最重要的调试手段。观察模型的“思考”内容看它是否误解了任务或工具。精炼工具描述确保description字段用最简单明确的语言说明工具的用途、输入格式和输出示例。规范化工具输出确保工具函数返回的是干净、结构化的字符串。避免返回包含多余换行、标记的复杂对象。调整提示词在系统消息中强调“在得到足够信息后请给出最终答案并停止”。降低max_iterations比如设为3强制其尽早结束。问题4模型响应慢或超时原因网络连接问题。使用了qwen-max等重型模型本身延迟较高。提示词或问题过于复杂导致模型生成时间长。解决检查网络连通性。对于实时交互场景换用qwen-turbo。在初始化ChatTongyi时尝试设置streamingTrue以流式获取响应提升用户体验感。优化提示词使其更简洁直接。问题5工具调用格式解析失败Parsing error原因模型的输出不符合LangChain智能体预期的工具调用格式通常是JSON或特定文本块。解决确保handle_parsing_errorsTrue让执行器尝试处理错误。检查使用的prompt模板是否与智能体类型匹配。create_react_agent应搭配ReAct风格的prompt。如果问题持续考虑使用更“听话”的模型如qwen-max在指令遵循上可能更好或者对模型输出进行后处理清洗。调试智能体是一个需要耐心的过程。核心秘诀就是打开verbose日志像侦探一样分析模型的每一步“思考”和“行动”从而定位问题是出在工具定义、提示词还是模型本身的理解上。每一次成功的调试都会让你对智能体工作原理的理解加深一层。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门