[AI]实现简易AI Agent — — Langchain库
文中全部代码地址:
https://github.com/ziyifast/ziyifast-code_instruction/tree/main/python-demo/AI-demo/AI-Agent/lang-chain
- 欢迎大家star哦😯~
目前实现AI Agent主要有两种方式:一种是基于更底层的Transformer,另一种是基于Langchain库。上期有给大家Transformer的实现,本期主要介绍基于Langchain该如何实现。
概念
为什么LLM需要Agent
经常用AI的人都知道,AI的输出结果只能作为一个参考,这是为什么呢?因为虽然大语言模型的能力很强大,但是LLM仅限于用于训练的知识,这些知识很快会过时(虽然现在有联网功能,但依然免不了幻觉),所以LLM有以下缺点:
- 幻觉
- 结果并不总是真实的
- 对时事的了解有限或一无所知
- 难以应对复杂推理和计算
(虽然LLM完全理解了我的需求,但是它本身并不知道“我”所处的城市等信息)
而基于大模型的Agent (LLM based Agent) 可以利用外部工具来克服以上缺点。
ReAct核心定义
ReAct Agent 论文:https://arxiv.org/abs/2210.03629
ReAct = Reasoning(推理) + Action(行动),是一种AI Agent的设计范式:
- Reasoning:模型通过思考确定解决问题的最佳路径(如选择工具、分解步骤)
- Action:根据推理结果调用外部工具(如API、数据库)或执行操作
AI Agent典型流程:
实战
这里以查询天气的AI Agent为例,思路:
- 通过Langchain库调用大模型
- 注册高德开发者,通过高德API直接查询城市天气。将该功能封装为工具,提供给AI
- Langchain官方文档:https://python.langchain.ac.cn/docs/tutorials/agents/
- 解析AI返回结果
为了让大家可以更直观的感受到大模型根据我们的输入,进行判断并调用不同的工具,我们将会实现两个自定义工具,一个是get_weather,一个是say_hello。
对比Transformer实现方式,我们这里不用自己将向量转换为文本输出,Langchain API帮我们封装了对应的能力。
环境准备
- Python环境准备:本地需要有Python开发环境,我这里是Mac,所以自带Python。
- 方式一:可以选择直接下载PyCharm:https://www.jetbrains.com/pycharm/
- 方式二:直接从Python官方下载并配置:https://www.python.org/
- 高德API Key:注册高德开发者即可
- 注册高德开发者:https://developer.amap.com/api/webservice/guide/create-project/get-key
- 获取API Key:
- 获取大模型 API Key
我这里以ChatGPT API 为例,大家可以根据自己的想法选用不同的模型。只要最后配置好API Key即可。
- 我这里使用DevAGI平台获取ChatGPT API Key,新用户注册免费送20次调用机会,通过邮箱注册即可:https://devcto.com/app/account
- 安装python依赖
pip install requests langchain-openai langchain langchain-core python-dotenv openai
模型与工具初始化
实现Agent第一个自定义工具get_weather:天气查询
这里主要实现Agent核心能力:调用高德API查询实时天气
- 获取行政区划代码
- 获取天气数据
①调用高德API获取行政区划代码
- 调用高德行政区划API
- 检查API返回状态码status
- 提取第一个匹配城市的adcode和名称
def get_abcode(city):
url = "https://restapi.amap.com/v3/config/district?"
params = {"key": GD_KEY, "keywords": city, "subdistrict": 0}
try:
response = requests.get(url=url, params=params)
response.raise_for_status() # 自动抛出HTTP错误
if response.json()["status"] == "1":
return (
response.json()["districts"][0]["adcode"], # 行政区划代码
response.json()["districts"][0]["name"] # 城市名称
)
else:
return None
except Exception as e:
print(f"Error: {e}")
return None
②获取对应城市天气数据
def get_weather(cityname: str = "成都"):
abcode, city_name = get_abcode(cityname)
url = "https://restapi.amap.com/v3/weather/weatherInfo?"
params = {"key": GD_KEY, "city": abcode, "extensions": "base"}
try:
response = requests.get(url=url, params=params)
if response.json()["status"] == "1":
return response.json()["lives"][0] # 实时天气数据
else:
return None
except Exception as e:
print(f"Error: {e}")
return None
实现第二个自定义工具say_hello:打招呼
# 定义打招呼工具
@tool
def say_hello(name: str) -> str:
"""当需要向某人打招呼时使用此工具。例如:向Tom打招呼。
Args:
name: 需要打招呼的对象名称
Returns:
个性化问候语
"""
return f"👋 你好 {name}!今天过得怎么样?"
主对话循环
①消息模板构建
预制提示词以及大模型角色。
- 官方提示词模版:https://python.langchain.com/api_reference/core/prompts/langchain_core.prompts.chat.ChatPromptTemplate.html
# 构建提示模板
prompt = ChatPromptTemplate.from_messages([
("system", """你是一个智能助手,可以使用以下工具:
{tools}
使用规则:
1. 当用户说“向[名字]打招呼”时,必须使用say_hello工具
2. 当用户说“查询[城市]天气”时,必须使用get_weather工具
3. 保持自然友好的语气
4. 始终使用中文
"""),
MessagesPlaceholder("chat_history", optional=True),
("human", "{input}"),
MessagesPlaceholder("agent_scratchpad")
]).partial(
tools="\n".join([
f"工具名称:{t.name}\n功能描述:{t.description}\n参数格式:{t.args}"
for t in tools
]),
tool_names=", ".join([t.name for t in tools])
)
②模型推理与输出解析
# 创建Agent工作流
agent = create_openai_tools_agent(llm=llm, tools=tools, prompt=prompt)
# 创建执行器
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True, # 显示详细执行过程
handle_parsing_errors=True, # 自动处理解析错误
return_intermediate_steps=True # 返回中间步骤
)
# 格式化函数
def format_response(data, tool_name):
"""根据工具类型增强格式化"""
if tool_name == "get_weather":
return (
f"🌆 {data['city']}天气\n"
f"🌤 现象:{data['weather']}\n"
f"🌡 温度:{data['temperature']}℃\n"
f"💨 风力:{data['windpower']}\n"
f"💧 湿度:{data['humidity']}%\n"
f"🕒 更新:{data['reporttime']}"
)
elif tool_name == "say_hello":
return f"✨ {data}"
else:
return data
# 主循环
while True:
user_input = input("请输入你的需求(输入退出结束对话):")
if user_input == "退出":
break
try:
result = agent_executor.invoke({"input": user_input})
# 提取工具调用结果
if "intermediate_steps" in result:
for step in result["intermediate_steps"]:
tool_call, tool_result = step
fn_name = tool_call.tool
print(format_response(tool_result, fn_name))
except Exception as e:
print(f"\n❌ 错误: {str(e)}\n")
运行效果
说明:这里为了给大家演示大模型对工具的选择,所以我Python完整代码里提供了两个工具,一个是查天气,一个是打招呼。
1. 案例一:调用天气查询功能
2. 案例二:调用打招呼功能
相关文档:
https://python.langchain.com.cn/docs/modules/agents/tools/how_to/custom_tools
https://devcto.com/app/account
https://arxiv.org/abs/2210.03629