尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Anaconda虚拟环境+LangGraph:从零搭建AI Agent开发环境

Anaconda虚拟环境+LangGraph:从零搭建AI Agent开发环境 最近不少读者来问我同一个问题想试着做点 LangGraph 的 AI Agent 项目结果第一步装环境就劝退了。有的是 Python 版本乱成一锅粥装这个包把那个包搞崩了有的是项目文件散落得到处都是换台电脑直接跑不起来。折腾一晚上正事一点没干成。这篇就是我自己的标准实操流程用 Anaconda 部署 Python 虚拟环境然后在这个干干净净的隔离环境里创建 LangGraph 项目。这串操作解决的是最基础也最要命的问题——环境混乱和依赖冲突。不管你是刚接触 Python 的新手还是已经在写爬虫、做数据分析但想往 Agent 方向拓展的老手这套流程都能直接复用。读完你会得到一个随时能跑、坏了随时重来的标准开发环境以及一个真正能运行起来的 LangGraph 示例项目。1. 为什么用 Anaconda 来管理项目环境1.1 虚拟环境到底解决了什么麻烦先不急着敲命令先把思路理清楚。Python 开发里最烦人的一件事就是项目 A 要用 Flask 2.x项目 B 要用 Flask 3.x如果都装在一个全局环境里必然会互相覆盖。之前有位读者做爬虫项目装某个新库时 pip 自动把 requests 从 2.28 升到了 2.31结果原来能跑的脚本突然开始超时查了一整天最后发现是依赖版本变化导致的兼容性问题。这就是典型的环境污染。虚拟环境的本质很简单每个项目单独开辟一块依赖空间A 项目里的 Flask 2.x 和 B 项目里的 Flask 3.x 互不干扰。Anaconda 自带的 conda 工具除了能创建隔离环境还能管理 Python 版本本身。同一个系统上大的项目用 Python 3.10小的项目用 Python 3.12完全靠 conda 切换不会撞车。这一点在做 LangGraph 这类要装很多依赖的 AI 项目时尤其重要—— LangChain 生态更新极快依赖关系错综复杂稍有不慎就出现版本冲突。另外Anaconda 自带科学计算全家桶NumPy、Pandas、matplotlib 都是预装好的做数据和 AI 方向的项目能省不少安装时间。1.2 和 venv、uv 这些工具怎么选Python 官方其实自带了一个虚拟环境工具叫 venv很多人也用过。venv 的优点是轻量、随 Python 附带但它的毛病是只管 Python 包不管 Python 版本本身。假设系统里只有 Python 3.9venv 能创建的也只是基于 3.9 的环境没法凭空变出一个 3.11 来。而 conda 是一个跨语言的包管理器Python 解释器本身就是它管理的一个包所以 conda 可以创建任意指定版本的 Python 环境。另外这两年很流行的 uv 做环境管理和依赖解析速度飞快处理纯 Python 包依赖体验非常好但如果要管理不同版本的 Python 解释器还是得配合工具来下载。对于大多数读者来说Anaconda 的 conda 入口最省心—— Python 版本、包依赖、虚拟环境三个问题一次解决和 LangGraph 生态的安装文档也贴合得很紧密。我自己的选择是日常快速实验用 uv正经项目开发统一走 conda因为这多团队协作时环境文件导出和执行最标准。2. Anaconda 安装实操与镜像加速2.1 下载安装时那几个容易踩的坑Anaconda 的安装本身不复杂但有几个细节不注意后面会反复被折磨。第一是版本选择。打开官网下载页面时注意选 Python 3.x 对应版本的安装包现在的新版本内置 Python 3.11 或 3.12不要贪图某些教程里的 Python 2.7 老古董LangGraph 这类新框架从不支持旧版 Python。第二是安装路径。Windows 上安装时千万不要把路径写成C:\Program Files\Anaconda3带空格和中文的路径会引发各种莫名其妙的库加载问题。建议直接放在D:\Anaconda3或C:\Anaconda3这种纯英文且无空格的路径。第三是环境变量。安装过程有一个 Add Anaconda3 to my PATH environment variable 的选项。老版本默认不推荐勾选很多教程也照抄说不勾结果终端里敲 conda 提示找不到命令。新版本安装时也有个 Register Anaconda3 as my default Python 选项我也不建议在没搞清楚原理的情况下乱勾。最稳妥的方式是安装完成后如果终端不认识 conda 命令手动在 PATH 里加上 Anaconda3 和 Anaconda3\Scripts 两个路径或者用 Anaconda Prompt 这个自带终端。安装完成后建议打开终端执行一次conda --version。如果能看到版本号说明安装是通的后面所有命令都好使。2.2 配置镜像源来提速Anaconda 官方源在国外国内环境下动不动就下载到一半断掉几十 KB/s 的速度看着都着急。解决办法是切换成国内镜像源。以清华源为例在终端依次执行以下命令conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ conda config --set show_channel_urls yes配置完之后可以通过conda config --show channels查看当前的 channel 列表。一般有三个以上渠道就够了不用全部塞进去。除了 conda 源pip 的源也建议一起配了。因为在虚拟环境内装 LangGraph 时很多时候用的还是 pip 命令。Windows 用户在用户目录下新建pip.iniLinux/Mac 用户新建pip.conf[global] index-url https://pypi.tuna.tsinghua.edu.cn/simple trusted-host pypi.tuna.tsinghua.edu.cn或者直接执行这一条命令也能生效pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple配完这两个源后面创建虚拟环境和安装 LangGraph 的速度会有肉眼可见的提升强烈建议在正式开始前先花两分钟做完这一步。3. 用 conda 创建和管理 Python 虚拟环境3.1 创建指定版本的虚拟环境Anaconda 装完之后自带一个基础环境叫base。我强烈建议不要在 base 环境里搞任何项目开发。base 相当于系统的干净底盘装太多乱七八糟的包最后环境崩了想恢复很麻烦。任何项目都应该单独建一个环境。创建 LangGraph 项目的专用环境命令如下conda create -n langgraph-env python3.11 -y我来拆解一下每个参数的含义-n是指定环境名字这里叫langgraph-env你可以根据项目名来起比如agent-dev、langgraph-dev都行python3.11是指定环境的 Python 版本-y表示遇到确认提示时自动选 yes不用手动敲。为什么选 Python 3.11 而不是最新的 3.12 或 3.13这一点很多教程不会写清楚。LangGraph 和 LangChain 生态依赖很多底层 C 扩展包比如 tokenizers、pydantic-core 这类它们的预编译 wheel 轮子包对新版本 Python 的跟进有延迟。目前测试下来3.11 的兼容性最稳3.12 也可以3.13 偶尔会遇到某个包还在编译源码导致安装失败。对于新项目3.11 是当下最不会出错的档位。等命令执行完可以查看环境列表确认创建成功conda env list输出结果里会看到base和langgraph-env两条记录langgraph-env那一行前面的 * 号代表当前激活的环境。3.2 激活、退出和删除环境的正确姿势创建好环境之后第一步是激活它。Windows 用户在终端里执行conda activate langgraph-envLinux 和 macOS 用户也可以用同样的命令。激活成功之后终端提示符前面会多出一个(langgraph-env)前缀这时候当前终端里的所有 python 和 pip 命令都指向这个隔离环境和系统全局环境彻底脱钩。退出环境用conda deactivate删除某个不再需要的环境用conda env remove -n langgraph-env注意这里有个常见的坑conda 官方推荐用conda env remove但有些老教程写的是conda remove -n langgraph-env --all两者效果其实一样。如果环境已经被激活最好先deactivate再删。还有一个实用技巧是复制环境。之前我有个项目跑得好好的另一个项目想用同一套依赖做二次开发直接用conda create -n new-env --clone old-env就能完整复制一份比重新装省事太多。常用命令我整理了一张表方便随时查阅操作命令创建环境conda create -n env-name python3.11 -y查看所有环境conda env list激活环境conda activate env-name退出环境conda deactivate删除环境conda env remove -n env-name复制环境conda create -n new-env --clone old-env导出环境配置conda env export environment.yml3.3 环境迁移和复用的小技巧很多读者后面会遇到一个问题在本地环境调通了要不要把整个项目打包给同事还是复现到服务器上最专业也最省事的方法是把环境配置导出成一个文件让目标机器按文件重建环境而不是直接把整个环境文件夹复制过去。conda env export environment.yml可以导出当前环境的完整配置包括 pip 安装的包。这个文件适合在同操作系统之间迁移跨平台时可能遇到部分包版本对不上的情况。另一个轻量的方案是生成的requirements.txt文件只记录 Python 包名字和版本号兼容性更好。pip freeze requirements.txt在另一台机器上重建环境时先创建虚拟环境然后激活再执行pip install -r requirements.txt即可。如果目标机器完全没有外网也可以提前在有网络的电脑上下载 wheel 包然后拷贝过去统一安装这是离线环境搭建的标准做法。提示导出的 environment.yml 文件里会包含当前系统的绝对路径信息提交到 Git 仓库或者发给别人之前建议手动检查一下把带本机路径的行清理掉。这算是我踩过的一个坑。4. 在虚拟环境内安装 LangGraph4.1 明确 LangGraph 与 LangChain 的关系装包之前有必要把框架之间的关系捋清楚。LangChain 和 LangGraph 这两个项目虽然都出自同一团队但定位完全不同。LangChain 是面向 LLM 应用的工具链提供各种大模型接口的封装、提示词模板、文档加载器等组件解决了“怎么和模型对话”“怎么处理文档”这类问题。而 LangGraph 解决的是另一个问题当一个任务需要多个步骤协作完成时比如先搜索资料、再分析、再总结或者模型需要反复调用工具直到得出结果这时候流程是带循环和条件分支的普通的链式调用写起来特别费劲。LangGraph 的核心思想是把任务编排成一张有向图节点是具体操作边是流转条件整体状态由一份 State 对象维护。通俗理解LangChain 是一堆零件LangGraph 是流水线的控制框架两者经常搭配使用。为什么现在聊 Agent 开发绕不开 LangGraph因为 Agent 的本质是要模型自己判断下一步做什么甚至反复尝试这天然就是一张图。早期用 LangChain 写 Agent 时高层接口封装得死想改一个判断逻辑都很难下手LangGraph 把控制权完全交还给了开发者节点和边的定义都是显式的调试起来非常直观。4.2 安装 LangGraph 和模型接入依赖现在回到虚拟环境里。确保当前环境是langgraph-env然后执行安装pip install langgraph langchain-core langchain-openai如果用的是国内大模型服务比如想接 DeepSeek可以再装一个适当的第三方集成包pip install langchain-deepseek这些都是纯 Python 包直接用 pip 安装即可不需要用 conda 去指定特定频道。不过要留意的是不要在同一环境里混用 conda 装一个包、pip 装另一个同功能的包这两个工具管理依赖的方式不一样混用可能导致包版本互相覆盖且难以排查。我的习惯是环境本身和需编译的底层包用 conda 管理纯 Python 项目依赖统一用 pip 管理。装完之后验证一下是否成功python -c import langgraph; print(langgraph.__version__)如果能正常输出版本号说明安装成功。如果提示ModuleNotFoundError说明当前终端可能没有激活虚拟环境或者 pip 装到了别的环境里。这种问题非常普遍八成不是安装流程出错而是环境没激活对。4.3 把当前依赖情况保存下来LangGraph 生态迭代速度极快今天装的版本可能下周就升级了。为了项目可复现建议在把项目跑通后第一时间把依赖锁定pip freeze requirements-lock.txt这个文件会记录所有包的精确版本比如langgraph0.2.x、langchain-core0.3.x。将来项目出问题需要排查时照着这个文件恢复环境能省掉大量时间。我自己通常同时生成一份宽松的requirements.in只写顶层依赖和一份锁定的requirements-lock.txt前者用来说明项目依赖哪些库后者用来精确复现。5. 创建并运行一个 LangGraph 示例项目5.1 项目目录结构环境准备好了框架装好了现在开始实际创建项目。很多人以为 Agent 项目有多神秘其实本质就是一个 Python 脚本加上配置文件。为了方便后续扩展建议按下面的结构组织目录langgraph-demo/ ├── .env ├── graph_basic.py └── requirements.txt.env文件里保存模型服务的 API Key 等敏感信息不要提交到 Git 仓库用export或者在 Python 里读环境变量。graph_basic.py是项目入口包含整张 Agent 图的定义。requirements.txt记录项目依赖方便别人重装。这种结构虽然简单但层次清楚适合作为起步项目。后续项目复杂了再拆出tools.py、state.py、nodes.py等模块也不迟。5.2 从零写一个最小的可运行 Agent下面这个例子我会做得非常直接用 DeepSeek 的模型接入 LangGraph搭一个可以进行简单对话并且能调用自定义加法工具的小 Agent。这个例子短但足以说明问题模型如何根据指令决定调用工具工具返回结果后再交回模型最后模型输出答案整个过程就构成一次带条件分支和循环的图遍历。先在项目目录下创建.env文件DEEPSEEK_API_KEY你的密钥然后在终端里安装 dotenv 工具用于读取这个文件pip install python-dotenv接下来创建graph_basic.py一步步写。LangGraph 的核心概念是 State、Node、Edge。State 是用来存放任务过程中产生的所有数据的数据结构比如对话消息列表、工具返回结果Node 是图里的一个执行步骤本质是一个普通 Python 函数Edge 定义了节点之间的流转路径包括条件跳转。完整代码如下import os from typing import TypedDict, Annotated from dotenv import load_dotenv from langchain_deepseek import ChatDeepSeek from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages from langgraph.prebuilt import ToolNode load_dotenv() api_key os.getenv(DEEPSEEK_API_KEY) # 1. 定义图的状态这里只需要一个消息列表 class State(TypedDict): messages: Annotated[list, add_messages] # 2. 定义一个供模型调用的工具 def add(a: int, b: int) - int: 计算两个数字的和。 return a b定义完工具把工具传给模型核心是让模型能感知到工具的存在并学会按格式发起工具调用tools [add] model ChatDeepSeek( modeldeepseek-chat, api_keyapi_key, temperature0, ).bind_tools(tools)然后定义图中的节点。这里用的model_node是让模型根据当前消息列表决定回复内容或发起工具调用。invoke_tools节点用来执行模型请求的工具。还有一个允许模型在有工具调用循环的情况下重复数次的逻辑这里通过条件边维护一个“递归限制”来实现。def model_node(state: State): # 让模型拿到完整消息列表输出新消息 result model.invoke(state[messages]) return {messages: result} # 如果模型发起工具调用则跳转到工具节点否则结束 def should_continue(state: State): last_message state[messages][-1] if last_message.tool_calls: return invoke_tools return END # 3. 组装成图 graph_workflow StateGraph(State) graph_workflow.add_node(model, model_node) graph_workflow.add_node(invoke_tools, ToolNode(tools)) graph_workflow.add_edge(START, model) graph_workflow.add_conditional_edges( model, should_continue, { invoke_tools: invoke_tools, END: END, } ) graph_workflow.add_edge(invoke_tools, model) app graph_workflow.compile()最后是入口逻辑if __name__ __main__: result app.invoke( {messages: [(user, 请帮我计算 15 加 27 的结果是多少)]}, config{recursion_limit: 20}, ) print(result[messages][-1].content)这里值得展开说一下recursion_limit。LangGraph 的图会限制节点流转的最大次数这是为了防止 Agent 无限循环。默认值通常是 25但在一些复杂的多轮工具调用场景下可能不够用所以我习惯在调用时显式设一个大一点的数。执行这个脚本后模型会产生一个工具调用请求图中流转一次进到invoke_tools节点工具计算出结果 42再交回模型最后由模型生成对用户的自然语言总结python graph_basic.py如果一切正常你会看到终端输出类似这样的一句话15 加 27 的结果是 42。至此一个最小可用的 LangGraph Agent 项目就搭起来并跑通了。5.3 拆解 LangGraph 的执行流程细节可能刚接触的读者会好奇这张图到底是怎么流转的。我用上面的例子逐步拆解一次。程序启动后用户输入一句话被包装成一条 user 消息放入 State 的 messages 列表。app.invoke()触发图开始从 START 节点执行。START 边固定连接到我们注册的model节点模型读到消息列表后判断出用户想要计算结果同时模型知道有一个add工具可用于是返回一条带 tool_calls 的 AI 消息而不是直接回复文字。条件边函数should_continue发现最后一条消息里存在 tool_calls于是将流程导向invoke_tools节点。这个节点自动执行工具函数 add结果为 42于是往消息列表追加一条 tool 消息。工具执行完后边定义里把流程无条件送回model节点模型这次看到完整的信息用户提问、自己的工具调用请求、工具返回的结果于是生成最终的总结性回答并返回没有新的 tool_calls条件边判定流程结束图走到 END最终拿到完整结果。有一点让我第一次用的时候很惊艳add_messages这个归约函数。如果没有它每次节点返回的 messages 都会直接覆盖掉原来的列表整个对话就丢了历史。加上它之后新消息会被自动追加到已有列表中这让状态管理变得异常省心。后续做多轮对话或者复杂任务时这个机制能省掉大量手工拼接逻辑。6. 常见问题与排查技巧实录6.1 终端激活环境失败、conda 命令找不到这几个问题加起来能劝退一半新手。症状通常是明明安装了 Anaconda终端里执行conda却提示不是内部或外部命令或者执行conda activate langgraph-env时提示“系统找不到指定的路径”。前者是环境变量没配好需要把 Anaconda3 和 Anaconda3\Scripts 手动加到 PATH 里。后者通常是 Windows PowerShell 的执行策略限制了 conda 初始化脚本执行一次conda init powershell然后重开终端。如果是 PowerShell 提示“无法加载脚本”之类的错误可以用管理员权限执行Set-ExecutionPolicy RemoteSigned这是我在 Windows 上遇到过最多的一个隐藏坑。Mac 和 Linux 上一般少见反而更常见的问题是忘记用source ~/.bashrc或source ~/.zshrc重载配置文件。6.2 装包太慢、超时或版本冲突配好镜像源之后仍然可能出现超时尤其是安装 LangGraph 这种依赖树很深的框架。遇到这种情况可以临时指定更长的超时时间和确认源pip install langgraph -i https://pypi.tuna.tsinghua.edu.cn/simple --default-timeout120版本冲突也是高频问题。之前有读者在环境里同时安装了多个版本不兼容的 LangChain 生态包导致启动报pydantic相关错误。LangChain 和 LangGraph 对 pydantic 版本非常敏感如果遇到ValueError: validator(...)这类报错优先检查 pydantic 是否为 2.x 版本。解决思路是强制重新安装兼容版本或者干脆删掉环境重建。我的经验是LangGraph 项目环境一旦出现难以排查的版本冲突直接重建环境往往比花两小时排查更划算这也是虚拟环境最让人安心的价值。6.3 LangGraph 项目运行常见报错速查表运行 LangGraph 项目过程中我把常见报错整理成了一张速查表方便对照检查报错信息可能原因解决方式ModuleNotFoundError: No module named langgraph当前终端不在目标虚拟环境中执行conda activate langgraph-env后再运行ValidationError或KeyError: messagesState 定义和节点返回值不一致检查节点返回字典的 key 是否包含在 State 定义中RecursionError: maximum recursion depth exceeded图循环次数超限在invoke时提高recursion_limit或检查条件边逻辑Anthropic/OpenAI 相关报错模型接口配置错误或 API Key 缺失检查环境变量.env是否正确加载网络是否可达TypeError: NoneType object is not callablemodel节点拿到空消息或工具定义格式错误检查bind_tools是否成功绑定工具函数是否有完整 docstring这张表不是我凭空编的每一条都是真实经历过的报错场景。把我自己卡得最久的细节补充一下给工具函数写 docstring 非常重要因为模型的工具描述就是从函数名和 docstring 里提取的没有写文档说明的工具模型可能根本不知道这个工具是干什么的自然也不会调用它。这属于框架使用中极其关键的经验。6.4 两个容易忽略的习惯最后分享两个环境管理上的小习惯。第一不要频繁在多个环境间反复切换并随意安装包每次新装包后及时更新 requirements 文件这样将来环境崩了恢复成本极低。第二不要为了图省事直接在 base 环境里运行 LangGraph虽然一时爽但 base 环境的包一旦冲突连 Anaconda 自带的工具都可能受影响。虚拟环境的意义就在于随便折腾坏了就删删了重建几分钟又是一条好汉。这个 LangGraph 示例项目本身后续还可以扩展成带网络搜索的工具、接入记忆模块、或者挂到 FastAPI 上做成服务。但所有扩展的前提都是先把环境治理得干干净净。把基础打牢后面的路会比别人快很多。
返回列表