SmolAgents深入探索
本博客将深入介绍 SmolAgents,包括工具、代码代理、安全代码执行和实际实现。我们还将结合代码示例使概念更清晰。
SmolAgents 是 Hugging Face 的一个尖端库,允许开发人员创建能够解决复杂任务的智能、特定领域的代理。本博客将深入介绍 SmolAgents,包括工具、代码代理、安全代码执行和实际实现。我们还将结合代码示例使概念更清晰。
1、代理简介
在 AI 领域,代理是 LLM 输出控制工作流的程序。LLM 对系统操作的影响程度决定了其代理级别。这种代理存在于以下范围内:
- 无代理 (☆☆☆):LLM 输出不影响程序流程。
- 低代理 (★☆☆):LLM 输出确定工作流中的条件分支。
- 中代理 (★★☆):LLM 输出决定执行哪些功能或工具。
- 高代理 (★★★):LLM 输出控制迭代过程并可以启动其他代理工作流。
当任务需要基于动态输入进行调整的灵活工作流时,实施代理是有益的。但是,对于具有可预测和定义明确的流程的任务,传统的确定性编程可能就足够了。
!pip install -q smolagents
!pip install huggingface_hub
2、构建有效的代理
创建强大的代理涉及几个关键考虑因素:
- 定义明确的目标:为代理建立特定的任务或目标,以确保专注的表现。
- 结合相关工具:为代理配备与其目标一致的工具,增强其执行指定任务的能力。
- 实施记忆机制:使代理能够保留以前交互中的上下文,从而做出更连贯和明智的响应。
- 确保安全的代码执行:保护执行环境以防止未经授权的操作或安全漏洞。
3、在 smolagents 中使用工具
工具对于扩展代理的功能至关重要。在 smolagents 中,工具本质上是 LLM 可以在代理系统中使用的功能。为了实现这一点,工具被封装在提供元数据的类中,帮助 LLM 了解它们的用法。例如:
from smolagents import Tool
class HFModelDownloadsTool(Tool):
name = "model_download_counter"
description = "Returns the most downloaded model of a given task on the Hugging Face Hub."
inputs = {
"task": {
"type": "string",
"description": "The task category (e.g., text-classification, depth-estimation).",
}
}
output_type = "string"
def forward(self, task: str):
from huggingface_hub import list_models
model = next(iter(list_models(filter=task, sort="downloads", direction=-1)))
return model.id
model_downloads_tool = HFModelDownloadsTool()
此结构允许 LLM 有效地与工具交互,利用其功能完成特定任务。
要构建工具,开发人员可以将 smolagents 提供的 Tool
类子类化。这种方法允许将函数的逻辑与其元数据一起封装,从而促进与代理的无缝集成。或者,对于更简单的工具,可以使用 @tool
装饰器以更少的样板代码实现类似的结果。
一旦定义,工具就可以在 Hugging Face Hub 上共享,从而实现重用和协作。通过在工具实例上调用 push_to_hub()
方法,开发人员可以将他们的工具上传到 Hub,使其可以加载到其他代理中。这促进了一个协作生态系统,其中工具可以轻松地分发和使用在各个项目中。
4、定义一个简单的工具
可以使用 @tool
装饰器创建一个工具。
from smoltools import tool
@tool
def add_numbers(a: int, b: int) -> int:
"""Adds two numbers."""
return a + b
# Using the tool
result = add_numbers(3, 5)
print(result) # Output: 8
可以将工具推送到 Hugging Face Hub 以供重用。
add_numbers.push_to_hub("your-username/add_numbers_tool")
从 Hub 加载工具:
from smoltools import Tool
# Load the tool from the Hub
tool_from_hub = Tool.from_hub("your-username/add_numbers_tool")
# Use the loaded tool
print(tool_from_hub.run(3, 5)) # Output: 8
5、使用 OpenTelemetry 检查代理运行
监控和调试代理操作对于保持性能和可靠性至关重要。smolagents 与 OpenTelemetry 集成,以促进对代理运行的全面记录和检查。通过使用 OpenTelemetry 检测代理,开发人员可以跟踪操作、监控性能并识别潜在问题。该过程包括:
安装所需的软件包:
pip install smolagents arize-phoenix opentelemetry-sdk opentelemetry-exporter-otlp openinference-instrumentation-smolagents
运行收集器:
python -m phoenix.server.main serve
设置 Instrumentor:
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from openinference.instrumentation.smolagents import SmolagentsInstrumentor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
endpoint = "http://0.0.0.0:6006/v1/traces"
trace_provider = TracerProvider()
trace_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(endpoint)))
SmolagentsInstrumentor().instrument(tracer_provider=trace_provider)
此设置可实现实时监控和运行后分析,从而提供有关代理行为的宝贵见解。
6、确保安全的代码执行
鉴于代理可能会执行由 LLM 生成的代码,因此确保安全的执行环境至关重要。smolagents 提供了防范潜在安全风险的机制:
- 本地 Python 解释器:一种定制的解释器,可将导入限制为用户定义的列表,限制操作数量以防止资源耗尽,并禁止未定义的操作。
- E2B 代码执行器:为了增强安全性,smolagents 与 E2B 集成,允许在沙盒隔离容器中执行代码。此设置可确保执行的代码不会影响本地环境,从而提供额外的保护层。
实施这些安全措施对于维护运行代理工作流的系统的完整性和安全性至关重要。
7、代码代理
代码代理是 smolagents 中的一种代理,它在操作的每个步骤中编写和执行 Python 代码片段。这种方法允许代理通过动态编写和运行代码来执行复杂任务,利用 Python 广泛的库和工具生态系统。
默认情况下,这些代码片段的执行发生在本地环境中。但是,为了确保安全性并防止与执行不受信任的代码相关的潜在风险,smolagents 提供了安全代码执行机制。这包括与 E2B 等服务集成,这些服务允许在沙盒隔离的容器中执行代码,从而保护本地环境免受未经授权的操作或安全漏洞的影响。
from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel
agent = CodeAgent(
tools=[retriever_tool, DuckDuckGoSearchTool()], model=HfApiModel(), max_iterations=4, verbose=True
)
agent.run("How to download a model from Huggingface?")
此代理将自定义检索工具与 DuckDuckGo 搜索相结合,使其能够从结构化和非结构化来源获取精确答案。
from smolagents import Tool
from langchain.docstore.document import Document
from langchain_community.retrievers import BM25Retriever
class RetrieverTool(Tool):
name = "retriever"
description = "Uses semantic search to retrieve the parts of transformers documentation that could be most relevant to answer your query."
inputs = {
"query": {
"type": "string",
"description": "The query to perform. This should be semantically close to your target documents. Use the affirmative form rather than a question.",
}
}
output_type = "string"
def __init__(self, docs, **kwargs):
super().__init__(**kwargs)
self.retriever = BM25Retriever.from_documents(
docs, k=10
)
def forward(self, query: str) -> str:
assert isinstance(query, str), "Your search query must be a string"
docs = self.retriever.invoke(
query,
)
return "\nRetrieved documents:\n" + "".join(
[
f"\n\n===== Document {str(i)} =====\n" + doc.page_content
for i, doc in enumerate(docs)
]
)
要使用此工具:
retriever_tool = RetrieverTool(docs_processed)
retriever_tool.forward("How to download a model from Huggingface?")
8、基于 RAG 的检索
检索增强生成 (RAG) 系统从 SmolAgents 中受益匪浅。但是,普通 RAG 系统有局限性,例如依赖于单个检索步骤。SmolAgents 通过以下方式解决了这些问题:
- 改进的语义相似性评分。
- 迭代检索以提高准确性。
import datasets
from langchain.docstore.document import Document
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.retrievers import BM25Retriever
knowledge_base = datasets.load_dataset("m-ric/huggingface_doc", split="train")
knowledge_base = knowledge_base.filter(lambda row: row["source"].startswith("huggingface/transformers"))
source_docs = [
Document(page_content=doc["text"], metadata={"source": doc["source"].split("/")[1]})
for doc in knowledge_base
]
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
add_start_index=True,
strip_whitespace=True,
separators=["\n\n", "\n", ".", " ", ""]
)
docs_processed = text_splitter.split_documents(source_docs)
将其与检索工具结合使用:
retriever_tool = RetrieverTool(docs_processed)
agent = CodeAgent(
tools=[retriever_tool], model=HfApiModel(), max_iterations=4, verbose=True
)
agent_output = agent.run("For a transformers model training, which is slower, the forward or the backward pass?")
print("Final output:")
print(agent_output)
9、解决 Vanilla RAG 挑战
Vanilla RAG 中的挑战包括:
- 单一检索步骤:当结果不佳时,这种方法不够用。
- 语义评分限制:查询和文档之间的评分不一致。
SmolAgents 通过以下方式解决这些问题:
- 多步骤检索。
- 优化语义匹配。
10、结束语
Hugging Face 的 SmolAgents 提供了一个强大的框架,用于构建智能、特定于任务的代理。凭借其无缝集成的工具、安全的代码执行和高级检索功能,它是 AI 开发人员不可或缺的库。立即试用并将您的项目提升到一个新的水平!
原文链接:Exploring SmolAgents: Building Intelligent Agents with Hugging Face
汇智网翻译整理,转载请标明出处