最近在尝试将AI能力集成到自己的项目中时你是否也遇到了这样的困惑网上关于Agent和Skill的资料要么是晦涩难懂的学术论文要么是零散的代码片段真正能让你从零开始、手把手搭建一个可用智能体的完整教程少之又少。很多开发者卡在环境配置、工具链选择、代码调试和工程化部署这些环节走了不少弯路。本文旨在为你提供一套从概念理解到代码落地的完整Agent Skill开发指南。我们将从一个简单的“天气查询”Skill入手逐步构建一个具备记忆、工具调用和自主决策能力的智能体。无论你是想为现有应用添加AI能力还是想探索AI Agent的开发这篇文章都将为你提供清晰的路径和可直接复用的代码。1. 智能体Agent与技能Skill核心概念解析在深入代码之前我们必须先厘清几个核心概念。这能帮助你理解我们正在构建的是什么以及为什么需要这样构建。1.1 什么是智能体Agent你可以将智能体理解为一个具备一定自主性的软件实体。它不同于传统的、被动响应请求的程序。一个典型的AI智能体通常具备以下特征感知Perception能够接收来自用户、环境或其他系统的输入如文本、图像、数据。决策Decision-making基于内部状态记忆、知识和接收到的输入通过推理如调用大语言模型决定下一步行动。执行Execution调用工具Tools或技能Skills来执行决策例如运行一段代码、查询数据库、调用API。学习与适应Learning Adaptation根据执行结果反馈更新内部状态优化未来的决策。当前基于大语言模型LLM的Agent是主流。其核心思想是利用LLM强大的理解和生成能力作为“大脑”来驱动感知、决策和部分执行过程。1.2 什么是技能Skill技能是智能体能够执行的具体、原子化的操作单元。它是智能体能力的延伸。一个技能通常对应一个明确的功能。计算技能执行数学运算、单位换算。信息查询技能调用搜索引擎API、查询数据库、获取天气、股票信息。文件操作技能读写本地文件、解析PDF/Word文档。系统控制技能执行命令行指令、控制智能家居设备。技能Skill与工具Tool的关系在大多数AI框架中这两个术语经常混用。通常“工具”是一个更底层的概念指一个可被调用的函数或API而“技能”可能是一个或多个工具的组合或者是一个封装了更复杂逻辑的功能模块。在本文中我们将统一使用“技能”来指代智能体可调用的功能单元。1.3 主流Agent开发框架与技术栈在开始实战前了解生态有助于我们选择合适的技术。目前社区活跃的框架主要有以下几类LangChain / LangGraph这是目前最流行、生态最丰富的Python框架。它提供了构建基于LLM应用的标准化组件模型I/O、记忆、索引、链、代理。LangGraph特别擅长构建有状态的、多步骤的智能体工作流。本文将主要基于LangChain进行演示。LlamaIndex最初专注于数据索引和检索现在也提供了强大的Agent和工具调用能力尤其在私有知识库问答方面表现出色。AutoGen由微软推出专注于多智能体协作场景可以轻松创建能对话、协作完成复杂任务的智能体群。Semantic Kernel微软推出的.NET/Python框架强调将传统编程与AI语义技能Semantic Skills和原生技能Native Skills相结合。其他与特定模型绑定的框架如OpenAI的Assistants API、Anthropic的Claude SDK等它们提供了开箱即用的智能体构建体验但通常与特定模型厂商绑定。我们的技术栈选择为了兼顾通用性、学习资源和社区支持本教程将使用Python LangChain OpenAI GPT模型作为核心栈。即使你后续想换用其他模型如国内大模型或框架其核心思想也是相通的。2. 环境准备与项目初始化工欲善其事必先利其器。让我们先搭建一个干净、可复现的开发环境。2.1 基础环境要求操作系统Windows 10/11, macOS, 或 Linux (如Ubuntu 20.04)。本文命令以macOS/Linux的bash为例Windows用户可在PowerShell或WSL中运行。Python版本推荐使用 Python 3.10 或 3.11。避免使用Python 3.12可能存在的某些库兼容性问题。包管理工具使用pip或更推荐的uv更快、更现代。本文将使用pip。代码编辑器VS Code、PyCharm等均可。确保安装了Python扩展。API密钥你需要一个OpenAI的API密钥。访问 OpenAI平台 创建。请妥善保管不要提交到代码仓库2.2 创建项目并安装依赖首先创建一个新的项目目录并初始化虚拟环境这是管理项目依赖的最佳实践。# 1. 创建项目目录并进入 mkdir ai-agent-tutorial cd ai-agent-tutorial # 2. 创建虚拟环境 (以venv为例) python -m venv venv # 3. 激活虚拟环境 # macOS/Linux: source venv/bin/activate # Windows: # venv\Scripts\activate # 4. 升级pip pip install --upgrade pip # 5. 安装核心依赖 pip install langchain langchain-openai langchain-community python-dotenv requests依赖包说明langchain: LangChain核心库。langchain-openai: LangChain官方维护的OpenAI集成包。langchain-community: 社区贡献的第三方集成、工具和技能。python-dotenv: 用于从.env文件加载环境变量。requests: 用于编写调用外部API的技能。2.3 项目结构与关键文件在项目根目录下创建如下文件和文件夹ai-agent-tutorial/ ├── .env # 存储敏感信息如API密钥 ├── .gitignore # Git忽略文件 ├── requirements.txt # 项目依赖清单 ├── skills/ # 自定义技能包 │ ├── __init__.py │ └── weather_skill.py # 示例天气查询技能 ├── agents/ # 智能体定义 │ ├── __init__.py │ └── basic_agent.py # 基础智能体 └── main.py # 应用主入口初始化requirements.txt文件pip freeze requirements.txt创建.gitignore文件内容至少包含venv/ .env __pycache__/ *.pyc最重要的安全步骤创建.env文件并填入你的OpenAI API密钥。切记将此文件加入.gitignore# .env OPENAI_API_KEYsk-your-actual-openai-api-key-here3. 从零构建你的第一个技能Skill技能是智能体的手脚。我们从一个最简单的“天气查询”技能开始了解技能的基本结构。3.1 技能设计模式在LangChain中一个技能通常被定义为一个“工具Tool”。一个工具需要具备名称name智能体识别该技能的唯一标识。描述description清晰描述技能的功能和输入要求。描述至关重要LLM根据描述决定是否以及如何调用该技能。参数模式args_schema定义技能所需的输入参数及其类型可选但推荐。执行函数_run包含技能核心逻辑的函数。3.2 实现天气查询技能我们将使用一个免费的天气API例如 wttr.in 来获取天气信息。首先在skills/weather_skill.py中编写代码# skills/weather_skill.py import requests from typing import Type, Optional from pydantic import BaseModel, Field from langchain.tools import BaseTool # 1. 定义技能的输入参数模型 class WeatherSkillInput(BaseModel): 输入参数模型用于验证和说明。 location: str Field(description城市名称例如北京、Shanghai、New York) # 2. 创建技能类继承自BaseTool class WeatherSkill(BaseTool): name: str get_weather description: str ( 获取指定城市的当前天气信息。 输入应该是一个明确的城市名称。 ) args_schema: Type[BaseModel] WeatherSkillInput return_direct: bool False # 设为True则技能结果直接返回给用户不经过LLM加工 def _run(self, location: str) - str: 执行技能的核心逻辑。 # 简单的错误处理 if not location or not isinstance(location, str): return 错误请输入有效的城市名称。 try: # 使用 wttr.in API设置格式和语言 url fhttps://wttr.in/{location}?format%C%t%h%wlangzh response requests.get(url, timeout10) response.raise_for_status() # 如果状态码不是200抛出HTTPError weather_data response.text.strip() if weather_data: # 解析返回的简单数据天气状况温度湿度风力 # 示例返回”晴 18°C 45% 10km/h“ parts weather_data.split() if len(parts) 4: condition, temp, humidity, wind parts[0], parts[1], parts[2], parts[3] return f{location}的天气{condition}温度{temp}湿度{humidity}风速{wind}。 else: return f{location}的天气信息{weather_data} else: return f未能获取到{location}的天气信息请检查城市名称是否正确。 except requests.exceptions.RequestException as e: # 处理网络请求错误 return f请求天气信息时出错{e} except Exception as e: # 处理其他未知错误 return f处理天气信息时发生未知错误{e} async def _arun(self, location: str) - str: 异步执行版本。如果不需要异步可以抛出NotImplementedError。 # 对于简单技能可以直接调用同步版本 # 对于IO密集型技能建议实现真正的异步逻辑 raise NotImplementedError(此技能暂不支持异步调用)代码详解WeatherSkillInput使用Pydantic定义输入参数。Field中的description会帮助LLM理解这个参数需要什么。WeatherSkill类name和description是给LLM看的“说明书”必须清晰准确。args_schema关联了输入模型让LangChain能自动验证和解析输入。_run方法是核心。我们调用外部API处理响应并返回一个给LLM或用户的字符串结果。包含了基本的错误处理网络异常、无效输入这对于生产环境至关重要。API选择我们使用了wttr.in它是一个简单、免费的天气服务。在实际项目中你可能需要注册更稳定、功能更全的天气API如和风天气、OpenWeatherMap并处理API密钥和请求限制。3.3 测试你的技能在实现智能体之前我们先单独测试一下技能是否工作。创建一个测试文件test_skill.py# test_skill.py import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) from skills.weather_skill import WeatherSkill # 实例化技能 weather_tool WeatherSkill() # 测试1正常查询 print(测试1 - 查询北京天气) result weather_tool.run(北京) print(result) print(- * 30) # 测试2查询不存在的城市模拟错误 print(测试2 - 查询不存在的城市) result weather_tool.run(SomeRandomCity123) print(result) print(- * 30) # 测试3使用invoke方法LangChain推荐 print(测试3 - 使用invoke方法查询上海) result weather_tool.invoke({location: 上海}) print(result)运行测试python test_skill.py你应该能看到类似以下的输出表明技能工作正常测试1 - 查询北京天气 北京的天气晴 18°C湿度45%风速10km/h。 ------------------------------ 测试2 - 查询不存在的城市 未能获取到SomeRandomCity123的天气信息请检查城市名称是否正确。 ------------------------------ 测试3 - 使用invoke方法查询上海 上海的天气多云 22°C湿度60%风速15km/h。4. 创建你的第一个智能体Agent有了技能我们现在需要创建一个“大脑”来指挥它。我们将使用LangChain的“ReAct”代理框架它鼓励LLM进行“推理Reasoning”和“行动Acting”。4.1 智能体核心组件一个基本的智能体需要以下部分LLM智能体的推理引擎。我们使用OpenAI的GPT模型。工具技能列表智能体可以调用的技能集合。代理执行器AgentExecutor负责运行代理循环处理LLM的输出调用工具并将结果反馈给LLM直到得到最终答案。4.2 构建基础智能体在agents/basic_agent.py中编写代码# agents/basic_agent.py import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_react_agent from langchain_core.prompts import PromptTemplate from skills.weather_skill import WeatherSkill # 加载环境变量中的API密钥 load_dotenv() openai_api_key os.getenv(OPENAI_API_KEY) if not openai_api_key: raise ValueError(请在 .env 文件中设置 OPENAI_API_KEY) class BasicAgent: def __init__(self, model_name: str gpt-3.5-turbo, temperature: float 0.1): 初始化基础智能体。 Args: model_name: 使用的OpenAI模型名称。 temperature: 模型创造性越低越确定越高越随机。 # 1. 初始化LLM self.llm ChatOpenAI( modelmodel_name, temperaturetemperature, openai_api_keyopenai_api_key ) # 2. 准备工具列表 self.tools [WeatherSkill()] # 目前只有天气技能后续可以添加更多 # 3. 定义ReAct风格的提示词模板 # 这个模板指导LLM如何思考Reason和行动Act self.prompt_template PromptTemplate.from_template( 你是一个乐于助人的AI助手。你可以使用工具来帮助你回答问题。 如果你不知道答案请诚实地说你不知道不要编造信息。 你可以使用的工具 {tools} 使用以下格式回答 问题用户提出的问题 思考你需要思考如何一步步解决问题。如果你需要使用工具请在这里说明。 行动需要调用的工具名称必须是以下之一[{tool_names}] 行动输入调用该工具所需的输入必须是一个简单的字符串 观察工具返回的结果 ... (这个 思考/行动/行动输入/观察 循环可以重复多次) 最终答案根据所有观察得出的最终答案 开始 问题{input} 思考{agent_scratchpad} ) # 4. 创建代理 self.agent create_react_agent( llmself.llm, toolsself.tools, promptself.prompt_template ) # 5. 创建代理执行器控制循环次数和错误处理 self.agent_executor AgentExecutor( agentself.agent, toolsself.tools, verboseTrue, # 设为True可以看到详细的思考过程调试时非常有用 handle_parsing_errorsTrue, # 处理LLM输出解析错误 max_iterations5, # 限制最大循环次数防止无限循环 early_stopping_methodgenerate # 当LLM生成最终答案时停止 ) def run(self, query: str) - str: 运行智能体处理用户查询。 try: result self.agent_executor.invoke({input: query}) return result.get(output, 智能体未返回有效输出。) except Exception as e: return f智能体执行过程中出错{e}关键点解析提示词模板这是智能体的“操作规程”。它明确告诉LLM你的角色是什么。你可以使用哪些工具{tools}和{tool_names}会被自动替换。必须遵循“思考-行动-观察”的格式。最终必须给出“最终答案”。create_react_agentLangChain提供的快捷函数用于创建基于ReAct框架的代理。AgentExecutor它是智能体的“引擎”。verboseTrue会在控制台打印出LLM的思考过程和工具调用详情是调试的神器。max_iterations防止智能体陷入死循环。错误处理在run方法中包裹了try-except确保应用不会因为单次查询失败而崩溃。4.3 运行并测试智能体现在创建主程序入口main.py# main.py import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) from agents.basic_agent import BasicAgent def main(): print(初始化智能体...) agent BasicAgent(model_namegpt-3.5-turbo) # 也可以使用 gpt-4 print(智能体就绪输入您的问题输入 quit 或 exit 退出) print(- * 40) while True: try: user_input input(\n您) if user_input.lower() in [quit, exit, q]: print(再见) break if not user_input.strip(): continue print(\n智能体正在思考...) response agent.run(user_input) print(f\n助手{response}) except KeyboardInterrupt: print(\n\n程序被中断。) break except Exception as e: print(f\n发生错误{e}) if __name__ __main__: main()运行你的第一个AI智能体python main.py尝试进行对话初始化智能体... 智能体就绪输入您的问题输入 quit 或 exit 退出 ---------------------------------------- 您今天北京天气怎么样 智能体正在思考... 控制台会输出verbose日志显示思考过程、工具调用和结果 进入新的AgentExecutor链... 思考用户想知道北京的天气我需要使用天气查询工具。 行动get_weather 行动输入北京 观察北京的天气晴 18°C湿度45%风速10km/h。 思考我已经获得了北京的天气信息可以给出最终答案。 最终答案今天北京天气晴朗气温大约18摄氏度湿度45%风速10公里每小时。 助手今天北京天气晴朗气温大约18摄氏度湿度45%风速10公里每小时。恭喜你已经成功创建了一个能够理解自然语言、自主调用工具并给出回答的AI智能体。5. 扩展智能体添加更多技能与记忆一个只会查天气的智能体显然不够。让我们增强它的能力并赋予它“记忆”。5.1 添加计算与时间技能在skills/目录下创建math_skill.py和time_skill.py。# skills/math_skill.py from typing import Type from pydantic import BaseModel, Field from langchain.tools import BaseTool import math class MathSkillInput(BaseModel): expression: str Field(description一个有效的数学表达式例如3 5 * 2 或 sqrt(16)) class MathSkill(BaseTool): name: str calculator description: str 计算一个数学表达式的值。支持加减乘除(, -, *, /)、乘方(**)、括号和常见函数如sqrt, sin, cos, log等。 args_schema: Type[BaseModel] MathSkillInput def _run(self, expression: str) - str: 使用eval计算表达式但要注意安全性 # 警告在生产环境中直接使用eval是危险的可能造成代码注入。 # 这里仅用于演示。实际项目应使用安全的表达式解析库如 ast.literal_eval, numexpr。 try: # 添加一些常用的数学函数到命名空间确保安全 safe_dict {__builtins__: None} safe_dict.update({k: getattr(math, k) for k in dir(math) if not k.startswith(_)}) safe_dict.update({abs: abs, round: round}) # 非常基础的过滤防止恶意代码 if any(keyword in expression.lower() for keyword in [import, exec, eval, open, file, os, sys]): return 错误表达式中包含不安全的关键字。 result eval(expression, {__builtins__: {}}, safe_dict) return f{expression} {result} except Exception as e: return f计算表达式 {expression} 时出错{e} async def _arun(self, expression: str): raise NotImplementedError(计算器暂不支持异步调用)# skills/time_skill.py from typing import Type from pydantic import BaseModel, Field from langchain.tools import BaseTool from datetime import datetime class TimeSkillInput(BaseModel): # 这个技能不需要输入但为了统一我们定义一个空模型或带可选参数的模型 pass class TimeSkill(BaseTool): name: str get_current_time description: str 获取当前的日期和时间。当用户询问‘现在几点’、‘今天几号’、‘当前时间’时使用此工具。 args_schema: Type[BaseModel] TimeSkillInput def _run(self, *args, **kwargs) - str: 返回当前时间。 now datetime.now() # 格式化成易读的字符串 return now.strftime(当前日期和时间是%Y年%m月%d日 %H时%M分%S秒) async def _arun(self): raise NotImplementedError(时间工具暂不支持异步调用)5.2 为智能体添加对话记忆没有记忆的智能体每次对话都是独立的。我们需要让它记住之前的对话内容。LangChain提供了多种记忆后端这里使用简单的ConversationBufferMemory。更新agents/basic_agent.py将其升级为agents/advanced_agent.py# agents/advanced_agent.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_core.prompts import PromptTemplate, MessagesPlaceholder from langchain_core.messages import SystemMessage from skills.weather_skill import WeatherSkill from skills.math_skill import MathSkill from skills.time_skill import TimeSkill load_dotenv() openai_api_key os.getenv(OPENAI_API_KEY) class AdvancedAgent: def __init__(self, model_name: str gpt-3.5-turbo, temperature: float 0.1): self.llm ChatOpenAI(modelmodel_name, temperaturetemperature, openai_api_keyopenai_api_key) # 1. 集成更多技能 self.tools [WeatherSkill(), MathSkill(), TimeSkill()] # 2. 创建对话记忆 self.memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # 3. 构建包含记忆的提示词 # 系统消息定义角色 system_message SystemMessage(content你是一个功能强大的AI助手名叫‘智囊’。你友好、专业并且可以使用工具来帮助用户。 如果你不知道答案请诚实地说你不知道。在回答时请参考之前的对话历史如果存在来使对话更连贯。) # 提示词模板包含工具描述、聊天历史占位符和用户输入 prompt PromptTemplate.from_template( template {system_message} 以下是当前的对话历史 {chat_history} 你可以使用以下工具 {tools} 请严格按照以下格式回应 思考首先分析用户的问题并参考对话历史。决定是否需要使用工具。 行动需要调用的工具名称必须是以下之一[{tool_names}] 行动输入调用该工具所需的输入 观察工具返回的结果 ... (重复思考/行动/观察直到可以回答问题) 最终答案给用户的最终回复 当前问题{input} {agent_scratchpad} , partial_variables{ system_message: system_message, tool_names: , .join([tool.name for tool in self.tools]), } ) # 注意这里我们使用from_template但需要手动处理chat_history和agent_scratchpad的注入。 # 更简洁的方式是使用ChatPromptTemplate但为了清晰我们稍作调整。 # 4. 使用LangChain的create_react_agent它已经很好地集成了记忆 # 我们需要一个包含MessagesPlaceholder的ChatPromptTemplate from langchain_core.prompts import ChatPromptTemplate prompt ChatPromptTemplate.from_messages([ system_message, MessagesPlaceholder(variable_namechat_history), (human, {input}), MessagesPlaceholder(variable_nameagent_scratchpad) ]) self.agent create_react_agent(llmself.llm, toolsself.tools, promptprompt) # 5. 创建执行器传入记忆 self.agent_executor AgentExecutor( agentself.agent, toolsself.tools, memoryself.memory, verboseTrue, handle_parsing_errorsTrue, max_iterations7, early_stopping_methodgenerate ) def run(self, query: str) - str: try: result self.agent_executor.invoke({input: query}) return result.get(output, 智能体未返回有效输出。) except Exception as e: return f智能体执行过程中出错{e} def clear_memory(self): 清空对话记忆。 self.memory.clear()主要改进更多工具集成了计算器和时间查询工具。对话记忆ConversationBufferMemory保存了完整的对话历史。memory_keychat_history指定了在提示词中插入历史的位置。提示词优化使用了ChatPromptTemplate和MessagesPlaceholder来更优雅地处理系统消息、对话历史和代理的临时思考记录agent_scratchpad。清空记忆方法提供了clear_memory方法用于开始新一轮对话。5.3 测试增强版智能体更新main.py来使用新的智能体并测试其记忆和多功能# main.py (更新版) import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) from agents.advanced_agent import AdvancedAgent def main(): print(初始化高级智能体带记忆和多技能...) agent AdvancedAgent(model_namegpt-3.5-turbo) print(智能体‘智囊’已上线输入您的问题输入 clear 清空记忆quit 退出) print(- * 50) while True: try: user_input input(\n您) if user_input.lower() in [quit, exit, q]: print(再见) break if user_input.lower() clear: agent.clear_memory() print(对话记忆已清空。) continue if not user_input.strip(): continue print(\n智囊正在思考...) response agent.run(user_input) print(f\n智囊{response}) except KeyboardInterrupt: print(\n\n程序被中断。) break except Exception as e: print(f\n发生错误{e}) if __name__ __main__: main()现在运行python main.py体验更强大的对话您计算一下 15 的平方加上 20 的三次方是多少 智囊调用计算器工具得到结果。最终回答你。 您现在几点了 智囊调用时间工具告诉你当前时间。 您我刚才让你计算了什么 智囊依靠记忆你刚才让我计算了 15 的平方加上 20 的三次方结果是...你可以看到智能体现在能记住上下文并且能灵活运用多个技能。6. 常见问题与排查指南FAQ在开发和使用Agent过程中你一定会遇到各种问题。以下是典型问题及其解决方案。6.1 智能体不调用工具现象LLM直接回答了问题而没有调用你提供的工具。可能原因与解决工具描述不清晰检查技能的description字段。它必须极其清晰、无歧义地说明技能的功能和适用场景。LLM完全依赖这个描述做决策。提示词模板问题确保你的提示词模板明确要求LLM遵循“思考-行动”的格式。ReAct模板通常效果很好。模型能力不足过于简单或陈旧的模型可能无法很好理解工具调用。尝试切换到更强大的模型如gpt-4或gpt-4-turbo。问题太简单如果问题LLM本身就能回答如常识问题它可能不会调用工具。你可以通过系统提示词强制要求“对于涉及实时数据、计算或特定操作的问题必须使用工具”。6.2 智能体陷入循环或调用错误工具现象智能体反复调用同一个工具或调用一个不相关的工具。可能原因与解决工具描述重叠如果两个技能的描述太相似LLM可能会混淆。确保每个技能的描述独一无二。max_iterations设置过小或过大太小可能导致任务未完成就停止太大可能导致死循环。根据任务复杂度调整一般5-10次。观察结果不清晰工具返回的结果_run方法的输出应该清晰、结构化。如果结果混乱或包含错误信息LLM可能无法理解导致后续决策错误。确保工具返回有意义、简洁的字符串。6.3 解析错误Parsing Errors现象控制台报错OutputParserException或类似错误。可能原因与解决LLM输出格式不符合预期ReAct代理期望LLM严格按照“思考...行动...行动输入...”的格式输出。有时LLM会“放飞自我”。可以尝试在提示词中更加强调格式。使用handle_parsing_errorsTrue参数我们已经设置让执行器在解析失败时尝试让LLM重试或修复格式。使用更稳定的模型。工具参数错误LLM生成的“行动输入”可能不符合args_schema的定义。确保你的参数描述Field(description...)足够明确。6.4 API密钥与网络问题现象AuthenticationError或连接超时。解决检查.env文件中的OPENAI_API_KEY是否正确且没有多余空格。确认网络环境可以访问OpenAI API。如果你在国内可能需要配置网络环境。检查OpenAI账户是否有余额或调用额度。6.5 性能与成本优化现象响应慢或API调用费用高。优化建议选择合适的模型对于简单任务gpt-3.5-turbo性价比最高。对于复杂推理和工具调用gpt-4效果更好但更贵。限制对话轮次通过max_iterations严格控制。使用缓存LangChain支持LLM调用缓存如InMemoryCache,SQLiteCache对于重复问题可以显著节省成本和时间。流式传输Streaming对于长文本生成使用流式输出可以提升用户体验。7. 工程化最佳实践与进阶方向当你掌握了基础开发后要将智能体投入实际项目还需要考虑以下方面。7.1 技能开发规范单一职责一个技能只做一件事。不要编写一个“万能”技能。健壮的错误处理技能必须能处理各种边界情况和异常网络超时、无效输入、API限流等并返回友好的错误信息而不是抛出异常导致智能体崩溃。输入验证与安全永远不要信任来自LLM或用户的输入。使用args_schema进行类型验证。对于像计算器这样需要执行代码的技能必须使用安全的表达式求值库如ast.literal_eval或numexpr替代eval。清晰的文档为每个技能编写详细的docstring说明其功能、输入输出格式和可能的错误。7.2 智能体设计模式规划Planning对于复杂任务让智能体先制定计划再执行。可以使用LLMChain生成步骤或使用LangGraph构建有状态的工作流。多智能体协作使用像AutoGen这样的框架创建多个各司其职的智能体如规划者、执行者、审核者进行协作。工具检索Tool Retrieval当工具数量很多时几十上百个让LLM从所有工具中挑选合适的变得低效。可以实现一个“工具检索器”根据用户问题语义搜索最相关的几个工具再交给LLM决策。7.3 生产环境部署配置管理使用环境变量或专业的配置管理工具如Azure App Configuration, AWS Parameter Store管理API密钥、模型参数等敏感信息。日志与监控记录智能体的所有决策、工具调用和结果。这对于调试、优化和审计至关重要。可以集成像LangSmith这样的LangChain官方追踪平台。速率限制与重试为LLM API和第三方工具API添加速率限制和指数退避重试机制。异步与并发对于IO密集型技能如网络请求实现其_arun异步方法并使用异步代理执行器AgentExecutor的异步版本来提高吞吐量。容器化使用Docker将你的智能体应用打包确保环境一致性便于在云服务器或Kubernetes上部署。7.4 后续学习路线深入LangChain学习Chains用于固定流程、Indexes用于检索增强生成RAG、Memory的各种实现向量存储记忆、窗口记忆等。探索LangGraph用于构建复杂、有状态、可循环的智能体工作流是构建高级Agent的利器。集成向量数据库为智能体添加长期记忆和知识库如使用Chroma, Pinecone, Weaviate使其能回答基于私有文档的问题。尝试其他框架了解AutoGen多智能体、Semantic Kernel微软系、LlamaIndex专注RAG等拓宽视野。关注开源项目在GitHub上关注langchain-ai、microsoft/autogen等官方仓库学习社区的最佳实践和新兴模式。从构建一个简单的天气查询技能到创建一个具备记忆和多技能协作的智能体你已经走完了AI Agent开发的核心路径。记住Agent开发是一个迭代过程从定义清晰的任务开始设计并实现可靠的技能然后通过精心设计的提示词和记忆机制将它们组合起来最后在真实场景中测试和优化。
从零构建AI智能体:基于LangChain的Agent与Skill开发实战指南
发布时间:2026/7/1 3:44:03
最近在尝试将AI能力集成到自己的项目中时你是否也遇到了这样的困惑网上关于Agent和Skill的资料要么是晦涩难懂的学术论文要么是零散的代码片段真正能让你从零开始、手把手搭建一个可用智能体的完整教程少之又少。很多开发者卡在环境配置、工具链选择、代码调试和工程化部署这些环节走了不少弯路。本文旨在为你提供一套从概念理解到代码落地的完整Agent Skill开发指南。我们将从一个简单的“天气查询”Skill入手逐步构建一个具备记忆、工具调用和自主决策能力的智能体。无论你是想为现有应用添加AI能力还是想探索AI Agent的开发这篇文章都将为你提供清晰的路径和可直接复用的代码。1. 智能体Agent与技能Skill核心概念解析在深入代码之前我们必须先厘清几个核心概念。这能帮助你理解我们正在构建的是什么以及为什么需要这样构建。1.1 什么是智能体Agent你可以将智能体理解为一个具备一定自主性的软件实体。它不同于传统的、被动响应请求的程序。一个典型的AI智能体通常具备以下特征感知Perception能够接收来自用户、环境或其他系统的输入如文本、图像、数据。决策Decision-making基于内部状态记忆、知识和接收到的输入通过推理如调用大语言模型决定下一步行动。执行Execution调用工具Tools或技能Skills来执行决策例如运行一段代码、查询数据库、调用API。学习与适应Learning Adaptation根据执行结果反馈更新内部状态优化未来的决策。当前基于大语言模型LLM的Agent是主流。其核心思想是利用LLM强大的理解和生成能力作为“大脑”来驱动感知、决策和部分执行过程。1.2 什么是技能Skill技能是智能体能够执行的具体、原子化的操作单元。它是智能体能力的延伸。一个技能通常对应一个明确的功能。计算技能执行数学运算、单位换算。信息查询技能调用搜索引擎API、查询数据库、获取天气、股票信息。文件操作技能读写本地文件、解析PDF/Word文档。系统控制技能执行命令行指令、控制智能家居设备。技能Skill与工具Tool的关系在大多数AI框架中这两个术语经常混用。通常“工具”是一个更底层的概念指一个可被调用的函数或API而“技能”可能是一个或多个工具的组合或者是一个封装了更复杂逻辑的功能模块。在本文中我们将统一使用“技能”来指代智能体可调用的功能单元。1.3 主流Agent开发框架与技术栈在开始实战前了解生态有助于我们选择合适的技术。目前社区活跃的框架主要有以下几类LangChain / LangGraph这是目前最流行、生态最丰富的Python框架。它提供了构建基于LLM应用的标准化组件模型I/O、记忆、索引、链、代理。LangGraph特别擅长构建有状态的、多步骤的智能体工作流。本文将主要基于LangChain进行演示。LlamaIndex最初专注于数据索引和检索现在也提供了强大的Agent和工具调用能力尤其在私有知识库问答方面表现出色。AutoGen由微软推出专注于多智能体协作场景可以轻松创建能对话、协作完成复杂任务的智能体群。Semantic Kernel微软推出的.NET/Python框架强调将传统编程与AI语义技能Semantic Skills和原生技能Native Skills相结合。其他与特定模型绑定的框架如OpenAI的Assistants API、Anthropic的Claude SDK等它们提供了开箱即用的智能体构建体验但通常与特定模型厂商绑定。我们的技术栈选择为了兼顾通用性、学习资源和社区支持本教程将使用Python LangChain OpenAI GPT模型作为核心栈。即使你后续想换用其他模型如国内大模型或框架其核心思想也是相通的。2. 环境准备与项目初始化工欲善其事必先利其器。让我们先搭建一个干净、可复现的开发环境。2.1 基础环境要求操作系统Windows 10/11, macOS, 或 Linux (如Ubuntu 20.04)。本文命令以macOS/Linux的bash为例Windows用户可在PowerShell或WSL中运行。Python版本推荐使用 Python 3.10 或 3.11。避免使用Python 3.12可能存在的某些库兼容性问题。包管理工具使用pip或更推荐的uv更快、更现代。本文将使用pip。代码编辑器VS Code、PyCharm等均可。确保安装了Python扩展。API密钥你需要一个OpenAI的API密钥。访问 OpenAI平台 创建。请妥善保管不要提交到代码仓库2.2 创建项目并安装依赖首先创建一个新的项目目录并初始化虚拟环境这是管理项目依赖的最佳实践。# 1. 创建项目目录并进入 mkdir ai-agent-tutorial cd ai-agent-tutorial # 2. 创建虚拟环境 (以venv为例) python -m venv venv # 3. 激活虚拟环境 # macOS/Linux: source venv/bin/activate # Windows: # venv\Scripts\activate # 4. 升级pip pip install --upgrade pip # 5. 安装核心依赖 pip install langchain langchain-openai langchain-community python-dotenv requests依赖包说明langchain: LangChain核心库。langchain-openai: LangChain官方维护的OpenAI集成包。langchain-community: 社区贡献的第三方集成、工具和技能。python-dotenv: 用于从.env文件加载环境变量。requests: 用于编写调用外部API的技能。2.3 项目结构与关键文件在项目根目录下创建如下文件和文件夹ai-agent-tutorial/ ├── .env # 存储敏感信息如API密钥 ├── .gitignore # Git忽略文件 ├── requirements.txt # 项目依赖清单 ├── skills/ # 自定义技能包 │ ├── __init__.py │ └── weather_skill.py # 示例天气查询技能 ├── agents/ # 智能体定义 │ ├── __init__.py │ └── basic_agent.py # 基础智能体 └── main.py # 应用主入口初始化requirements.txt文件pip freeze requirements.txt创建.gitignore文件内容至少包含venv/ .env __pycache__/ *.pyc最重要的安全步骤创建.env文件并填入你的OpenAI API密钥。切记将此文件加入.gitignore# .env OPENAI_API_KEYsk-your-actual-openai-api-key-here3. 从零构建你的第一个技能Skill技能是智能体的手脚。我们从一个最简单的“天气查询”技能开始了解技能的基本结构。3.1 技能设计模式在LangChain中一个技能通常被定义为一个“工具Tool”。一个工具需要具备名称name智能体识别该技能的唯一标识。描述description清晰描述技能的功能和输入要求。描述至关重要LLM根据描述决定是否以及如何调用该技能。参数模式args_schema定义技能所需的输入参数及其类型可选但推荐。执行函数_run包含技能核心逻辑的函数。3.2 实现天气查询技能我们将使用一个免费的天气API例如 wttr.in 来获取天气信息。首先在skills/weather_skill.py中编写代码# skills/weather_skill.py import requests from typing import Type, Optional from pydantic import BaseModel, Field from langchain.tools import BaseTool # 1. 定义技能的输入参数模型 class WeatherSkillInput(BaseModel): 输入参数模型用于验证和说明。 location: str Field(description城市名称例如北京、Shanghai、New York) # 2. 创建技能类继承自BaseTool class WeatherSkill(BaseTool): name: str get_weather description: str ( 获取指定城市的当前天气信息。 输入应该是一个明确的城市名称。 ) args_schema: Type[BaseModel] WeatherSkillInput return_direct: bool False # 设为True则技能结果直接返回给用户不经过LLM加工 def _run(self, location: str) - str: 执行技能的核心逻辑。 # 简单的错误处理 if not location or not isinstance(location, str): return 错误请输入有效的城市名称。 try: # 使用 wttr.in API设置格式和语言 url fhttps://wttr.in/{location}?format%C%t%h%wlangzh response requests.get(url, timeout10) response.raise_for_status() # 如果状态码不是200抛出HTTPError weather_data response.text.strip() if weather_data: # 解析返回的简单数据天气状况温度湿度风力 # 示例返回”晴 18°C 45% 10km/h“ parts weather_data.split() if len(parts) 4: condition, temp, humidity, wind parts[0], parts[1], parts[2], parts[3] return f{location}的天气{condition}温度{temp}湿度{humidity}风速{wind}。 else: return f{location}的天气信息{weather_data} else: return f未能获取到{location}的天气信息请检查城市名称是否正确。 except requests.exceptions.RequestException as e: # 处理网络请求错误 return f请求天气信息时出错{e} except Exception as e: # 处理其他未知错误 return f处理天气信息时发生未知错误{e} async def _arun(self, location: str) - str: 异步执行版本。如果不需要异步可以抛出NotImplementedError。 # 对于简单技能可以直接调用同步版本 # 对于IO密集型技能建议实现真正的异步逻辑 raise NotImplementedError(此技能暂不支持异步调用)代码详解WeatherSkillInput使用Pydantic定义输入参数。Field中的description会帮助LLM理解这个参数需要什么。WeatherSkill类name和description是给LLM看的“说明书”必须清晰准确。args_schema关联了输入模型让LangChain能自动验证和解析输入。_run方法是核心。我们调用外部API处理响应并返回一个给LLM或用户的字符串结果。包含了基本的错误处理网络异常、无效输入这对于生产环境至关重要。API选择我们使用了wttr.in它是一个简单、免费的天气服务。在实际项目中你可能需要注册更稳定、功能更全的天气API如和风天气、OpenWeatherMap并处理API密钥和请求限制。3.3 测试你的技能在实现智能体之前我们先单独测试一下技能是否工作。创建一个测试文件test_skill.py# test_skill.py import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) from skills.weather_skill import WeatherSkill # 实例化技能 weather_tool WeatherSkill() # 测试1正常查询 print(测试1 - 查询北京天气) result weather_tool.run(北京) print(result) print(- * 30) # 测试2查询不存在的城市模拟错误 print(测试2 - 查询不存在的城市) result weather_tool.run(SomeRandomCity123) print(result) print(- * 30) # 测试3使用invoke方法LangChain推荐 print(测试3 - 使用invoke方法查询上海) result weather_tool.invoke({location: 上海}) print(result)运行测试python test_skill.py你应该能看到类似以下的输出表明技能工作正常测试1 - 查询北京天气 北京的天气晴 18°C湿度45%风速10km/h。 ------------------------------ 测试2 - 查询不存在的城市 未能获取到SomeRandomCity123的天气信息请检查城市名称是否正确。 ------------------------------ 测试3 - 使用invoke方法查询上海 上海的天气多云 22°C湿度60%风速15km/h。4. 创建你的第一个智能体Agent有了技能我们现在需要创建一个“大脑”来指挥它。我们将使用LangChain的“ReAct”代理框架它鼓励LLM进行“推理Reasoning”和“行动Acting”。4.1 智能体核心组件一个基本的智能体需要以下部分LLM智能体的推理引擎。我们使用OpenAI的GPT模型。工具技能列表智能体可以调用的技能集合。代理执行器AgentExecutor负责运行代理循环处理LLM的输出调用工具并将结果反馈给LLM直到得到最终答案。4.2 构建基础智能体在agents/basic_agent.py中编写代码# agents/basic_agent.py import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_react_agent from langchain_core.prompts import PromptTemplate from skills.weather_skill import WeatherSkill # 加载环境变量中的API密钥 load_dotenv() openai_api_key os.getenv(OPENAI_API_KEY) if not openai_api_key: raise ValueError(请在 .env 文件中设置 OPENAI_API_KEY) class BasicAgent: def __init__(self, model_name: str gpt-3.5-turbo, temperature: float 0.1): 初始化基础智能体。 Args: model_name: 使用的OpenAI模型名称。 temperature: 模型创造性越低越确定越高越随机。 # 1. 初始化LLM self.llm ChatOpenAI( modelmodel_name, temperaturetemperature, openai_api_keyopenai_api_key ) # 2. 准备工具列表 self.tools [WeatherSkill()] # 目前只有天气技能后续可以添加更多 # 3. 定义ReAct风格的提示词模板 # 这个模板指导LLM如何思考Reason和行动Act self.prompt_template PromptTemplate.from_template( 你是一个乐于助人的AI助手。你可以使用工具来帮助你回答问题。 如果你不知道答案请诚实地说你不知道不要编造信息。 你可以使用的工具 {tools} 使用以下格式回答 问题用户提出的问题 思考你需要思考如何一步步解决问题。如果你需要使用工具请在这里说明。 行动需要调用的工具名称必须是以下之一[{tool_names}] 行动输入调用该工具所需的输入必须是一个简单的字符串 观察工具返回的结果 ... (这个 思考/行动/行动输入/观察 循环可以重复多次) 最终答案根据所有观察得出的最终答案 开始 问题{input} 思考{agent_scratchpad} ) # 4. 创建代理 self.agent create_react_agent( llmself.llm, toolsself.tools, promptself.prompt_template ) # 5. 创建代理执行器控制循环次数和错误处理 self.agent_executor AgentExecutor( agentself.agent, toolsself.tools, verboseTrue, # 设为True可以看到详细的思考过程调试时非常有用 handle_parsing_errorsTrue, # 处理LLM输出解析错误 max_iterations5, # 限制最大循环次数防止无限循环 early_stopping_methodgenerate # 当LLM生成最终答案时停止 ) def run(self, query: str) - str: 运行智能体处理用户查询。 try: result self.agent_executor.invoke({input: query}) return result.get(output, 智能体未返回有效输出。) except Exception as e: return f智能体执行过程中出错{e}关键点解析提示词模板这是智能体的“操作规程”。它明确告诉LLM你的角色是什么。你可以使用哪些工具{tools}和{tool_names}会被自动替换。必须遵循“思考-行动-观察”的格式。最终必须给出“最终答案”。create_react_agentLangChain提供的快捷函数用于创建基于ReAct框架的代理。AgentExecutor它是智能体的“引擎”。verboseTrue会在控制台打印出LLM的思考过程和工具调用详情是调试的神器。max_iterations防止智能体陷入死循环。错误处理在run方法中包裹了try-except确保应用不会因为单次查询失败而崩溃。4.3 运行并测试智能体现在创建主程序入口main.py# main.py import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) from agents.basic_agent import BasicAgent def main(): print(初始化智能体...) agent BasicAgent(model_namegpt-3.5-turbo) # 也可以使用 gpt-4 print(智能体就绪输入您的问题输入 quit 或 exit 退出) print(- * 40) while True: try: user_input input(\n您) if user_input.lower() in [quit, exit, q]: print(再见) break if not user_input.strip(): continue print(\n智能体正在思考...) response agent.run(user_input) print(f\n助手{response}) except KeyboardInterrupt: print(\n\n程序被中断。) break except Exception as e: print(f\n发生错误{e}) if __name__ __main__: main()运行你的第一个AI智能体python main.py尝试进行对话初始化智能体... 智能体就绪输入您的问题输入 quit 或 exit 退出 ---------------------------------------- 您今天北京天气怎么样 智能体正在思考... 控制台会输出verbose日志显示思考过程、工具调用和结果 进入新的AgentExecutor链... 思考用户想知道北京的天气我需要使用天气查询工具。 行动get_weather 行动输入北京 观察北京的天气晴 18°C湿度45%风速10km/h。 思考我已经获得了北京的天气信息可以给出最终答案。 最终答案今天北京天气晴朗气温大约18摄氏度湿度45%风速10公里每小时。 助手今天北京天气晴朗气温大约18摄氏度湿度45%风速10公里每小时。恭喜你已经成功创建了一个能够理解自然语言、自主调用工具并给出回答的AI智能体。5. 扩展智能体添加更多技能与记忆一个只会查天气的智能体显然不够。让我们增强它的能力并赋予它“记忆”。5.1 添加计算与时间技能在skills/目录下创建math_skill.py和time_skill.py。# skills/math_skill.py from typing import Type from pydantic import BaseModel, Field from langchain.tools import BaseTool import math class MathSkillInput(BaseModel): expression: str Field(description一个有效的数学表达式例如3 5 * 2 或 sqrt(16)) class MathSkill(BaseTool): name: str calculator description: str 计算一个数学表达式的值。支持加减乘除(, -, *, /)、乘方(**)、括号和常见函数如sqrt, sin, cos, log等。 args_schema: Type[BaseModel] MathSkillInput def _run(self, expression: str) - str: 使用eval计算表达式但要注意安全性 # 警告在生产环境中直接使用eval是危险的可能造成代码注入。 # 这里仅用于演示。实际项目应使用安全的表达式解析库如 ast.literal_eval, numexpr。 try: # 添加一些常用的数学函数到命名空间确保安全 safe_dict {__builtins__: None} safe_dict.update({k: getattr(math, k) for k in dir(math) if not k.startswith(_)}) safe_dict.update({abs: abs, round: round}) # 非常基础的过滤防止恶意代码 if any(keyword in expression.lower() for keyword in [import, exec, eval, open, file, os, sys]): return 错误表达式中包含不安全的关键字。 result eval(expression, {__builtins__: {}}, safe_dict) return f{expression} {result} except Exception as e: return f计算表达式 {expression} 时出错{e} async def _arun(self, expression: str): raise NotImplementedError(计算器暂不支持异步调用)# skills/time_skill.py from typing import Type from pydantic import BaseModel, Field from langchain.tools import BaseTool from datetime import datetime class TimeSkillInput(BaseModel): # 这个技能不需要输入但为了统一我们定义一个空模型或带可选参数的模型 pass class TimeSkill(BaseTool): name: str get_current_time description: str 获取当前的日期和时间。当用户询问‘现在几点’、‘今天几号’、‘当前时间’时使用此工具。 args_schema: Type[BaseModel] TimeSkillInput def _run(self, *args, **kwargs) - str: 返回当前时间。 now datetime.now() # 格式化成易读的字符串 return now.strftime(当前日期和时间是%Y年%m月%d日 %H时%M分%S秒) async def _arun(self): raise NotImplementedError(时间工具暂不支持异步调用)5.2 为智能体添加对话记忆没有记忆的智能体每次对话都是独立的。我们需要让它记住之前的对话内容。LangChain提供了多种记忆后端这里使用简单的ConversationBufferMemory。更新agents/basic_agent.py将其升级为agents/advanced_agent.py# agents/advanced_agent.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_core.prompts import PromptTemplate, MessagesPlaceholder from langchain_core.messages import SystemMessage from skills.weather_skill import WeatherSkill from skills.math_skill import MathSkill from skills.time_skill import TimeSkill load_dotenv() openai_api_key os.getenv(OPENAI_API_KEY) class AdvancedAgent: def __init__(self, model_name: str gpt-3.5-turbo, temperature: float 0.1): self.llm ChatOpenAI(modelmodel_name, temperaturetemperature, openai_api_keyopenai_api_key) # 1. 集成更多技能 self.tools [WeatherSkill(), MathSkill(), TimeSkill()] # 2. 创建对话记忆 self.memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # 3. 构建包含记忆的提示词 # 系统消息定义角色 system_message SystemMessage(content你是一个功能强大的AI助手名叫‘智囊’。你友好、专业并且可以使用工具来帮助用户。 如果你不知道答案请诚实地说你不知道。在回答时请参考之前的对话历史如果存在来使对话更连贯。) # 提示词模板包含工具描述、聊天历史占位符和用户输入 prompt PromptTemplate.from_template( template {system_message} 以下是当前的对话历史 {chat_history} 你可以使用以下工具 {tools} 请严格按照以下格式回应 思考首先分析用户的问题并参考对话历史。决定是否需要使用工具。 行动需要调用的工具名称必须是以下之一[{tool_names}] 行动输入调用该工具所需的输入 观察工具返回的结果 ... (重复思考/行动/观察直到可以回答问题) 最终答案给用户的最终回复 当前问题{input} {agent_scratchpad} , partial_variables{ system_message: system_message, tool_names: , .join([tool.name for tool in self.tools]), } ) # 注意这里我们使用from_template但需要手动处理chat_history和agent_scratchpad的注入。 # 更简洁的方式是使用ChatPromptTemplate但为了清晰我们稍作调整。 # 4. 使用LangChain的create_react_agent它已经很好地集成了记忆 # 我们需要一个包含MessagesPlaceholder的ChatPromptTemplate from langchain_core.prompts import ChatPromptTemplate prompt ChatPromptTemplate.from_messages([ system_message, MessagesPlaceholder(variable_namechat_history), (human, {input}), MessagesPlaceholder(variable_nameagent_scratchpad) ]) self.agent create_react_agent(llmself.llm, toolsself.tools, promptprompt) # 5. 创建执行器传入记忆 self.agent_executor AgentExecutor( agentself.agent, toolsself.tools, memoryself.memory, verboseTrue, handle_parsing_errorsTrue, max_iterations7, early_stopping_methodgenerate ) def run(self, query: str) - str: try: result self.agent_executor.invoke({input: query}) return result.get(output, 智能体未返回有效输出。) except Exception as e: return f智能体执行过程中出错{e} def clear_memory(self): 清空对话记忆。 self.memory.clear()主要改进更多工具集成了计算器和时间查询工具。对话记忆ConversationBufferMemory保存了完整的对话历史。memory_keychat_history指定了在提示词中插入历史的位置。提示词优化使用了ChatPromptTemplate和MessagesPlaceholder来更优雅地处理系统消息、对话历史和代理的临时思考记录agent_scratchpad。清空记忆方法提供了clear_memory方法用于开始新一轮对话。5.3 测试增强版智能体更新main.py来使用新的智能体并测试其记忆和多功能# main.py (更新版) import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) from agents.advanced_agent import AdvancedAgent def main(): print(初始化高级智能体带记忆和多技能...) agent AdvancedAgent(model_namegpt-3.5-turbo) print(智能体‘智囊’已上线输入您的问题输入 clear 清空记忆quit 退出) print(- * 50) while True: try: user_input input(\n您) if user_input.lower() in [quit, exit, q]: print(再见) break if user_input.lower() clear: agent.clear_memory() print(对话记忆已清空。) continue if not user_input.strip(): continue print(\n智囊正在思考...) response agent.run(user_input) print(f\n智囊{response}) except KeyboardInterrupt: print(\n\n程序被中断。) break except Exception as e: print(f\n发生错误{e}) if __name__ __main__: main()现在运行python main.py体验更强大的对话您计算一下 15 的平方加上 20 的三次方是多少 智囊调用计算器工具得到结果。最终回答你。 您现在几点了 智囊调用时间工具告诉你当前时间。 您我刚才让你计算了什么 智囊依靠记忆你刚才让我计算了 15 的平方加上 20 的三次方结果是...你可以看到智能体现在能记住上下文并且能灵活运用多个技能。6. 常见问题与排查指南FAQ在开发和使用Agent过程中你一定会遇到各种问题。以下是典型问题及其解决方案。6.1 智能体不调用工具现象LLM直接回答了问题而没有调用你提供的工具。可能原因与解决工具描述不清晰检查技能的description字段。它必须极其清晰、无歧义地说明技能的功能和适用场景。LLM完全依赖这个描述做决策。提示词模板问题确保你的提示词模板明确要求LLM遵循“思考-行动”的格式。ReAct模板通常效果很好。模型能力不足过于简单或陈旧的模型可能无法很好理解工具调用。尝试切换到更强大的模型如gpt-4或gpt-4-turbo。问题太简单如果问题LLM本身就能回答如常识问题它可能不会调用工具。你可以通过系统提示词强制要求“对于涉及实时数据、计算或特定操作的问题必须使用工具”。6.2 智能体陷入循环或调用错误工具现象智能体反复调用同一个工具或调用一个不相关的工具。可能原因与解决工具描述重叠如果两个技能的描述太相似LLM可能会混淆。确保每个技能的描述独一无二。max_iterations设置过小或过大太小可能导致任务未完成就停止太大可能导致死循环。根据任务复杂度调整一般5-10次。观察结果不清晰工具返回的结果_run方法的输出应该清晰、结构化。如果结果混乱或包含错误信息LLM可能无法理解导致后续决策错误。确保工具返回有意义、简洁的字符串。6.3 解析错误Parsing Errors现象控制台报错OutputParserException或类似错误。可能原因与解决LLM输出格式不符合预期ReAct代理期望LLM严格按照“思考...行动...行动输入...”的格式输出。有时LLM会“放飞自我”。可以尝试在提示词中更加强调格式。使用handle_parsing_errorsTrue参数我们已经设置让执行器在解析失败时尝试让LLM重试或修复格式。使用更稳定的模型。工具参数错误LLM生成的“行动输入”可能不符合args_schema的定义。确保你的参数描述Field(description...)足够明确。6.4 API密钥与网络问题现象AuthenticationError或连接超时。解决检查.env文件中的OPENAI_API_KEY是否正确且没有多余空格。确认网络环境可以访问OpenAI API。如果你在国内可能需要配置网络环境。检查OpenAI账户是否有余额或调用额度。6.5 性能与成本优化现象响应慢或API调用费用高。优化建议选择合适的模型对于简单任务gpt-3.5-turbo性价比最高。对于复杂推理和工具调用gpt-4效果更好但更贵。限制对话轮次通过max_iterations严格控制。使用缓存LangChain支持LLM调用缓存如InMemoryCache,SQLiteCache对于重复问题可以显著节省成本和时间。流式传输Streaming对于长文本生成使用流式输出可以提升用户体验。7. 工程化最佳实践与进阶方向当你掌握了基础开发后要将智能体投入实际项目还需要考虑以下方面。7.1 技能开发规范单一职责一个技能只做一件事。不要编写一个“万能”技能。健壮的错误处理技能必须能处理各种边界情况和异常网络超时、无效输入、API限流等并返回友好的错误信息而不是抛出异常导致智能体崩溃。输入验证与安全永远不要信任来自LLM或用户的输入。使用args_schema进行类型验证。对于像计算器这样需要执行代码的技能必须使用安全的表达式求值库如ast.literal_eval或numexpr替代eval。清晰的文档为每个技能编写详细的docstring说明其功能、输入输出格式和可能的错误。7.2 智能体设计模式规划Planning对于复杂任务让智能体先制定计划再执行。可以使用LLMChain生成步骤或使用LangGraph构建有状态的工作流。多智能体协作使用像AutoGen这样的框架创建多个各司其职的智能体如规划者、执行者、审核者进行协作。工具检索Tool Retrieval当工具数量很多时几十上百个让LLM从所有工具中挑选合适的变得低效。可以实现一个“工具检索器”根据用户问题语义搜索最相关的几个工具再交给LLM决策。7.3 生产环境部署配置管理使用环境变量或专业的配置管理工具如Azure App Configuration, AWS Parameter Store管理API密钥、模型参数等敏感信息。日志与监控记录智能体的所有决策、工具调用和结果。这对于调试、优化和审计至关重要。可以集成像LangSmith这样的LangChain官方追踪平台。速率限制与重试为LLM API和第三方工具API添加速率限制和指数退避重试机制。异步与并发对于IO密集型技能如网络请求实现其_arun异步方法并使用异步代理执行器AgentExecutor的异步版本来提高吞吐量。容器化使用Docker将你的智能体应用打包确保环境一致性便于在云服务器或Kubernetes上部署。7.4 后续学习路线深入LangChain学习Chains用于固定流程、Indexes用于检索增强生成RAG、Memory的各种实现向量存储记忆、窗口记忆等。探索LangGraph用于构建复杂、有状态、可循环的智能体工作流是构建高级Agent的利器。集成向量数据库为智能体添加长期记忆和知识库如使用Chroma, Pinecone, Weaviate使其能回答基于私有文档的问题。尝试其他框架了解AutoGen多智能体、Semantic Kernel微软系、LlamaIndex专注RAG等拓宽视野。关注开源项目在GitHub上关注langchain-ai、microsoft/autogen等官方仓库学习社区的最佳实践和新兴模式。从构建一个简单的天气查询技能到创建一个具备记忆和多技能协作的智能体你已经走完了AI Agent开发的核心路径。记住Agent开发是一个迭代过程从定义清晰的任务开始设计并实现可靠的技能然后通过精心设计的提示词和记忆机制将它们组合起来最后在真实场景中测试和优化。