1. 项目概述
最近在探索LangChain的Agent开发,尝试实现了一个简单的天气查询助手。这个项目核心是利用LangChain框架,将天气API封装成工具函数,让大语言模型能够通过工具调用的方式获取实时天气数据,并以自然语言形式返回给用户。
这个天气查询Agent的实现涉及几个关键技术点:
- 使用@tool装饰器定义天气查询工具函数
- 配置ChatOpenAI连接阿里云百炼模型
- 设计系统提示词规范输出格式
- 创建具备工具调用能力的智能体
下面我会详细拆解每个环节的实现细节和设计考量,分享在实际开发中遇到的问题和解决方案。
2. 环境准备与依赖安装
2.1 版本兼容性说明
首先需要特别注意LangChain的版本问题。这个项目使用的是LangChain 1.0版本,与老版本0.3存在兼容性问题。如果你之前安装过旧版本,建议先卸载:
bash复制pip uninstall langchain
然后安装指定版本:
bash复制pip install langchain==1.0.0
还需要安装以下依赖:
bash复制pip install langchain_openai requests pydantic
注意:这里使用langchain_openai而不是直接安装openai库,因为我们需要的是LangChain对OpenAI API的封装实现,而不是原生OpenAI SDK。
2.2 开发环境配置
建议使用Python 3.8+版本,我实测在3.10环境下运行最稳定。如果你使用虚拟环境,可以这样创建:
bash复制python -m venv weather_agent
source weather_agent/bin/activate # Linux/Mac
weather_agent\Scripts\activate # Windows
3. 核心组件实现
3.1 天气查询工具函数
工具函数是Agent能够调用外部API的关键。我们使用@tool装饰器定义一个get_weather函数:
python复制import requests
from langchain.tools import tool
from pydantic import SecretStr
@tool
def get_weather(location: str) -> str:
"""获取指定地点的天气信息。参数 location 必须是城市名称,例如'北京'。"""
url = "https://uapis.cn/api/v1/misc/weather"
params = {
"city": location,
"lang": "zh",
"forecast": "true"
}
try:
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
return str(response.json())
except Exception as e:
return f"错误: {str(e)}"
几个关键设计点:
- 使用@tool装饰器让LangChain能识别这个函数作为工具
- 函数文档字符串会作为工具描述被Agent理解
- 添加了异常处理确保API调用失败时有合理返回
- 参数明确指定为城市名称,避免歧义
3.2 模型配置
这里使用阿里云百炼模型(qwen3.5-27b)作为基础模型:
python复制from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="qwen3.5-27b",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1/",
api_key=SecretStr("你的API_KEY"),
temperature=0.5,
)
配置说明:
- base_url指向阿里云API端点
- 使用SecretStr封装API密钥更安全
- temperature=0.5平衡创造性和确定性
- 模型选择qwen3.5-27b是中文场景下的较优选择
提示:如果没有阿里云API,也可以替换为其他兼容OpenAI API的模型服务,只需修改base_url和api_key即可。
3.3 系统提示词设计
好的提示词能显著提升Agent的表现:
python复制system_prompt = """你是一个专业的天气查询助手。请必须使用工具获取准确的天气数据,并用自然、友好的语言回答用户。不要输出原始的 JSON 格式。回答时应包含以下信息:
1. 当前天气状况
2. 温度范围
3. 风力风向
4. 湿度
5. 未来几小时的天气变化趋势(如果有)
用中文回答,语气亲切自然。"""
提示词设计技巧:
- 明确角色和专业性要求
- 强制要求使用工具获取数据
- 规范输出格式和内容要点
- 指定语言和语气风格
4. Agent创建与调用
4.1 创建Agent
使用create_agent函数将模型、工具和提示词组合起来:
python复制from langchain.agents import create_agent
agent = create_agent(
model=model,
tools=[get_weather],
system_prompt=system_prompt
)
4.2 调用Agent
调用Agent进行天气查询:
python复制if __name__ == "__main__":
question = "北京最近天气怎么样?"
print(f"正在查询:{question}\n" + "-" * 40)
response = agent.invoke({"messages": [("user", question)]})
if isinstance(response, dict) and 'messages' in response:
final_answer = response['messages'][-1].content
print("天气查询结果:\n", final_answer)
else:
print("天气查询结果:\n", response)
调用过程解析:
- 构造用户问题
- 调用agent.invoke方法
- 处理返回结果,提取最终回答
- 打印天气信息
5. 优化与调试技巧
5.1 常见问题排查
-
API调用失败
- 检查网络连接
- 确认API端点可用
- 验证API密钥是否正确
-
工具调用不触发
- 确保函数有@tool装饰器
- 检查工具描述是否清晰
- 调整提示词强调工具使用
-
输出格式不规范
- 优化系统提示词
- 调整temperature参数
- 添加输出格式示例
5.2 性能优化建议
- 添加缓存机制,避免重复查询相同地点
- 实现异步调用提高响应速度
- 添加输入验证,处理无效城市名称
- 支持更多天气数据源作为备选
5.3 扩展思路
这个基础Agent可以进一步扩展:
- 增加多城市同时查询
- 支持天气预警功能
- 添加历史天气查询
- 集成到聊天机器人中
6. 完整代码示例
以下是整合后的完整实现:
python复制import requests
from langchain.tools import tool
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from pydantic import SecretStr
@tool
def get_weather(location: str) -> str:
"""获取指定地点的天气信息。参数 location 必须是城市名称,例如'北京'。"""
url = "https://uapis.cn/api/v1/misc/weather"
params = {
"city": location,
"lang": "zh",
"forecast": "true"
}
try:
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
return str(response.json())
except Exception as e:
return f"错误: {str(e)}"
model = ChatOpenAI(
model="qwen3.5-27b",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1/",
api_key=SecretStr("你的API_KEY"),
temperature=0.5,
)
system_prompt = """你是一个专业的天气查询助手。请必须使用工具获取准确的天气数据,并用自然、友好的语言回答用户。不要输出原始的 JSON 格式。回答时应包含以下信息:
1. 当前天气状况
2. 温度范围
3. 风力风向
4. 湿度
5. 未来几小时的天气变化趋势(如果有)
用中文回答,语气亲切自然。"""
agent = create_agent(
model=model,
tools=[get_weather],
system_prompt=system_prompt
)
if __name__ == "__main__":
question = "北京最近天气怎么样?"
print(f"正在查询:{question}\n" + "-" * 40)
response = agent.invoke({"messages": [("user", question)]})
if isinstance(response, dict) and 'messages' in response:
final_answer = response['messages'][-1].content
print("天气查询结果:\n", final_answer)
else:
print("天气查询结果:\n", response)
7. 实际应用建议
在实际部署时,我有几个实用建议:
-
API密钥管理:不要将API密钥硬编码在代码中,可以使用环境变量或密钥管理服务。
-
错误处理增强:添加更细致的错误处理逻辑,比如重试机制、备用API等。
-
性能监控:记录查询响应时间、成功率等指标,便于优化。
-
用户输入清洗:处理用户输入中的特殊字符、空格等,提高鲁棒性。
-
多语言支持:根据用户语言偏好返回对应语言的天气信息。
这个天气查询Agent虽然简单,但涵盖了LangChain Agent开发的核心流程。通过这个项目,我深刻体会到合理设计工具函数和提示词的重要性。在实际开发中,建议先用简单用例验证核心功能,再逐步添加复杂特性。