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

资讯详情

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

从零构建AI智能体:基于LangChain的工程实践指南

从零构建AI智能体:基于LangChain的工程实践指南 1. 引言从“AI小镇”到AI工程实践开发者如何构建自己的智能体世界最近一个名为“AI小镇”的开源项目在GitHub上引起了不小的关注。这个项目模拟了一个由25个AI智能体Agent构成的虚拟社会它们能够自主交流、协作、甚至发展出复杂的社会关系。与此同时网络上关于“AI Agent开发”、“无限制AI对话”、“AI编程”等关键词的搜索热度持续攀升反映出开发者社区对构建自主、智能的应用有着强烈的兴趣和需求。然而当我们将视线从这些前沿探索移开回归到实际的开发工作中会发现一个普遍的困境很多开发者对AI大模型的应用仍停留在调用API生成文本或图片的层面对于如何系统性地设计、开发、部署一个真正具有“智能”的AI应用或智能体缺乏清晰的路径和工程化的实践指南。网上资料虽多但往往零散不成体系或是过于理论化难以直接落地。本文旨在解决这一痛点。我们将以“AI工程实践”为核心为你拆解从零开始构建一个AI智能体Agent应用的全流程。我们将避开空泛的概念讨论直接切入实战涵盖环境搭建、核心架构设计、与大模型LLM的集成、工具调用、记忆管理、多智能体协作等关键环节并提供完整的、可运行的代码示例。无论你是想开发一个个性化的AI聊天助手还是构建一个像“AI小镇”那样的模拟环境甚至是开发辅助编程、数据分析的AI工具本文提供的框架和思路都能为你提供坚实的起点。2. 核心概念什么是AI智能体Agent在深入代码之前我们必须先厘清核心概念。AI智能体Agent是当前AI应用开发中的一个核心范式它远不止是一个简单的聊天接口。通俗理解你可以把一个AI智能体想象成一个虚拟的“数字员工”。它拥有明确的“目标”Goal可以“思考”Reasoning如何达成目标能够使用各种“工具”Tools来获取信息或执行操作如搜索网络、运行代码、查询数据库并且具备“记忆”Memory能力能够记住之前的对话和交互历史从而进行连贯的、有上下文的行动。与简单AI对话的区别简单AI对话如ChatGPT网页版用户输入模型输出。每次交互相对独立模型没有持久的目标也无法主动调用外部工具。AI智能体Agent围绕一个长期或短期目标运行。例如“帮我分析本季度销售数据并生成报告”。智能体会自主规划步骤先调用工具读取数据库再调用工具进行数据分析最后生成报告。整个过程是自主的、连贯的。关键组件大语言模型LLM智能体的“大脑”负责理解、规划和决策。工具Tools智能体的“手和脚”是它连接现实世界、获取信息和执行动作的接口。一个工具可以是一个函数、一个API调用或一个命令行程序。记忆Memory智能体的“经验”分为短期记忆当前对话的上下文和长期记忆向量数据库存储的过往重要信息。规划器Planner有些框架中会有一个专门的模块来将大目标分解为可执行的小步骤。执行器Executor负责调用工具并将结果反馈给LLM进行下一步决策。理解了这些我们就知道构建一个AI智能体本质上是为LLM装配上工具和记忆并设计一套机制让它能循环执行“感知-思考-行动”的过程。3. 环境准备与工具选型工欲善其事必先利其器。在开始编码前我们需要搭建开发环境并选择合适的框架。本文将使用Python作为开发语言并选择LangChain和LangGraph作为核心框架因为它们生态成熟、文档丰富非常适合学习和工程化。3.1 基础环境操作系统Windows 10/11, macOS, 或 Linux (Ubuntu 20.04)。本文示例在 macOS/Linux 环境下测试。Python 版本 3.8。推荐使用 3.10 或 3.11以获得最佳的兼容性。包管理工具pip或conda。代码编辑器VS Code推荐有丰富的AI插件或 PyCharm。3.2 核心框架与库我们将主要使用以下库请通过pip安装# 创建并进入项目目录 mkdir ai_agent_project cd ai_agent_project python -m venv venv # 创建虚拟环境 # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate # 安装核心库 pip install langchain langchain-community langchain-openai langgraph # 安装用于向量记忆存储的库 pip install chromadb # 安装用于网页搜索的工具库示例 pip install duckduckgo-search # 安装环境变量管理库 pip install python-dotenv版本说明AI领域库更新迅速以上安装命令会获取当前稳定版本。如果遇到兼容性问题可以尝试指定稍早的版本例如pip install langchain0.1.0。本文重点在于架构和思路代码示例会尽量使用通用接口。3.3 大模型API配置智能体需要“大脑”。我们将使用 OpenAI 的 GPT 系列模型作为示例你也可以替换为其他兼容API的模型如 Anthropic Claude、国内的通义千问等。获取 OpenAI API Key访问 OpenAI平台 注册并获取。在项目根目录创建.env文件用于安全存储密钥# .env 文件内容 OPENAI_API_KEY你的-api-key-here在代码中通过python-dotenv加载环境变量。重要请妥善保管你的.env文件不要将其提交到 Git 等版本控制系统。建议将.env添加到.gitignore文件中。4. 构建你的第一个AI智能体一个联网搜索助手让我们从一个相对简单但功能完整的智能体开始一个可以联网搜索并总结信息的助手。它的目标是根据用户的问题自动决定是否需要搜索然后获取信息并给出回答。4.1 项目结构初始化创建如下项目结构ai_agent_project/ ├── .env # 环境变量密钥 ├── .gitignore # Git忽略文件 ├── requirements.txt # 项目依赖可选 ├── src/ │ ├── __init__.py │ ├── tools/ # 工具模块 │ │ ├── __init__.py │ │ └── search_tool.py │ ├── agents/ # 智能体模块 │ │ ├── __init__.py │ │ └── search_agent.py │ └── main.py # 主程序入口 └── README.md4.2 实现搜索工具首先我们创建一个搜索工具。在src/tools/search_tool.py中# src/tools/search_tool.py from langchain_community.tools import DuckDuckGoSearchRun from langchain.tools import Tool def get_search_tool(): 创建并返回一个基于 DuckDuckGo 的搜索工具。 这是一个真实可用的网络搜索工具。 search DuckDuckGoSearchRun() # 将工具包装成 LangChain 的 Tool 对象并添加描述。 # 描述非常重要LLM 会根据描述决定何时使用这个工具。 search_tool Tool( nameWeb Search, funcsearch.run, description( Useful for when you need to answer questions about current events, or when you need to find recent information on the web. Input should be a clear search query string. ) ) return search_tool if __name__ __main__: # 简单测试工具 tool get_search_tool() result tool.invoke(今天北京天气怎么样) print(result)4.3 构建智能体接下来在src/agents/search_agent.py中构建智能体。我们将使用 LangChain 的create_react_agent模式这是一种经典的“Reasoning Acting”循环。# src/agents/search_agent.py import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain import hub # 用于拉取预定义的提示词 # 加载环境变量读取 OPENAI_API_KEY load_dotenv() def create_search_agent(): 创建一个具备搜索能力的智能体。 # 1. 初始化 LLM llm ChatOpenAI( modelgpt-3.5-turbo, # 也可使用 gpt-4 获得更强推理能力 temperature0, # 温度设为0使输出更确定、更可靠 openai_api_keyos.getenv(OPENAI_API_KEY) ) # 2. 获取工具列表目前只有一个搜索工具 from src.tools.search_tool import get_search_tool tools [get_search_tool()] # 3. 从 LangChain Hub 拉取一个为 ReAct 框架优化过的提示词 # 这个提示词会指导 LLM 如何思考和使用工具 prompt hub.pull(hwchase17/react) # 4. 创建智能体 agent create_react_agent(llm, tools, prompt) # 5. 创建执行器它负责运行智能体的循环 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 设为 True 可以看到智能体的思考过程调试非常有用 handle_parsing_errorsTrue # 优雅地处理解析错误 ) return agent_executor if __name__ __main__: # 测试智能体 agent create_search_agent() question 谁是2023年诺贝尔文学奖得主 print(f用户提问: {question}) try: result agent.invoke({input: question}) print(f\n智能体回答: {result[output]}) except Exception as e: print(f执行出错: {e})4.4 运行与验证创建主程序入口src/main.py# src/main.py from src.agents.search_agent import create_search_agent def main(): print( AI 联网搜索助手 ) agent create_search_agent() while True: try: user_input input(\n请输入您的问题 (输入 quit 退出): ) if user_input.lower() in [quit, exit, q]: print(再见) break if not user_input.strip(): continue print(\n【智能体思考中...】) # 调用智能体 result agent.invoke({input: user_input}) print(f\n【最终答案】: {result[output]}) except KeyboardInterrupt: print(\n程序被中断。) break except Exception as e: print(f\n抱歉处理过程中出现了错误: {e}) if __name__ __main__: main()现在在项目根目录下运行python -m src.main你会看到类似以下的输出verboseTrue时的详细思考过程 AI 联网搜索助手 请输入您的问题 (输入 quit 退出): 马斯克最近有什么新闻 【智能体思考中...】 Entering new AgentExecutor chain... 我需要搜索一下马斯克最近的新闻。 Action: Web Search Action Input: 马斯克 最近 新闻 Observation: 搜索结果埃隆·马斯克旗下公司SpaceX的星舰计划进行第三次试飞... Neuralink宣布首位人类患者成功植入脑机接口设备... 特斯拉股价... Thought: 根据搜索结果我找到了马斯克相关公司SpaceX, Neuralink, Tesla的最新动态。我需要把这些信息总结一下回答用户。 Action: Web Search Action Input: SpaceX 星舰第三次试飞 时间 Observation: 搜索结果SpaceX星舰于2024年3月14日进行了第三次集成飞行测试... Thought: 我现在有足够的信息来回答用户的问题了。 I now have enough information to answer the users question. Final Answer: 近期关于埃隆·马斯克的主要新闻有1. SpaceX方面星舰于2024年3月14日成功进行了第三次集成飞行测试... 2. Neuralink方面宣布首位人类患者已成功植入脑机接口设备... 3. 特斯拉方面股价近期有所波动... 【最终答案】: 近期关于埃隆·马斯克的主要新闻有1. SpaceX方面...结果说明你成功创建了一个具备自主决策能力的AI智能体它能够理解问题判断需要搜索执行搜索工具分析搜索结果并最终生成一个连贯、有信息量的回答。这比单纯调用ChatGPT并手动粘贴搜索结果要强大和自动化得多。5. 进阶构建具有记忆和复杂工作流的智能体基础的搜索助手已经很有用但一个成熟的智能体通常需要记忆和更复杂的工作流。我们接下来引入记忆Memory和LangGraph来构建一个状态化的、可处理多轮对话和复杂任务的智能体。5.1 为智能体添加对话记忆我们将使用ConversationBufferMemory来保存对话历史。# src/agents/agent_with_memory.py import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_react_agent from langchain.memory import ConversationBufferMemory from langchain import hub from src.tools.search_tool import get_search_tool load_dotenv() def create_agent_with_memory(): llm ChatOpenAI(modelgpt-3.5-turbo, temperature0, api_keyos.getenv(OPENAI_API_KEY)) tools [get_search_tool()] prompt hub.pull(hwchase17/react) # 关键创建记忆对象 memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) agent create_react_agent(llm, tools, prompt) # 创建执行器时传入 memory agent_executor AgentExecutor( agentagent, toolstools, memorymemory, # 注入记忆 verboseTrue, handle_parsing_errorsTrue ) return agent_executor if __name__ __main__: agent create_agent_with_memory() # 第一轮对话 print(Q: 我喜欢的球队是湖人队。) agent.invoke({input: 我喜欢的球队是湖人队。}) # 第二轮对话智能体会记得之前的上下文 print(\nQ: 他们最近一场比赛赢了吗) result agent.invoke({input: 他们最近一场比赛赢了吗}) print(fA: {result[output]}) # 注意这里“他们”指代的是湖人队因为记忆中存在上下文。5.2 使用LangGraph构建有状态的工作流LangGraph 允许我们以图Graph的形式定义智能体的执行流程非常适合构建包含条件分支、循环和多智能体协作的复杂应用。下面我们构建一个简单的“研究助手”工作流先搜索再总结如果总结不充分可以循环再次搜索。# src/agents/research_agent_graph.py import os from typing import TypedDict, Annotated, Sequence import operator from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain_core.messages import BaseMessage, HumanMessage from langgraph.graph import StateGraph, END from langgraph.graph.message import add_messages from langchain_community.tools import DuckDuckGoSearchRun from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder load_dotenv() # 1. 定义状态结构 class AgentState(TypedDict): messages: Annotated[Sequence[BaseMessage], add_messages] # 消息历史 question: str # 原始问题 search_results: list[str] # 搜索结果列表 final_answer: str # 最终答案 # 2. 初始化组件 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0, api_keyos.getenv(OPENAI_API_KEY)) search DuckDuckGoSearchRun() # 3. 定义节点函数 def search_node(state: AgentState): 搜索节点执行网络搜索 print(f[Search Node] 正在搜索: {state[question]}) results search.run(state[question]) state[search_results] [results] # 存储结果 return {search_results: state[search_results]} def generate_node(state: AgentState): 生成节点基于搜索结果生成答案 print(f[Generate Node] 正在生成答案...) search_content \n---\n.join(state[search_results]) prompt ChatPromptTemplate.from_messages([ (system, 你是一个研究助手。请基于以下的搜索内容为用户的问题提供一个全面、准确的回答。如果内容不足请明确指出信息有限。), MessagesPlaceholder(variable_namemessages), (user, f用户问题{state[question]}\n\n搜索内容\n{search_content}) ]) chain prompt | llm response chain.invoke({messages: state.get(messages, [])}) state[final_answer] response.content return {final_answer: state[final_answer], messages: state[messages] [response]} def should_continue(state: AgentState) - str: 条件判断节点决定是否继续搜索 # 这里可以加入更复杂的逻辑例如让LLM判断答案是否满意 # 为了示例简单我们假设一次搜索后直接结束 print([Decision Node] 判断流程结束。) return end # 4. 构建图 workflow StateGraph(AgentState) # 添加节点 workflow.add_node(search, search_node) workflow.add_node(generate, generate_node) # 设置入口边 workflow.set_entry_point(search) # 设置边搜索 - 生成 workflow.add_edge(search, generate) # 设置条件边生成 - (判断) - END workflow.add_conditional_edges( generate, should_continue, { end: END, } ) # 编译图 app workflow.compile() # 5. 运行图 if __name__ __main__: initial_state AgentState( messages[HumanMessage(content你好研究助手。)], question什么是量子计算它目前面临的主要挑战是什么, search_results[], final_answer ) print(开始执行研究助手工作流...) final_state app.invoke(initial_state) print(f\n 最终答案 \n{final_state[final_answer]})这个例子展示了如何将智能体的工作流分解为不同的“节点”搜索、生成、判断并通过图来控制执行顺序。LangGraph 使得构建像“AI小镇”中那种拥有复杂行为逻辑的智能体成为可能。6. 常见问题与排查思路FAQ在开发AI智能体过程中你一定会遇到各种问题。下面是一个常见问题排查清单问题现象可能原因解决思路ModuleNotFoundError: No module named langchain依赖未安装或虚拟环境未激活。1. 确认已激活虚拟环境 (venv\Scripts\activate或source venv/bin/activate)。2. 运行pip install -r requirements.txt或重新安装pip install langchain。AuthenticationError: Incorrect API key providedOpenAI API Key 错误或未设置。1. 检查.env文件中的OPENAI_API_KEY是否正确。2. 确保代码中通过load_dotenv()加载了环境变量。3. 检查API Key是否有余额或是否过期。智能体一直循环不输出最终答案1. 工具描述不清晰LLM无法正确调用。2. ReAct提示词与模型不匹配。3. 模型“幻觉”产生了无效的动作指令。1.检查工具描述确保description字段清晰说明了工具的用途和输入格式。2.开启verboseTrue观察思考链看卡在哪一步。3.尝试更换模型使用gpt-4通常有更强的推理和指令遵循能力。4.设置max_iterations在AgentExecutor中设置max_iterations10防止无限循环。DuckDuckGoSearchRun搜索失败或返回空1. 网络问题。2. DuckDuckGo API 临时限制或变更。1. 检查网络连接。2. 尝试使用其他搜索工具如SerpAPI需注册获取API Key或TavilySearch。3. 在工具函数中添加异常处理和重试逻辑。智能体“忘记”了之前的对话记忆Memory未正确配置或未传递给执行器。1. 确认创建了ConversationBufferMemory等记忆对象。2. 确认在创建AgentExecutor时传入了memory参数。3. 确认在调用invoke时状态中包含了历史消息。LangGraph 图编译或运行出错1. 状态State定义与节点函数返回值不匹配。2. 图的结构有误存在死循环或无法到达的节点。1.仔细检查TypedDict确保每个节点函数返回的字典键是状态中定义的键的子集。2.使用workflow.get_graph().draw_mermaid()输出图结构可视化检查逻辑。3. 从最简单的两个节点开始逐步构建和测试。处理速度慢Token消耗大1. 使用的模型较大如GPT-4。2. 对话历史或搜索上下文过长。3. 智能体循环次数过多。1.优化提示词使其更简洁、精准。2.使用摘要记忆用ConversationSummaryMemory替代ConversationBufferMemory压缩历史。3.限制上下文长度在调用LLM前截断过长的消息历史。4.设置预算监控API调用费用和Token使用量。7. 工程最佳实践与扩展方向构建可用于生产环境的AI智能体远不止让代码跑通。以下是一些关键的工程化建议和扩展思路7.1 工程化建议配置管理不要将API密钥、模型参数等硬编码在代码中。使用.env文件或专业的配置管理工具如pydantic-settings。日志与监控为智能体的关键步骤如工具调用、LLM请求、最终决策添加结构化日志。监控Token消耗、API延迟和错误率。错误处理与重试网络请求和外部API调用必然失败。为所有工具调用和LLM请求添加重试机制如tenacity库和优雅的降级处理。测试为你的工具函数和智能体工作流编写单元测试和集成测试。模拟MockLLM和工具调用来测试逻辑分支。版本控制与依赖管理使用requirements.txt或poetry严格管理依赖版本避免因库更新导致的不兼容。安全性工具权限仔细审查每个工具的能力。一个能执行任意Shell命令的工具是极度危险的。遵循最小权限原则。输入验证对用户输入进行清洗和验证防止提示词注入攻击。输出过滤对智能体的输出进行内容安全过滤避免生成有害或不适当的内容。7.2 扩展方向打造更强大的智能体更多工具为你的智能体装备“瑞士军刀”。代码执行使用PythonREPLTool让智能体可以运行Python代码进行数据分析或计算。文件读写让智能体能够读取本地文档PDF, Word, TXT或写入报告。数据库查询集成SQLDatabaseToolkit让智能体能直接与数据库对话。自定义API将你的内部业务系统封装成工具让智能体成为业务流程的自动化助手。更优的记忆系统向量记忆使用Chroma、Pinecone等向量数据库存储长期记忆实现基于语义相似度的信息检索。分层记忆结合短期对话缓存、中期摘要和长期向量存储记忆平衡性能与信息量。多智能体协作Multi-Agent这是“AI小镇”项目的核心。你可以创建多个具有不同角色如“研究员”、“写手”、“评审员”的智能体让它们通过消息传递协同完成一个复杂任务。LangGraph 的StateGraph非常适合编排多智能体系统。与前端集成使用Gradio、Streamlit快速构建Web界面。使用FastAPI构建RESTful API供其他应用程序调用。探索本地模型出于成本、隐私或定制化需求可以探索在本地部署开源大模型如 Llama 3、Qwen、DeepSeek并使用Ollama、vLLM或LM Studio进行服务化然后用LangChain的本地接口进行集成。从今天构建的联网搜索助手出发沿着这些方向深入你完全有能力开发出像“AI小镇”一样有趣的多智能体模拟系统或是能够真正提升工作效率的AI副驾。AI工程化的世界刚刚打开其核心在于将前沿的模型能力与扎实的软件工程实践相结合构建出可靠、可控、可扩展的智能应用。
返回列表