Skip to main content

与API交互 (Interacting with APIs)

在Collab中打开

使用案例 (Use case)

假设您想要一个LLM与外部API进行交互。

这对于获取LLM要使用的上下文非常有用。

而且,更一般地说,它允许我们使用自然语言与API进行交互!

概述 (Overview)

有两种主要的方法可以将LLM与外部API进行接口化:

  • 函数:例如,OpenAI函数是一种常用的方法。
  • LLM生成的接口:使用具有API文档访问权限的LLM来创建接口。

图像描述

快速入门 (Quickstart)

许多 API 已经与 OpenAI 函数调用兼容。

例如,Klarna 有一个描述其 API 的 YAML 文件,并允许 OpenAI 与其进行交互:

https://www.klarna.com/us/shopping/public/openai/v0/api-docs/

其他选项包括:

我们可以直接将规范提供给 get_openapi_chain,以便使用 OpenAI 函数查询 API:

pip install langchain openai 

# 设置环境变量 OPENAI_API_KEY 或从 .env 文件加载:
# import dotenv
# dotenv.load_env()
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")
    正在尝试加载 OpenAPI 3.0.1 规范。这可能会导致性能下降。请将您的 OpenAPI 规范转换为 3.1.* 规范以获得更好的支持。

{'query': "What are some options for a men's large blue button down shirt",
'response': {'products': [{'name': 'Cubavera Four Pocket Guayabera Shirt',
'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': ['Material:Polyester,Cotton',
'Target Group:Man',
'Color:Red,White,Blue,Black',
'Properties:Pockets',
'Pattern:Solid Color',
'Size (Small-Large):S,XL,L,M,XXL']},
{'name': 'Polo Ralph Lauren Plaid Short Sleeve Button-down Oxford Shirt',
'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': ['Material:Cotton',
'Target Group:Man',
'Color:Red,Blue,Multicolor',
'Size (Small-Large):S,XL,L,M,XXL']},
{'name': 'Brixton Bowery Flannel Shirt',
'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': ['Material:Cotton',
'Target Group:Man',
'Color:Gray,Blue,Black,Orange',
'Properties:Pockets',
'Pattern:Checkered',
'Size (Small-Large):XL,3XL,4XL,5XL,L,M,XXL']},
{'name': 'Vineyard Vines Gingham On-The-Go brrr Classic Fit Shirt Crystal',
'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': ['Material:Cotton',
'Target Group:Man',
'Color:Blue',
'Size (Small-Large):XL,XS,L,M']},
{'name': "Carhartt Men's Loose Fit Midweight Short Sleeve Plaid Shirt",
'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': ['Material:Cotton',
'Target Group:Man',
'Color:Red,Brown,Blue,Green',
'Properties:Pockets',
'Pattern:Checkered',
'Size (Small-Large):S,XL,L,M']}]}}

函数

我们可以解析在使用函数调用外部API时发生的情况。

让我们来看一下LangSmith跟踪

  • 这里,我们调用了OpenAI LLM并提供了API规范:
https://www.klarna.com/us/shopping/public/openai/v0/api-docs/
  • 然后,提示LLM使用API规范和输入问题:
使用提供的API来回应这个用户查询:
男士大号蓝色纽扣衬衫有哪些选择?
function_call:
name: productsUsingGET
arguments: |-
{
"params": {
"countryCode": "US",
"q": "男士大号蓝色纽扣衬衫",
"size": 5,
"min_price": 0,
"max_price": 100
}
}

图像描述

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('What is the weather like right now in Munich, Germany in degrees Fahrenheit?')
    

> 进入新的APIChain链...
https://api.open-meteo.com/v1/forecast?latitude=48.1351&longitude=11.5820&hourly=temperature_2m&temperature_unit=fahrenheit&current_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]}}

> 链结束。



' 德国慕尼黑的当前温度为52.9°F。'

请注意,我们提供了有关API的信息:

open_meteo_docs.OPEN_METEO_DOCS[0:500]
    'BASE URL: https://api.open-meteo.com/\n\nAPI Documentation\nThe API endpoint /v1/forecast accepts a geographical coordinate, a list of weather variables and responds with a JSON hourly weather forecast for 7 days. Time always starts at 0:00 today and contains 168 hours. All URL parameters are listed below:\n\nParameter\tFormat\tRequired\tDefault\tDescription\nlatitude, longitude\tFloating point\tYes\t\tGeographical WGS84 coordinate of the location\nhourly\tString array\tNo\t\tA list of weather variables which shou'

在底层,我们做了两件事:

  • api_request_chain:根据输入的问题和api_docs生成API URL
  • api_answer_chain:根据API响应生成最终的回答

我们可以查看LangSmith跟踪来检查这个过程:

  • api_request_chain根据我们的问题和API文档生成API URL:

Image description

  • 这里我们使用API URL进行API请求。
  • api_answer_chain根据API响应提供自然语言回答:

Image description

深入了解

使用其他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("搜索'Avatar'")
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个结果")

网络请求

URL请求是一个常见的用例,我们有LLMRequestsChain来进行HTTP GET请求。

from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMRequestsChain, LLMChain
template = """在>>>和<<<之间是来自Google的原始搜索结果文本。
提取关于问题“{query}”的答案,如果信息不包含在内,则返回“not found”。
使用以下格式:
提取的答案:<答案或“not found”>
>>> {requests_result} <<<
提取的答案:"""

PROMPT = PromptTemplate(
input_variables=["query", "requests_result"],
template=template,
)
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平方公里)'}