本文为微信公众号 敏叔的技术札记 原创文章,版权归 敏叔的技术札记 所有。如需转载或引用本文内容,请务必注明原文出处、作者以及原文链接。欢迎关注我的微信公众号 「敏叔的技术札记」,获取最新技术分享与深度解析。对于任何未注明来源的转载、摘编、修改或商业使用行为,本人保留追究法律责任的权利。
前言
最近在搞AI智能体的时候,发现一个挺有意思的问题:智能体怎么去用那些它从来没见过的API?
一开始我以为,得给每个API都写一堆说明文档,让大模型先学习一遍才能用。结果发现,现在有更高级的玩法了——零样本API理解与调用!
这玩意儿不用每次都训练,智能体自己就能看懂新API怎么用,那肯定就是干!!
什么是零样本API调用?
其实说白了,就是让AI智能体在没有预先训练过某个API的情况下,直接根据API的描述文档或者代码注释,就能理解这个API是干嘛的、怎么用。
我发现这技术特别实用,尤其是企业里面各种内部系统、私有接口那么多,不可能每个都去训练一遍。
环境准备
我们先从最简单的例子开始,用Python搞个演示。我习惯用虚拟环境隔离一下:
python3 -m venv agent_envsource agent_env/bin/activate
接下来安装需要的包,为了排版好看点,我把依赖包详情放在文章最后:
pip install openai langchain requests
附赠安装小技巧,改写安装仓库为阿里云,加速:
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
基础实现
我们先搞个简单的天气查询API来演示。新建一个文件 weather_api.py:
# weather_api.py"""这是一个天气查询API功能:根据城市名称查询当前天气参数:city (字符串) - 城市名称,比如"北京"、"上海"返回:JSON格式,包含温度、天气状况、湿度等信息示例调用:get_weather("北京")"""def get_weather(city: str): """查询指定城市的天气信息""" # 这里模拟API返回,实际项目中可能是调用第三方服务 weather_data = { "北京": {"temperature": "25°C", "condition": "晴朗", "humidity": "45%"}, "上海": {"temperature": "28°C", "condition": "多云", "humidity": "65%"}, "广州": {"temperature": "30°C", "condition": "阵雨", "humidity": "75%"} } if city in weather_data: return { "success": True, "city": city, "data": weather_data[city] } else: return { "success": False, "message": f"未找到{city}的天气信息" }
让智能体理解API
关键来了!我们怎么让智能体看懂这个API并调用呢?
我用下来之后发现,现在的LLM已经足够聪明,只要给够上下文信息就行。
新建一个 agent_zero_shot.py:
# agent_zero_shot.pyimport jsonfrom langchain.agents import Tool, AgentExecutor, create_react_agentfrom langchain.prompts import PromptTemplatefrom langchain_openai import ChatOpenAIimport weather_api # 导入我们刚才写的API# 初始化大模型llm = ChatOpenAI( model="gpt-3.5-turbo", temperature=0, api_key="你的API_KEY"# 记得替换成自己的)# 关键步骤:把API文档作为工具描述weather_tool = Tool( name="WeatherQuery", func=weather_api.get_weather, description=""" 这是一个天气查询工具。 功能:根据城市名称查询当前天气信息。 参数:city (字符串) - 城市名称,比如"北京"、"上海"。 返回:JSON格式,包含温度、天气状况、湿度等信息。 调用示例:get_weather("北京") 会返回北京的天气信息。 """)# 创建智能体tools = [weather_tool]agent = create_react_agent(llm, tools, PromptTemplate.from_template("{input}"))agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)# 测试一下if __name__ == "__main__": # 让智能体调用它从未见过的API result = agent_executor.invoke({ "input": "请帮我查询一下北京的天气情况" }) print("\n智能体返回结果:") print(result["output"])
运行看看效果:
python agent_zero_shot.py
更复杂的例子
刚才那个太简单了,我们上点难度。假设现在有个电商系统的订单查询API,智能体也没见过:
# order_api.py"""电商系统订单查询API功能:根据用户ID和订单状态查询订单信息参数: - user_id (整数): 用户ID - status (字符串, 可选): 订单状态,可选值:"pending", "shipped", "delivered", "cancelled" - limit (整数, 可选): 返回结果数量限制,默认10返回:订单列表,每个订单包含订单号、商品信息、金额、状态等示例:get_orders(123, status="shipped", limit=5)"""def get_orders(user_id: int, status: str = None, limit: int = 10): """查询用户订单""" # 模拟数据 all_orders = [ {"order_id": "ORD001", "user_id": 123, "items": ["手机", "耳机"], "amount": 5999, "status": "shipped"}, {"order_id": "ORD002", "user_id": 123, "items": ["书籍"], "amount": 89, "status": "delivered"}, {"order_id": "ORD003", "user_id": 456, "items": ["电脑"], "amount": 12999, "status": "pending"}, ] # 过滤逻辑 filtered = [order for order in all_orders if order["user_id"] == user_id] if status: filtered = [order for order in filtered if order["status"] == status] return filtered[:limit]
更新我们的智能体,让它同时理解多个API:
# multi_api_agent.pyimport jsonfrom langchain.agents import Tool, AgentExecutor, create_react_agentfrom langchain.prompts import PromptTemplatefrom langchain_openai import ChatOpenAIimport weather_apiimport order_apillm = ChatOpenAI( model="gpt-3.5-turbo", temperature=0, api_key="你的API_KEY")# 定义多个工具tools = [ Tool( name="WeatherQuery", func=weather_api.get_weather, description="天气查询工具。参数:city (字符串)。返回天气信息JSON。" ), Tool( name="OrderQuery", func=order_api.get_orders, description="订单查询工具。参数:user_id (整数), status (可选字符串), limit (可选整数)。返回订单列表。" )]# 创建智能体agent = create_react_agent(llm, tools, PromptTemplate.from_template("{input}"))agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)# 测试复杂查询if __name__ == "__main__": # 测试1:简单天气查询 print("测试1:天气查询") result1 = agent_executor.invoke({ "input": "上海今天天气怎么样?" }) print(result1["output"]) print("\n" + "="*50 + "\n") # 测试2:复杂订单查询 print("测试2:订单查询") result2 = agent_executor.invoke({ "input": "请帮我查一下用户ID为123的已发货订单,最多返回3条" }) print(result2["output"])
实战技巧
我用下来之后发现几个实用技巧:
1. 描述要准确但简洁
API描述不能太长也不能太短,要包含关键信息:
-
功能是什么
-
参数类型和含义
-
返回格式
-
简单示例
2. 错误处理很重要
智能体可能会用错参数,API要有基本的错误处理:
def safe_api_call(func): """装饰器:包装API调用,处理异常""" def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: return {"error": True, "message": f"API调用失败: {str(e)}"} return wrapper
3. 类型提示很有用
Python的类型提示能让智能体更好地理解参数:
from typing import List, Dict, Optionaldef search_products( keyword: str, category: Optional[str] = None, min_price: float = 0, max_price: float = 10000) -> List[Dict]: """商品搜索API""" # 实现...
依赖包详情
为了方便复制,这里列出完整的依赖:
openai==1.3.0langchain==0.0.340langchain-openai==0.0.2requests==2.31.0python-dotenv==1.0.0
requirements.txt文件可以直接用:
pip install -r requirements.txt
后记
其实零样本API调用这个技术最厉害的地方在于,它让AI智能体真正具备了"学习使用新工具"的能力。
以前每个新接口都得训练,现在只要写好文档描述就行,这在实际项目中太实用了!
我发现企业内部的系统对接特别适合用这个技术,各种CRM、ERP、OA系统的接口,智能体都能快速上手使用。
最后,这份示例代码不复杂,需要源码的话直接留言找我要就行。
祝各位的智能体越来越聪明!
最后还是讨一波三连(点赞+关注+转发)关注我,AI学习不迷路!!