与API交互的使用案例
假设您希望一个LLM与外部API进行交互。
这对于检索LLM可以利用的上下文非常有用。
通过Langchain,借助LLM大模型的自然语言处理能力,理解用户需求自动调用外部系统的API,可以实现丰富应用场景,例如你跟AI说我明天有事,请假一天,AI自动调用请假系统的API,帮你生成一个请假单。
概述
有两种主要的方式可以将LLM与外部API接口连接起来:
函数
:例如,OpenAI函数是一种常见的方法之一。LLM生成的接口
:使用具有API文档访问权限的LLM创建接口。
快速入门
许多API已经与OpenAI函数调用兼容。
例如,Klarna有一个描述其API并允许OpenAI与其交互的YAML文件:
https://www.klarna.com/us/shopping/public/openai/v0/api-docs/
其他选项包括:
如下所示,我们可以直接向get_openapi_chain
提供规范,以便使用OpenAI函数查询API:
pip install langchain openai
from langchain.chains.openai_functions.openapi import get_openapi_chain
chain = get_openapi_chain("https://www.klarna.com/us/shopping/public/openai/v0/api-docs/")
chain("What are some options for a men's large blue button down shirt")
API参考:
正在尝试加载OpenAPI 3.0.1规范。这可能会导致性能下降。将您的OpenAPI规范转换为更好的3.1.*规范以获得更好的支持。
{'query': '男士大号蓝色敞开扣衬衫的一些选择',
'response': {'products': [{'name': 'Cubavera Four Pocket古巴衬衫',
'url': 'https://www.klarna.com/us/shopping/pl/cl10001/3202055522/Clothing/Cubavera-Four-Pocket-Guayabera-Shirt/?utm_source=openai&ref-site=openai_plugin',
'price': '$13.50',
'attributes': ['材质:涤纶,棉',
'适用人群:男性',
'颜色:红色,白色,蓝色,黑色',
'属性:口袋',
'图案:纯色',
'尺寸(小-大):S,XL,L,M,XXL']},
{'name': 'Polo Ralph Lauren格子短袖敞开扣牛津衬衫',
'url': 'https://www.klarna.com/us/shopping/pl/cl10001/3207163438/Clothing/Polo-Ralph-Lauren-Plaid-Short-Sleeve-Button-down-Oxford-Shirt/?utm_source=openai&ref-site=openai_plugin',
'price': '$52.20',
'attributes': ['材质:棉',
'适用人群:男性',
'颜色:红色,蓝色,多色',
'尺寸(小-大):S,XL,L,M,XXL']},
{'name': 'Brixton Bowery法兰绒衬衫',
'url': 'https://www.klarna.com/us/shopping/pl/cl10001/3202331096/Clothing/Brixton-Bowery-Flannel-Shirt/?utm_source=openai&ref-site=openai_plugin',
'price': '$27.48',
'attributes': ['材质:棉',
'适用人群:男性',
'颜色:灰色,蓝色,黑色,橙色',
'属性:口袋',
'图案:方格',
'尺寸(小-大):XL,3XL,4XL,5XL,L,M,XXL']},
{'name': 'Vineyard Vines格子快速智能亚克力宽松衬衫',
'url': 'https://www.klarna.com/us/shopping/pl/cl10001/3201938510/Clothing/Vineyard-Vines-Gingham-On-The-Go-brrr-Classic-Fit-Shirt-Crystal/?utm_source=openai&ref-site=openai_plugin',
'price': '$80.64',
'attributes': ['材质:棉',
'适用人群:男性',
'颜色:蓝色',
'尺寸(小-大):XL,XS,L,M']},
{'name': 'Carhartt男士宽松中重量短袖方格衬衫',
'url': 'https://www.klarna.com/us/shopping/pl/cl10001/3201826024/Clothing/Carhartt-Men-s-Loose-Fit-Midweight-Short-Sleeve-Plaid-Shirt/?utm_source=openai&ref-site=openai_plugin',
'price': '$17.99',
'attributes': ['材质:棉',
'适用人群:男性',
'颜色:红色,棕色,蓝色,绿色',
'属性:口袋',
'图案:方格',
'尺寸(小-大):S,XL,L,M']}]}}
函数
我们可以解开使用函数调用外部API时所发生的情况。
让我们来看看LangSmith trace:
- 请查看此处,我们使用提供的API规范调用OpenAI LLM:
https://www.klarna.com/us/shopping/public/openai/v0/api-docs/
- 然后,prompt会告诉LLM使用API规范,并提供输入问题:
使用提供的API来响应用户查询:
男士大号蓝色纽扣衬衫的一些选项有哪些?
- LLM返回函数调用
productsUsingGET
的参数,该函数在提供的API规范中指定:
function_call:
name: productsUsingGET
arguments: |-
{
"params": {
"countryCode": "US",
"q": "男士大号蓝色纽扣衬衫",
"size": 5,
"min_price": 0,
"max_price": 100
}
}
- 上述
Dict
被分割,在这里调用了API。
API链
我们还可以使用APIChain
和提供的API文档构建自己的与外部API的接口。
from langchain.llms import OpenAI
from langchain.chains import APIChain
from langchain.chains.api import open_meteo_docs
llm = OpenAI(temperature=0)
chain = APIChain.from_llm_and_api_docs(llm, open_meteo_docs.OPEN_METEO_DOCS, verbose=True)
chain.run('目前在德国慕尼黑的天气是多少华氏度?')
API参考文档:
> Entering new APIChain chain...
https://api.open-meteo.com/v1/forecast?latitude=48.1351&longitude=11.5820&hourly=temperature_2m&temperature_unit=fahrenheit¤t_weather=true
{"latitude":48.14,"longitude":11.58,"generationtime_ms":1.0769367218017578,"utc_offset_seconds":0,"timezone":"GMT","timezone_abbreviation":"GMT","elevation":521.0,"current_weather":{"temperature":52.9,"windspeed":12.6,"winddirection":239.0,"weathercode":3,"is_day":0,"time":"2023-08-07T22:00"},"hourly_units":{"time":"iso8601","temperature_2m":"°F"},"hourly":{"time":["2023-08-07T00:00","2023-08-07T01:00","2023-08-07T02:00","2023-08-07T03:00","2023-08-07T04:00","2023-08-07T05:00","2023-08-07T06:00","2023-08-07T07:00","2023-08-07T08:00","2023-08-07T09:00","2023-08-07T10:00","2023-08-07T11:00","2023-08-07T12:00","2023-08-07T13:00","2023-08-07T14:00","2023-08-07T15:00","2023-08-07T16:00","2023-08-07T17:00","2023-08-07T18:00","2023-08-07T19:00","2023-08-07T20:00","2023-08-07T21:00","2023-08-07T22:00","2023-08-07T23:00","2023-08-08T00:00","2023-08-08T01:00","2023-08-08T02:00","2023-08-08T03:00","2023-08-08T04:00","2023-08-08T05:00","2023-08-08T06:00","2023-08-08T07:00","2023-08-08T08:00","2023-08-08T09:00","2023-08-08T10:00","2023-08-08T11:00","2023-08-08T12:00","2023-08-08T13:00","2023-08-08T14:00","2023-08-08T15:00","2023-08-08T16:00","2023-08-08T17:00","2023-08-08T18:00","2023-08-08T19:00","2023-08-08T20:00","2023-08-08T21:00","2023-08-08T22:00","2023-08-08T23:00","2023-08-09T00:00","2023-08-09T01:00","2023-08-09T02:00","2023-08-09T03:00","2023-08-09T04:00","2023-08-09T05:00","2023-08-09T06:00","2023-08-09T07:00","2023-08-09T08:00","2023-08-09T09:00","2023-08-09T10:00","2023-08-09T11:00","2023-08-09T12:00","2023-08-09T13:00","2023-08-09T14:00","2023-08-09T15:00","2023-08-09T16:00","2023-08-09T17:00","2023-08-09T18:00","2023-08-09T19:00","2023-08-09T20:00","2023-08-09T21:00","2023-08-09T22:00","2023-08-09T23:00","2023-08-10T00:00","2023-08-10T01:00","2023-08-10T02:00","2023-08-10T03:00","2023-08-10T04:00","2023-08-10T05:00","2023-08-10T06:00","2023-08-10T07:00","2023-08-10T08:00","2023-08-10T09:00","2023-08-10T10:00","2023-08-10T11:00","2023-08-10T12:00","2023-08-10T13:00","2023-08-10T14:00","2023-08-10T15:00","2023-08-10T16:00","2023-08-10T17:00","2023-08-10T18:00","2023-08-10T19:00","2023-08-10T20:00","2023-08-10T21:00","2023-08-10T22:00","2023-08-10T23:00","2023-08-11T00:00","2023-08-11T01:00","2023-08-11T02:00","2023-08-11T03:00","2023-08-11T04:00","2023-08-11T05:00","2023-08-11T06:00","2023-08-11T07:00","2023-08-11T08:00","2023-08-11T09:00","2023-08-11T10:00","2023-08-11T11:00","2023-08-11T12:00","2023-08-11T13:00","2023-08-11T14:00","2023-08-11T15:00","2023-08-11T16:00","2023-08-11T17:00","2023-08-11T18:00","2023-08-11T19:00","2023-08-11T20:00","2023-08-11T21:00","2023-08-11T22:00","2023-08-11T23:00","2023-08-12T00:00","2023-08-12T01:00","2023-08-12T02:00","2023-08-12T03:00","2023-08-12T04:00","2023-08-12T05:00","2023-08-12T06:00","2023-08-12T07:00","2023-08-12T08:00","2023-08-12T09:00","2023-08-12T10:00","2023-08-12T11:00","2023-08-12T12:00","2023-08-12T13:00","2023-08-12T14:00","2023-08-12T15:00","2023-08-12T16:00","2023-08-12T17:00","2023-08-12T18:00","2023-08-12T19:00","2023-08-12T20:00","2023-08-12T21:00","2023-08-12T22:00","2023-08-12T23:00","2023-08-13T00:00","2023-08-13T01:00","2023-08-13T02:00","2023-08-13T03:00","2023-08-13T04:00","2023-08-13T05:00","2023-08-13T06:00","2023-08-13T07:00","2023-08-13T08:00","2023-08-13T09:00","2023-08-13T10:00","2023-08-13T11:00","2023-08-13T12:00","2023-08-13T13:00","2023-08-13T14:00","2023-08-13T15:00","2023-08-13T16:00","2023-08-13T17:00","2023-08-13T18:00","2023-08-13T19:00","2023-08-13T20:00","2023-08-13T21:00","2023-08-13T22:00","2023-08-13T23:00"],"temperature_2m":[53.0,51.2,50.9,50.4,50.7,51.3,51.7,52.9,54.3,56.1,57.4,59.3,59.1,60.7,59.7,58.8,58.8,57.8,56.6,55.3,53.9,52.7,52.9,53.2,52.0,51.8,51.3,50.7,50.8,51.5,53.9,57.7,61.2,63.2,64.7,66.6,67.5,67.0,68.7,68.7,67.9,66.2,64.4,61.4,59.8,58.9,57.9,56.3,55.7,55.3,55.5,55.4,55.7,56.5,57.6,58.8,59.7,59.1,58.9,60.6,59.9,59.8,59.9,61.7,63.2,63.6,62.3,58.9,57.3,57.1,57.0,56.5,56.2,56.0,55.3,54.7,54.4,55.2,57.8,60.7,63.0,65.3,66.9,68.2,70.1,72.1,72.6,71.4,69.7,68.6,66.2,63.6,61.8,60.6,59.6,58.9,58.0,57.1,56.3,56.2,56.7,57.9,59.9,63.7,68.4,72.4,75.0,76.8,78.0,78.7,78.9,78.4,76.9,74.8,72.5,70.1,67.6,65.6,64.4,63.9,63.4,62.7,62.2,62.1,62.5,63.4,65.1,68.0,71.7,74.8,76.8,78.2,79.1,79.6,79.7,79.2,77.6,75.3,73.7,68.6,66.8,65.3,64.2,63.4,62.6,61.7,60.9,60.6,60.9,61.6,63.2,65.9,69.3,72.2,74.4,76.2,77.6,78.8,79.6,79.6,78.4,76.4,74.3,72.3,70.4,68.7,67.6,66.8]}}
> Finished chain.
' The current temperature in Munich, Germany is 52.9°F.'
请注意,我们提供了有关API的信息:
open_meteo_docs.OPEN_METEO_DOCS[0:500]
'BASE URL: https://api.open-meteo.com/\n\nAPI文档\nAPI端点/v1/forecast接受地理坐标、天气变量列表,并以JSON小时天气预报形式对7天的天气情况进行响应。时间始终从今天的0:00开始,包含168小时。以下是所有URL参数的列表:\n\n参数\t\t格式\t\t是否必需\t默认值\t\t描述\nlatitude, longitude\t浮点数\t\t是\t\t\t地点的地理WGS84坐标\nhourly\t\t\t字符串数组\t否\t\t\t应显示的天气变量列表'
在幕后,我们做了两件事情:
api_request_chain
:根据输入问题和api_docs生成API URLapi_answer_chain
:根据API响应生成最终答案
我们可以查看 LangSmith trace 进行检查:
api_request_chain
从我们的问题和API文档中生成API URL:
- 这里 我们使用API URL进行API请求。
api_answer_chain
接收来自API的响应并提供自然语言的回答:
深入了解
尝试其他API
import os
os.environ['TMDB_BEARER_TOKEN'] = ""
from langchain.chains.api import tmdb_docs
headers = {"Authorization": f"Bearer {os.environ['TMDB_BEARER_TOKEN']}"}
chain = APIChain.from_llm_and_api_docs(llm, tmdb_docs.TMDB_DOCS, headers=headers, verbose=True)
chain.run("搜索'阿凡达'")
API 参考文档:
import os
from langchain.llms import OpenAI
from langchain.chains.api import podcast_docs
from langchain.chains import APIChain
listen_api_key = 'xxx' # 在此处获取 API 密钥:https://www.listennotes.com/api/pricing/
llm = OpenAI(temperature=0)
headers = {"X-ListenAPI-Key": listen_api_key}
chain = APIChain.from_llm_and_api_docs(llm, podcast_docs.PODCAST_DOCS, headers=headers, verbose=True)
chain.run("搜索'silicon valley bank'播客剧集,音频长度超过30分钟,仅返回1个结果")
API 参考文档:
网页请求
URL 请求是一个常见的用例,我们有 LLMRequestsChain
可以通过进行 HTTP GET 请求。
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMRequestsChain, LLMChain
API 参考文档:
template = """在 >>> 和 > 之间 {requests_result} """
chain = LLMRequestsChain(llm_chain=LLMChain(llm=OpenAI(temperature=0), prompt=PROMPT))
question = "什么是三个最大的国家,以及它们各自的面积?"
inputs = {
"query": question,
"url": "https://www.google.com/search?q=" + question.replace(" ", "+"),
}
chain(inputs)
{'query': '什么是三个最大的国家,以及它们各自的面积?',
'url': 'https://www.google.com/search?q=什么是三个最大的国家,以及它们各自的面积?',
'output': ' 俄罗斯(17,098,242平方公里),加拿大(9,984,670平方公里),中国(9,706,961平方公里)'}