Вызов инструментов
Вызов инструментов
Используйте инструменты (или функции) в ваших запросах с AITUNNEL. Узнайте, как использовать инструменты с OpenAI, Anthropic и другими моделями, поддерживающими вызов инструментов.
Вызов инструментов (также известный как вызов функций) дает LLM доступ к внешним инструментам. LLM не вызывает инструменты напрямую. Вместо этого он предлагает инструмент для вызова. Затем пользователь вызывает инструмент отдельно и предоставляет результаты обратно в LLM. Наконец, LLM форматирует ответ в ответ на исходный вопрос пользователя.
AITUNNEL стандартизирует интерфейс вызова инструментов для всех моделей и провайдеров.
Пример вызова инструментов
Вот пример кода на Python, который дает LLM возможность вызывать внешний API - в данном случае Project Gutenberg, для поиска книг.
Сначала выполним базовую настройку:
import json, requests
from openai import OpenAI
AITUNNEL_API_KEY = "sk-aitunnel-xxx"
# Вы можете использовать любую модель, поддерживающую вызов инструментов
MODEL = "gpt-4"
client = OpenAI(
base_url="https://api.aitunnel.ru/v1",
api_key=AITUNNEL_API_KEY,
)
task = "Какие книги написал Джеймс Джойс?"
messages = [
{
"role": "system",
"content": "Вы - полезный ассистент."
},
{
"role": "user",
"content": task,
}
]
Определение инструмента
Далее мы определяем инструмент, который хотим вызвать. Помните, что инструмент будет запрошен LLM, но код, который мы пишем здесь, в конечном итоге отвечает за выполнение вызова и возврат результатов в LLM.
def search_gutenberg_books(search_terms):
search_query = " ".join(search_terms)
url = "https://gutendex.com/books"
response = requests.get(url, params={"search": search_query})
simplified_results = []
for book in response.json().get("results", []):
simplified_results.append({
"id": book.get("id"),
"title": book.get("title"),
"authors": book.get("authors")
})
return simplified_results
tools = [
{
"type": "function",
"function": {
"name": "search_gutenberg_books",
"description": "Поиск книг в библиотеке Project Gutenberg на основе указанных поисковых запросов",
"parameters": {
"type": "object",
"properties": {
"search_terms": {
"type": "array",
"items": {
"type": "string"
},
"description": "Список поисковых запросов для поиска книг в библиотеке Gutenberg (например, ['диккенс', 'великий'] для поиска книг Диккенса со словом 'великий' в названии)"
}
},
"required": ["search_terms"]
}
}
}
]
TOOL_MAPPING = {
"search_gutenberg_books": search_gutenberg_books
}
Использование инструмента и получение результатов
Давайте сделаем первый вызов API AITUNNEL к модели:
request_1 = {
"model": MODEL,
"tools": tools,
"messages": messages
}
response_1 = client.chat.completions.create(**request_1).message
LLM отвечает с причиной завершения tool_calls и массивом tool_calls. В общем обработчике ответов LLM вы должны проверить причину завершения перед обработкой вызовов инструментов, но здесь мы предположим, что это так. Давайте продолжим, обрабатывая вызов инструмента:
# Добавляем ответ в массив сообщений, чтобы LLM имел полный контекст
# Легко забыть этот шаг!
messages.append(response_1)
# Теперь мы обрабатываем запрошенные вызовы инструментов и используем наш инструмент поиска книг
for tool_call in response_1.tool_calls:
'''
В этом случае мы предоставили только один инструмент, поэтому мы знаем, какую функцию вызывать.
При предоставлении нескольких инструментов вы можете проверить `tool_call.function.name`,
чтобы определить, какую функцию вам нужно вызвать локально.
'''
tool_name = tool_call.function.name
tool_args = json.loads(tool_call.function.arguments)
tool_response = TOOL_MAPPING[tool_name](**tool_args)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"name": tool_name,
"content": json.dumps(tool_response),
})
Массив сообщений теперь содержит:
- Наш исходный запрос
- Ответ LLM (содержащий запрос на вызов инструмента)
- Результат вызова инструмента (JSON-объект, возвращенный из API Project Gutenberg)
Теперь мы можем сделать второй вызов API AITUNNEL и, надеюсь, получить наш результат!
request_2 = {
"model": MODEL,
"messages": messages,
"tools": tools
}
response_2 = client.chat.completions.create(**request_2)
print(response_2.choices[0].message.content)
Вывод будет примерно таким:
Вот некоторые книги Джеймса Джойса:
* *Улисс*
* *Дублинцы*
* *Портрет художника в юности*
* *Камерная музыка*
* *Изгнанники: Пьеса в трех актах*
Мы сделали это! Мы успешно использовали инструмент в запросе.
Простой агентский цикл
В приведенном выше примере вызовы выполняются явно и последовательно. Для обработки широкого спектра пользовательских входных данных и вызовов инструментов вы можете использовать агентский цикл.
Вот пример простого агентского цикла (используя те же tools
и начальные messages
, что и выше):
def call_llm(msgs):
resp = client.chat.completions.create(
model=MODEL,
tools=tools,
messages=msgs
)
msgs.append(resp.choices[0].message.dict())
return resp
def get_tool_response(response):
tool_call = response.choices[0].message.tool_calls[0]
tool_name = tool_call.function.name
tool_args = json.loads(tool_call.function.arguments)
# Ищем правильный инструмент локально и вызываем его с предоставленными аргументами
# Другие инструменты могут быть добавлены без изменения агентского цикла
tool_result = TOOL_MAPPING[tool_name](**tool_args)
return {
"role": "tool",
"tool_call_id": tool_call.id,
"name": tool_name,
"content": tool_result,
}
while True:
resp = call_llm(messages)
if resp.choices[0].message.tool_calls is not None:
messages.append(get_tool_response(resp))
else:
break
print(messages[-1]['content'])
Поддержка моделей
Вызов инструментов поддерживается следующими моделями:
- Модели OpenAI (GPT-4 и более поздние версии)
- Некоторые модели от других провайдеров