从任意的 LLM 推理提供商中创建一个 Transformers 智能体
作者: Aymeric Roucher
本教程建立在智能体知识的基础上:要了解更多关于智能体的信息,你可以从这里介绍开始。
Transformers Agents 是一个用于构建智能体的库,它使用 LLM 在 llm_engine
参数中提供动力。这个参数的设计是为了给用户最大的自由度去选择任意 LLM。
让我们看看如何从一些主要提供商的 API 中构建这个 llm_engine
。
HuggingFace 无服务器 API 和专用端点
Transformers Agents 提供了一个内置的 HfEngine
类,允许你通过无服务器 API 或你自己的专用端点使用 Hub 上的任何模型。这是使用 HF 智能体的首选方式。
>>> from transformers.agents import HfEngine, ReactCodeAgent
>>> repo_id = "meta-llama/Meta-Llama-3-8B-Instruct"
>>> endpoint_url = "your_endpoint_url"
>>> llm_engine = HfEngine(model=repo_id) # you could use model=endpoint_url here
>>> agent = ReactCodeAgent(tools=[], llm_engine=llm_engine)
>>> agent.run("What's the 10th Fibonacci number?")
['unicodedata', 're', 'math', 'collections', 'queue', 'itertools', 'random', 'time', 'stat', 'statistics']
智能体的 llm_engine
初始化参数可以是一个简单的可调用对象,如下所示:
def llm_engine(messages, stop_sequences=[]) -> str:
return response(messages)
这个可调用对象是 llm 引擎的核心。它应该满足以下要求:
- 以 聊天模板 格式的消息列表作为输入,并输出一个
str
。 - 接受一个
stop_sequences
参数,智能体系统将传递给它应该停止生成的序列。
让我们更仔细地看看我们使用的 HfEngine
的代码:
from typing import List, Dict
from transformers.agents.llm_engine import MessageRole, get_clean_message_list
from huggingface_hub import InferenceClient
llama_role_conversions = {
MessageRole.TOOL_RESPONSE: MessageRole.USER,
}
class HfEngine:
def __init__(self, model: str = "meta-llama/Meta-Llama-3-8B-Instruct"):
self.model = model
self.client = InferenceClient(model=self.model, timeout=120)
def __call__(self, messages: List[Dict[str, str]], stop_sequences=[]) -> str:
# Get clean message list
messages = get_clean_message_list(messages, role_conversions=llama_role_conversions)
# Get LLM output
response = self.client.chat_completion(messages, stop=stop_sequences, max_tokens=1500)
response = response.choices[0].message.content
# Remove stop sequences from LLM output
for stop_seq in stop_sequences:
if response[-len(stop_seq) :] == stop_seq:
response = response[: -len(stop_seq)]
return response
在这里,引擎不是一个函数,而是一个带有 __call__
方法的类,这使得存储诸如客户端之类的属性成为可能。
我们还使用了 get_clean_message_list()
实用工具来将连续的消息连接到同一个角色。
这个方法接受一个 role_conversions
参数,用于将 Transformers 智能体支持的角色的范围转换为你的 LLM 所接受的那些角色。
这个配方可以适用于任何 LLM!让我们看看其他例子。
为任何 LLM 适配配方
使用上述配方,你可以使用任何 LLM 推理源作为你的 llm_engine
。
只需记住两个主要约束:
llm_engine
是一个可调用对象,它以 聊天模板 格式的消息列表作为输入,并输出一个str
。- 它接受一个
stop_sequences
参数。
OpenAI
import os
from openai import OpenAI
openai_role_conversions = {
MessageRole.TOOL_RESPONSE: MessageRole.USER,
}
class OpenAIEngine:
def __init__(self, model_name="gpt-4o"):
self.model_name = model_name
self.client = OpenAI(
api_key=os.getenv("OPENAI_API_KEY"),
)
def __call__(self, messages, stop_sequences=[]):
messages = get_clean_message_list(messages, role_conversions=openai_role_conversions)
response = self.client.chat.completions.create(
model=self.model_name,
messages=messages,
stop=stop_sequences,
temperature=0.5,
)
return response.choices[0].message.content
Anthropic
from anthropic import Anthropic, AnthropicBedrock
# Cf this page for using Anthropic from Bedrock: https://docs.anthropic.com/en/api/claude-on-amazon-bedrock
class AnthropicEngine:
def __init__(self, model_name="claude-3-5-sonnet-20240620", use_bedrock=False):
self.model_name = model_name
if use_bedrock:
self.model_name = "anthropic.claude-3-5-sonnet-20240620-v1:0"
self.client = AnthropicBedrock(
aws_access_key=os.getenv("AWS_BEDROCK_ID"),
aws_secret_key=os.getenv("AWS_BEDROCK_KEY"),
aws_region="us-east-1",
)
else:
self.client = Anthropic(
api_key=os.getenv("ANTHROPIC_API_KEY"),
)
def __call__(self, messages, stop_sequences=[]):
messages = get_clean_message_list(messages, role_conversions=openai_role_conversions)
index_system_message, system_prompt = None, None
for index, message in enumerate(messages):
if message["role"] == MessageRole.SYSTEM:
index_system_message = index
system_prompt = message["content"]
if system_prompt is None:
raise Exception("No system prompt found!")
filtered_messages = [message for i, message in enumerate(messages) if i != index_system_message]
if len(filtered_messages) == 0:
print("Error, no user message:", messages)
assert False
response = self.client.messages.create(
model=self.model_name,
system=system_prompt,
messages=filtered_messages,
stop_sequences=stop_sequences,
temperature=0.5,
max_tokens=2000,
)
full_response_text = ""
for content_block in response.content:
if content_block.type == "text":
full_response_text += content_block.text
return full_response_text
下一步
现在去为你自己选择的那个语言模型推理服务,用 transformers.agents
做一个 llm_engine
吧!
做好之后,你可以用这个新的 llm_engine
来玩玩这些应用场景: