1. AI Agent开发实战:从零构建智能助手
作为一名长期从事AI应用开发的工程师,我发现AI Agent正在彻底改变人机交互的方式。与传统的聊天机器人不同,一个真正的智能助手应该像人类助理一样,能够理解复杂指令、自主规划任务、调用各种工具,并且在长期互动中记住你的偏好和习惯。
1.1 为什么需要AI Agent?
在日常工作中,我们经常遇到这样的场景:需要查询天气、安排会议、查找资料、处理数据等一系列任务。传统做法是分别使用不同的应用和工具,而AI Agent可以将这些能力整合到一个智能系统中。
以天气查询为例,普通对话AI只能回答预设的问题,而一个成熟的Agent可以:
- 理解"下周去北京出差需要带什么衣服"这样的复杂请求
- 自动查询北京未来一周的天气预报
- 根据温度变化给出穿衣建议
- 记住用户的偏好(比如特别怕冷)
- 在下次类似查询时提供更个性化的建议
1.2 AI Agent的核心架构
一个完整的AI Agent系统由三大核心组件构成:
- 大脑(LLM):负责理解、推理和决策,通常使用大语言模型如GPT-4
- 工具(Tools):扩展Agent的能力边界,如搜索API、计算器、数据库等
- 记忆(Memory):保存对话历史和用户偏好,实现长期个性化服务
这三者的关系可以用人体来类比:
- 大脑相当于我们的思维能力
- 工具就像我们使用的手机、电脑等外部设备
- 记忆则是我们的经验和知识积累
2. 开发环境准备
2.1 基础工具安装
在开始构建Agent前,我们需要准备开发环境。推荐使用Python 3.9+版本,并创建一个干净的虚拟环境:
bash复制python -m venv agent-env
source agent-env/bin/activate # Linux/Mac
# 或
agent-env\Scripts\activate # Windows
然后安装核心依赖库:
bash复制pip install openai langchain langchain-community
注意:建议固定库版本以避免兼容性问题,例如:
bash复制pip install openai==1.12.0 langchain==0.1.0
2.2 API密钥配置
大多数AI Agent需要访问大模型API,以OpenAI为例:
- 登录OpenAI平台获取API密钥
- 在环境变量中设置:
bash复制export OPENAI_API_KEY='你的密钥'
或者在代码中直接配置:
python复制import os
os.environ['OPENAI_API_KEY'] = '你的密钥'
安全提示:永远不要将API密钥直接提交到代码仓库,建议使用环境变量或密钥管理服务
3. 构建基础天气查询Agent
3.1 定义工具函数
工具是Agent能力的延伸。我们先创建一个简单的天气查询工具:
python复制def get_weather(city: str) -> str:
"""获取城市天气信息
参数:
city: 城市名称
返回:
天气描述字符串
"""
# 模拟数据 - 实际项目中可以接入真实天气API
weather_data = {
"北京": "晴,15°C,北风3级,湿度45%",
"上海": "多云,18°C,东南风2级,湿度60%",
"深圳": "阵雨,22°C,南风4级,湿度85%",
"纽约": "阴,10°C,西北风5级,湿度70%",
"伦敦": "小雨,8°C,西南风3级,湿度90%"
}
return weather_data.get(city, f"未找到{city}的天气信息")
这个工具的特点:
- 明确定义了输入参数和返回类型
- 详细的docstring说明
- 内置了常见城市的模拟数据
- 处理了未知城市的情况
3.2 创建Agent核心
使用LangChain框架构建Agent的核心组件:
python复制from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain_openai import ChatOpenAI
from langchain.tools import Tool
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
# 1. 将天气函数包装成Tool对象
weather_tool = Tool(
name="get_weather",
func=get_weather,
description="获取指定城市的详细天气情况,包括温度、天气状况、风速和湿度"
)
# 2. 初始化LLM - 使用gpt-4模型
llm = ChatOpenAI(
model="gpt-4",
temperature=0.3, # 控制创造性,0-1之间
max_tokens=1000
)
# 3. 设计系统提示词
prompt = ChatPromptTemplate.from_messages([
("system", """你是一个专业的天气助手AI,主要帮助用户查询天气信息。
你的工作流程:
1. 仔细分析用户问题,识别需要查询的城市
2. 调用天气查询工具获取准确数据
3. 将原始天气数据转化为用户友好的表述
4. 根据天气情况给出适当的建议(如穿衣、出行等)
5. 记住用户的重要信息以便后续提供个性化服务
回答要求:
- 专业且友好
- 包含所有关键天气信息
- 提供实用建议
- 保持简洁明了"""),
MessagesPlaceholder(variable_name="chat_history", optional=True),
("human", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad")
])
# 4. 组装完整Agent
agent = create_openai_functions_agent(llm, [weather_tool], prompt)
agent_executor = AgentExecutor(
agent=agent,
tools=[weather_tool],
verbose=True, # 显示详细执行过程
max_iterations=3 # 限制最大执行步骤
)
3.3 测试基础功能
让我们测试这个基础Agent的能力:
python复制# 简单天气查询
result = agent_executor.invoke({
"input": "北京现在的天气怎么样?"
})
print(result["output"])
# 带记忆的交互
result = agent_executor.invoke({
"input": "我下周要去上海出差,需要带什么衣服?",
"chat_history": [("user", "北京现在的天气怎么样?"), ("ai", "北京当前天气是晴,15°C")]
})
print(result["output"])
预期输出示例:
code复制> Entering new AgentExecutor chain...
调用 get_weather,参数: {"city": "北京"}
北京天气:晴,15°C,北风3级,湿度45%
> Finished chain.
北京当前天气晴朗,气温15摄氏度,北风3级,湿度45%。建议穿着轻薄外套,适合户外活动。
> Entering new AgentExecutor chain...
调用 get_weather,参数: {"city": "上海"}
上海天气:多云,18°C,东南风2级,湿度60%
> Finished chain.
上海下周预计多云天气,气温18摄氏度,东南风2级。建议携带:
- 薄外套或针织衫
- 折叠伞以防阵雨
- 舒适的步行鞋
考虑到温差,可以准备一件稍厚的外套备用。
4. 增强Agent能力
4.1 添加多工具支持
一个实用的Agent需要多种工具协同工作。让我们扩展工具集:
python复制from langchain_community.tools import DuckDuckGoSearchRun
# 1. 增强版天气工具 - 接入真实API
def get_real_weather(city: str) -> str:
"""接入真实天气API获取数据"""
# 这里应该是实际的API调用代码
# 示例中使用模拟数据
return f"{city}: 晴,20°C(来自真实API数据)"
# 2. 添加搜索引擎工具
search_tool = DuckDuckGoSearchRun(
name="web_search",
description="当需要查找最新信息或天气API无法提供数据时使用"
)
# 3. 更新工具列表
tools = [
Tool(
name="get_weather",
func=get_real_weather,
description="获取指定城市的实时天气数据"
),
search_tool
]
# 重新创建Agent
agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
4.2 实现长期记忆
记忆系统让Agent能够跨会话记住用户信息:
python复制from langchain.memory import ConversationBufferMemory
# 1. 创建记忆系统
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="output"
)
# 2. 更新Agent配置
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
memory=memory,
max_iterations=5
)
# 测试记忆功能
agent_executor.invoke({"input": "我叫张三,喜欢晴天"})
result = agent_executor.invoke({"input": "我的名字是什么?喜欢什么天气?"})
print(result["output"])
4.3 流式输出优化
对于长时间任务,流式输出能显著改善用户体验:
python复制# 流式处理示例
for chunk in agent_executor.stream({"input": "比较北京和上海的天气差异"}):
if "actions" in chunk:
# 显示工具调用过程
print(f"调用工具: {chunk['actions'][0].tool}")
elif "steps" in chunk:
# 显示中间步骤
print(f"处理步骤: {chunk['steps'][0].action.tool_input}")
elif "output" in chunk:
# 最终输出
print("\n最终回答:", chunk["output"])
5. 生产环境优化
5.1 错误处理与重试机制
健壮的Agent需要完善的错误处理:
python复制from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
def reliable_get_weather(city: str) -> str:
try:
# 模拟可能失败的API调用
if random.random() < 0.3: # 30%失败率
raise Exception("API暂时不可用")
return get_real_weather(city)
except Exception as e:
print(f"天气查询失败: {str(e)}")
raise
5.2 性能监控与日志
添加监控指标和详细日志:
python复制import logging
from datetime import datetime
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
class MonitoredAgentExecutor(AgentExecutor):
def _call(self, inputs, run_manager=None):
start_time = datetime.now()
logging.info(f"开始处理请求: {inputs['input']}")
try:
result = super()._call(inputs, run_manager)
duration = (datetime.now() - start_time).total_seconds()
logging.info(f"请求处理成功 | 耗时: {duration:.2f}s")
return result
except Exception as e:
logging.error(f"处理失败: {str(e)}")
raise
5.3 安全与权限控制
实现基本的访问控制:
python复制from functools import wraps
def require_api_key(func):
@wraps(func)
def wrapper(*args, **kwargs):
if not validate_api_key(kwargs.get('api_key')):
raise PermissionError("无效的API密钥")
return func(*args, **kwargs)
return wrapper
@require_api_key
def secure_agent_invoke(agent, input_text, api_key=None):
return agent.invoke({"input": input_text})
6. 常见问题与解决方案
在实际开发中,我们总结了一些典型问题和解决方法:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| Agent频繁调用错误工具 | 工具描述不清晰 | 优化工具description,明确使用场景和限制 |
| 忘记重要上下文 | 记忆系统配置不当 | 检查memory_key设置,增加记忆容量 |
| 响应时间过长 | 复杂任务步骤太多 | 设置max_iterations限制,优化提示词 |
| 回答不准确 | 工具数据不可靠 | 验证工具输出,添加数据清洗步骤 |
| 安全性问题 | 未过滤用户输入 | 实现输入验证,限制敏感工具调用 |
6.1 调试技巧
- 启用详细日志:
python复制import langchain
langchain.debug = True
- 分析中间步骤:
python复制for step in agent_executor.iterations:
print(f"步骤 {step.step}: {step.action.tool}")
print("输入:", step.action.tool_input)
print("输出:", step.observation)
- 提示词优化:
- 明确角色设定
- 分步骤指导思考过程
- 设置回答格式要求
6.2 性能优化策略
- 缓存常用结果:
python复制from langchain.cache import InMemoryCache
langchain.llm_cache = InMemoryCache()
- 并行工具调用:
python复制from langchain.agents import ConcurrentAgentExecutor
concurrent_agent = ConcurrentAgentExecutor(agent_executor)
- 精简工具集:
- 移除不常用工具
- 合并相似功能工具
- 设置工具调用优先级
7. 项目扩展方向
这个基础Agent可以进一步扩展为:
- 多模态Agent:
- 集成图像识别
- 添加语音交互
- 支持文件处理
- 专业领域助手:
- 医疗咨询Agent
- 法律顾问Agent
- 技术支持Agent
- 自动化工作流:
- 邮件自动处理
- 日程智能管理
- 数据自动分析
- 多Agent协作系统:
- 任务分解与分配
- 结果汇总与验证
- 争议解决机制
在实际项目中,我通常会从一个小而专的功能开始,逐步验证核心逻辑,然后再考虑扩展性和复杂性。记住,一个好的Agent不是功能越多越好,而是要在特定场景下提供可靠、一致的服务。