从零构建AI智能体:基于LangChain与GPT的联网搜索助手实战
1. 项目概述从零到一构建并部署你的第一个AI智能体最近几年AI智能体AI Agent的概念越来越火。简单来说它不再是那个你问一句、它答一句的聊天机器人而是一个能自主思考、规划、调用工具并执行复杂任务的“数字员工”。想象一下你有一个助手你只需要告诉它“帮我分析一下上周的销售数据找出问题并生成一份PPT报告”它就能自己打开数据库、运行分析、撰写文案、调用PPT生成工具最后把成品发给你。这就是AI智能体的魅力所在。今天我们就来手把手地完成一个完整的旅程从零开始构建你的第一个AI智能体并把它部署到Sevalla平台上让它成为一个可以对外提供服务的“在线员工”。无论你是开发者、产品经理还是对AI应用感兴趣的爱好者这个过程都将为你打开一扇新的大门。我们将使用目前业界最主流、最易上手的工具链避开那些复杂的理论直接进入实战。你会发现构建一个能解决实际问题的智能体并没有想象中那么遥不可及。2. 核心思路与架构设计你的智能体如何“思考”与“行动”在动手写代码之前我们必须先想清楚我们的智能体要做什么以及它应该如何工作。一个典型的AI智能体架构通常包含以下几个核心部分感知Perception接收用户的指令或环境信息。在我们的场景里就是处理用户通过聊天界面或API发来的自然语言请求。规划Planning理解任务并将其拆解成一系列可执行的子步骤。比如用户说“查一下北京明天天气并推荐穿衣”智能体需要规划出“1. 调用天气API获取数据2. 根据温度数据生成穿衣建议”。行动Action执行规划好的步骤。这通常通过调用各种“工具”Tools来实现工具可以是函数、API、数据库查询等。记忆Memory记住对话历史、执行上下文和学到的知识以便进行连贯的、有上下文的交互。对于我们的第一个智能体我建议从一个实用且有趣的任务开始“联网搜索与信息总结智能体”。它的核心功能是用户提出任何问题智能体能够自动去互联网上搜索最新信息然后阅读、理解并整理成一份简洁、准确的答案回复给用户。2.1 技术栈选型为什么是它们工欲善其事必先利其器。以下是经过大量项目验证的、稳定且高效的技术组合大语言模型LLM核心OpenAI GPT-4o / GPT-3.5-Turbo。这是目前构建智能体最成熟的选择。其强大的推理能力、函数调用Function Calling支持以及稳定的API能极大降低开发难度。虽然也有Claude、国产模型等优秀选择但OpenAI的生态和文档对新手最为友好。智能体框架LangChain。它是当前AI应用开发的事实标准框架。LangChain抽象了与LLM交互、工具调用、记忆管理、链式工作流等复杂逻辑提供了大量开箱即用的模块让我们能像搭积木一样构建智能体。它的社区活跃遇到问题很容易找到解决方案。搜索工具Tavily Search API。为什么不用Google或Bing的API因为Tavily是专为AI智能体优化的搜索工具。它返回的是经过清洗、结构化的搜索结果摘要和链接而不是原始的HTML页面这大大减少了LLM需要处理的噪音信息提高了答案的准确性和生成速度。对于智能体来说这是更高效的“眼睛”。部署平台Sevalla。这是一个新兴的、专注于AI智能体部署和管理的平台。它简化了将LangChain或AutoGPT等框架构建的智能体打包成API服务的过程提供了监控、日志、版本管理等生产级功能。对于个人开发者和小团队来说它比从零搭建一套Kubernetes部署方案要省心得多。注意选择Tavily而非直接使用搜索引擎API是一个关键的设计决策。智能体处理原始HTML的效率很低且容易“迷失”在广告和无关信息中。Tavily提供的“AI原生”搜索结果相当于已经帮智能体完成了初步的信息筛选和整理这是提升智能体表现最有效的捷径之一。2.2 系统架构图概念版虽然我们不能画图但可以用文字清晰地描述数据流用户通过Web界面或API发送查询“特斯拉最新的财报有什么亮点”Sevalla平台接收请求并将其路由到我们部署的智能体服务。智能体LangChain程序启动其“规划”模块分析用户问题判断需要执行“搜索”动作。“行动”模块调用Tavily搜索工具获取关于特斯拉最新财报的结构化信息。LLM核心GPT接收搜索到的信息进行阅读理解、归纳总结。智能体将整理好的答案通过Sevalla平台返回给用户。这个架构清晰、职责分明每个环节都有成熟的工具支撑。3. 开发环境准备与核心依赖安装现在我们进入实操环节。首先确保你有一个可用的Python开发环境建议Python 3.9。3.1 创建项目与虚拟环境避免包冲突是Python项目的第一步。打开你的终端执行以下命令# 创建一个新的项目目录 mkdir my-first-ai-agent cd my-first-ai-agent # 创建Python虚拟环境以venv为例 python -m venv venv # 激活虚拟环境 # 在Windows上 venv\Scripts\activate # 在MacOS/Linux上 source venv/bin/activate激活后你的命令行提示符前应该会出现(venv)字样。3.2 安装核心Python库接下来安装我们所需的库。创建一个requirements.txt文件内容如下langchain0.1.0 langchain-openai0.0.5 langchain-community0.0.10 tavily-python0.3.0 fastapi0.104.1 uvicorn[standard]0.24.0 python-dotenv1.0.0 pydantic2.5.0然后使用pip安装pip install -r requirements.txt这里解释一下几个关键库langchain智能体框架本体。langchain-openaiLangChain官方维护的OpenAI集成包。langchain-community包含社区贡献的各种工具和集成Tavily工具就在这里。tavily-pythonTavily搜索API的官方客户端。fastapiuvicorn我们将用它们来构建一个简单的API服务器这是部署到Sevalla的前提。python-dotenv用于管理环境变量如API密钥这是保护敏感信息的最佳实践。3.3 获取并配置API密钥你需要准备两个关键的API密钥OpenAI API Key访问 OpenAI平台 创建。Tavily API Key访问 Tavily官网 注册并获取免费额度。在项目根目录下创建一个名为.env的文件将你的密钥填入OPENAI_API_KEYsk-your-openai-api-key-here TAVILY_API_KEYtvly-your-tavily-api-key-here重要安全提醒务必把.env文件添加到你的.gitignore文件中绝对不要将包含真实密钥的文件提交到Git仓库4. 逐步构建智能体核心逻辑环境准备好了让我们开始编写智能体的“大脑”。我们将分步骤构建一个完整的、可交互的智能体。4.1 初始化LLM和搜索工具创建一个名为agent_core.py的文件。import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain_community.tools.tavily_search import TavilySearchResults # 加载.env文件中的环境变量 load_dotenv() # 1. 初始化大语言模型 # 使用GPT-3.5-turbo性价比高适合实验。生产环境可考虑GPT-4o。 llm ChatOpenAI( modelgpt-3.5-turbo, temperature0, # 温度设为0使输出更确定、更可靠 openai_api_keyos.getenv(OPENAI_API_KEY) ) # 2. 初始化搜索工具 # TavilySearchResults默认返回5条最相关的结果这对大多数查询已经足够。 search_tool TavilySearchResults( tavily_api_keyos.getenv(TAVILY_API_KEY), max_results5 ) # 测试工具是否工作 if __name__ __main__: try: result search_tool.invoke(OpenAI最近发布了什么重要更新) print(搜索工具测试成功返回结果类型, type(result)) # 结果是一个字典列表包含snippet摘要和url等字段 if result and len(result) 0: print(第一条结果摘要, result[0][content][:200]) # 打印前200字符 except Exception as e: print(f工具测试失败请检查API密钥和网络{e})运行这个脚本python agent_core.py如果看到成功的搜索结果摘要说明你的LLM和工具配置正确。4.2 创建智能体执行链智能体的核心是一个“链”Chain它定义了任务执行的流程。我们将使用LangChain的“Agent Tools”模式。创建agent_chain.py。from langchain.agents import create_react_agent, AgentExecutor from langchain import hub from agent_core import llm, search_tool # 导入上一步定义的模型和工具 # 1. 定义工具列表 # 目前我们只有一个搜索工具但你可以很容易地在这里添加更多工具如计算器、数据库查询等。 tools [search_tool] # 2. 拉取一个预定义的智能体提示词模板 # LangChain Hub上有很多社区贡献的模板react模板非常适合工具调用场景。 prompt hub.pull(hwchase17/react) # 3. 创建ReAct智能体 # ReActReasoning Acting是一种让LLM在思考生成推理步骤和行动调用工具间循环的范式。 agent create_react_agent(llm, tools, prompt) # 4. 创建智能体执行器 # 这是智能体的“运行时”负责处理循环、解析输出、管理工具调用。 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 设为True可以看到智能体详细的思考过程调试时非常有用 handle_parsing_errorsTrue, # 自动处理LLM输出格式错误增加鲁棒性 max_iterations5 # 限制最大迭代次数防止智能体陷入死循环 ) # 测试智能体 if __name__ __main__: test_queries [ 谁赢得了2023年的金球奖, 计算一下2的10次方是多少, # 注意我们没有计算器工具它会如何处理 用中文总结一下特斯拉2024年第一季度的交付情况。 ] for query in test_queries: print(f\n{*50}) print(f用户提问: {query}) print(f{*50}) try: response agent_executor.invoke({input: query}) print(f智能体回答: {response[output]}) except Exception as e: print(f执行出错: {e})运行这个脚本你会看到verboseTrue模式下智能体详细的思考日志Thought/Action/Observation循环。对于第二个没有工具能处理的问题观察智能体是如何反应的它可能会诚实地表示自己无法计算。这就是工具扩展性的体现——你需要什么能力就为它添加相应的工具。4.3 为智能体添加记忆能力目前的智能体是“金鱼脑”每次对话都是独立的。为了让对话更连贯我们需要给它加上记忆。修改agent_chain.py引入对话记忆。from langchain.agents import create_react_agent, AgentExecutor from langchain import hub from langchain.memory import ConversationBufferMemory from agent_core import llm, search_tool tools [search_tool] prompt hub.pull(hwchase17/react) # 新增创建对话记忆 # ConversationBufferMemory会保存完整的对话历史。 memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # 修改提示词模板使其包含记忆的占位符 # 我们需要手动将记忆变量注入到提示词中。一个更简单的方法是使用agent_executor的memory参数。 agent create_react_agent(llm, tools, prompt) # 创建执行器时传入memory agent_executor AgentExecutor( agentagent, toolstools, memorymemory, # 关键绑定记忆 verboseTrue, handle_parsing_errorsTrue, max_iterations5 ) if __name__ __main__: # 测试多轮对话 queries [ 梅西现在效力于哪家俱乐部, 他是什么时候加入的, # “他”指代上一句的梅西 这家俱乐部所在的城市以什么闻名 # “这家俱乐部”指代迈阿密国际 ] for query in queries: print(f\n用户: {query}) response agent_executor.invoke({input: query}) print(f助手: {response[output]}) # 打印当前记忆观察变化 print(f当前记忆片段: {memory.buffer[:100]}...)现在运行测试你会发现智能体能够理解“他”和“这家俱乐部”的指代了。记忆让智能体更像一个真正的对话伙伴。5. 构建API服务并适配Sevalla部署一个本地运行的脚本还不够我们需要把它变成一个可以通过网络访问的API服务。Sevalla平台通常要求智能体以HTTP API的形式提供服务。我们将使用FastAPI来构建。5.1 创建FastAPI应用创建一个main.py文件。from fastapi import FastAPI, HTTPException from pydantic import BaseModel from typing import Optional import logging from agent_chain import agent_executor # 导入我们构建好的智能体执行器 # 配置日志便于在Sevalla平台查看运行状态 logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) # 初始化FastAPI应用 app FastAPI( title我的第一个AI智能体API, description一个具备联网搜索能力的AI智能体服务, version1.0.0 ) # 定义请求体模型 class AgentRequest(BaseModel): message: str session_id: Optional[str] None # 可选会话ID用于区分不同用户的记忆 # 定义响应体模型 class AgentResponse(BaseModel): reply: str session_id: Optional[str] None # 一个简单的健康检查端点Sevalla等平台会调用它来确认服务是否存活 app.get(/health) async def health_check(): return {status: healthy} # 核心的智能体交互端点 app.post(/chat, response_modelAgentResponse) async def chat_with_agent(request: AgentRequest): 与AI智能体对话。 - **message**: 用户发送的消息文本。 - **session_id**: 会话标识符。如果提供可用于隔离不同用户的对话记忆当前为简化版所有用户共享记忆。 user_input request.message.strip() if not user_input: raise HTTPException(status_code400, detail消息内容不能为空) logger.info(f收到请求: session_id{request.session_id}, message{user_input[:50]}...) try: # 调用智能体执行器 # 注意在实际生产环境中你需要根据session_id来管理独立的memory实例。 # 这里为了简化我们使用全局的agent_executor其记忆是所有请求共享的。 result agent_executor.invoke({input: user_input}) agent_output result[output] logger.info(f请求处理成功。) return AgentResponse(replyagent_output, session_idrequest.session_id) except Exception as e: logger.error(f处理请求时发生错误: {e}, exc_infoTrue) # 返回一个用户友好的错误信息而不是内部异常详情 raise HTTPException(status_code500, detail智能体处理您的请求时遇到了问题请稍后重试或简化您的问题。) # 启动应用当直接运行此脚本时 if __name__ __main__: import uvicorn # 在本地运行监听所有网络接口的8000端口 uvicorn.run(app, host0.0.0.0, port8000)5.2 本地测试API在终端运行python main.py。应用启动后你可以打开浏览器访问http://localhost:8000/docs这是FastAPI自动生成的交互式API文档Swagger UI。在/chat端点处点击“Try it out”输入{message: 今天北京天气怎么样}然后点击“Execute”。你应该能看到智能体调用搜索工具并返回天气信息。也可以用curl命令测试curl -X POST http://localhost:8000/chat \ -H Content-Type: application/json \ -d {message: 解释一下量子计算的基本原理}至此一个具备联网搜索、对话记忆功能的AI智能体后端服务就构建完成了。6. 部署到Sevalla平台Sevalla平台的目标是让AI智能体的部署变得像上传代码一样简单。虽然其具体界面和步骤可能随时间更新但核心流程通常如下6.1 准备部署文件Sevalla通常需要一个标准的项目结构。在你的项目根目录下确保有以下关键文件main.py你的FastAPI应用入口。requirements.txt所有依赖包列表。.env或通过平台界面设置环境变量重要不要在代码仓库中提交.env文件。Sevalla平台会提供一个安全的环境变量配置界面通常在应用设置的“Environment Variables”或“Secrets”部分。你需要在那里添加OPENAI_API_KEY和TAVILY_API_KEY。另外通常需要一个Dockerfile或由平台自动构建。为保险起见我们可以创建一个简单的Dockerfile# 使用官方Python轻量级镜像 FROM python:3.11-slim # 设置工作目录 WORKDIR /app # 复制依赖列表并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY . . # 暴露FastAPI默认端口 EXPOSE 8000 # 启动命令 CMD [uvicorn, main:app, --host, 0.0.0.0, --port, 8000]6.2 部署流程通用步骤注册与登录访问Sevalla官网注册账号并登录。创建新智能体在控制台找到“Create New Agent”或类似按钮。连接代码仓库大多数平台支持从GitHub、GitLab或直接上传ZIP包。将你的代码推送到GitHub仓库然后在Sevalla界面连接该仓库。或者如果你有Dockerfile也可以直接上传项目文件夹。配置构建与运行构建命令如果平台自动检测它可能会识别出你的requirements.txt和main.py。如果没有可能需要指定构建命令如pip install -r requirements.txt。启动命令指定如何启动应用即uvicorn main:app --host 0.0.0.0 --port 8000。Sevalla会告诉你容器内需要监听的端口通常是8080或8000请根据平台要求调整Dockerfile或启动命令中的端口号。设置环境变量在项目设置中找到环境变量配置页面添加OPENAI_API_KEY和TAVILY_API_KEY填入你的真实密钥。部署点击“Deploy”按钮。平台会开始拉取代码、安装依赖、构建镜像并启动容器。查看日志与测试部署完成后平台会提供一个访问你智能体的URL如https://your-agent-name.sevalla.app。使用这个URL替换之前本地测试的localhost:8000再次用curl或Postman测试/chat端点确保一切正常。实操心得在部署到生产环境前务必在本地彻底测试。特别是网络连接如Tavily API调用和依赖版本。一个常见的坑是langchain等库版本更新较快可能导致API变更。在requirements.txt中固定主版本号如langchain0.1.*是一个好习惯可以避免因自动升级到不兼容版本导致部署失败。7. 性能优化与生产环境考量一个能跑起来的智能体和一个健壮的生产级服务之间还有不少距离。以下是几个关键的优化方向7.1 管理API成本与速率限制智能体每次调用都可能涉及LLM API和搜索API这意味着成本。同时OpenAI和Tavily都有速率限制。缓存对相同或相似的查询结果进行缓存。可以使用langchain.cache配合SQLiteCache或RedisCache。例如对搜索工具的结果缓存1小时能显著减少重复调用和成本。from langchain.cache import SQLiteCache import langchain langchain.llm_cache SQLiteCache(database_path.langchain.db)设置超时与重试网络请求可能失败。为你的LLM和工具调用配置合理的超时timeout和重试逻辑retry。这可以通过LangChain的callback机制或底层HTTP客户端配置实现。监控用量定期查看OpenAI和Tavily控制台的用量统计设置预算警报。7.2 实现多用户会话隔离我们之前的例子使用了全局记忆这意味着所有用户共享同一个对话历史这显然是不对的。生产环境必须为每个用户或每个会话提供独立的记忆存储。解决方案使用一个字典来管理不同session_id对应的ConversationBufferMemory实例。from collections import defaultdict from langchain.memory import ConversationBufferMemory class SessionMemoryManager: def __init__(self): self.memories defaultdict(lambda: ConversationBufferMemory(memory_keychat_history, return_messagesTrue)) def get_memory(self, session_id: str): return self.memories[session_id] def clear_memory(self, session_id: str): if session_id in self.memories: del self.memories[session_id] # 在FastAPI应用中全局初始化一个管理器 memory_manager SessionMemoryManager() # 在/chat端点中根据request.session_id获取对应的memory # 然后使用这个memory去创建一个新的agent_executor实例注意创建执行器开销较大需要考虑缓存或池化优化当然对于高并发场景你需要将记忆存储到外部数据库如Redis中并考虑记忆的过期和清理策略。7.3 提升智能体的可靠性与安全性输入验证与清理对用户输入进行严格的检查和清理防止Prompt注入攻击。例如过滤过长的输入、检查是否有恶意指令。输出审查对智能体的回复进行后处理过滤掉不适当、有害或带有偏见的内容。可以结合第二层LLM调用进行内容安全审查。错误处理完善try...except块给用户返回友好、不暴露内部细节的错误信息同时将详细错误记录到日志系统如ELK或Sentry供开发者排查。设置迭代上限就像我们之前做的max_iterations5这能防止智能体在某些复杂问题上陷入无限循环消耗大量API资源。8. 扩展你的智能体从搜索到全能助手一个只会搜索的智能体只是起点。LangChain的强大之处在于其丰富的工具生态。你可以轻松地为你的智能体添加新能力计算与数据处理添加langchain_experimental.tools.PythonAstREPLTool让智能体能够运行安全的Python代码进行数学计算或数据处理。文件读写添加处理本地文件或云存储如S3的工具。专业领域查询接入Wolfram Alpha数学、科学、Arxiv学术论文等专业API。自动化操作结合playwright或selenium工具让智能体可以操作网页需谨慎权限控制很重要。多模态能力使用GPT-4V等视觉模型让智能体可以“看”图片并描述或分析。添加新工具通常只需要几行代码。例如添加一个计算器from langchain.tools import Tool from langchain.chains import LLMMathChain # 创建一个数学计算链 math_chain LLMMathChain.from_llm(llmllm) # 将其包装成工具 calc_tool Tool( nameCalculator, funcmath_chain.run, descriptionUseful for when you need to answer questions about math. Input should be a mathematical expression. ) # 然后将这个工具添加到你的tools列表中 tools [search_tool, calc_tool]重启你的智能体现在它就能回答“2的10次方是多少”这样的问题了。构建和部署你的第一个AI智能体就像学习骑自行车——一开始可能需要一些摸索和调试但一旦掌握了基本平衡核心架构剩下的就是不断添加新技能工具和练习更复杂的路况生产优化。通过这个项目你不仅学会了如何使用LangChain和Sevalla更重要的是你理解了AI智能体是如何将大语言模型的“思考”能力与外部工具的“行动”能力结合起来的。这个模式是通用的你可以用它来创造客服机器人、个人研究助理、自动化营销文案生成器等等。下一步尝试为你的智能体添加一个简单的Web聊天界面可以用Gradio或Streamlit快速搭建或者挑战更复杂的任务规划逻辑让它真正成为你的得力助手。