介紹 smolagents,一個構建智慧體的簡單庫
今天我們釋出了
smolagents
,這是一個非常簡單的庫,可為語言模型解鎖智慧體能力。以下是它的一些亮點:
from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel
agent = CodeAgent(tools=[DuckDuckGoSearchTool()], model=HfApiModel())
agent.run("How many seconds would it take for a leopard at full speed to run through Pont des Arts?")

目錄
🤔 什麼是智慧體?
任何高效使用 AI 的系統都需要為 LLM 提供對現實世界的某種訪問許可權:例如,調用搜索工具以獲取外部資訊,或對某些程式進行操作以解決任務的可能性。換句話說,LLM 應該擁有**代理能力**。智慧體程式是 LLM 通往外部世界的門戶。
AI 智慧體是**LLM 輸出控制工作流的程式**。
任何利用 LLM 的系統都會將 LLM 輸出整合到程式碼中。LLM 輸入對程式碼工作流的影響是 LLM 在系統中的代理能力水平。
請注意,根據此定義,“智慧體”不是一個離散的 0 或 1 定義:相反,“代理能力”在一個連續的範圍內演變,具體取決於您賦予 LLM 對工作流的權力大小。
下表說明了不同系統中代理能力的變化
代理能力等級 | 描述 | 名稱 | 示例模式 |
---|---|---|---|
☆☆☆ | LLM 輸出對程式流程無影響 | 簡單處理器 | process_llm_output(llm_response) |
★☆☆ | LLM 輸出決定基本控制流 | 路由器 | if llm_decision(): path_a() else: path_b() |
★★☆ | LLM 輸出決定函式執行 | 工具呼叫 | run_function(llm_chosen_tool, llm_chosen_args) |
★★★ | LLM 輸出控制迭代和程式繼續 | 多步智慧體 | while llm_should_continue(): execute_next_step() |
★★★ | 一個代理工作流可以啟動另一個代理工作流 | 多智慧體 | if llm_trigger(): execute_agent() |
多步智慧體具有以下程式碼結構
memory = [user_defined_task]
while llm_should_continue(memory): # this loop is the multi-step part
action = llm_get_next_action(memory) # this is the tool-calling part
observations = execute_action(action)
memory += [action, observations]
因此,該系統在一個迴圈中執行,每一步執行一個新動作(該動作可能涉及呼叫一些預先確定的**工具**,這些工具只是函式),直到其觀察結果表明已達到令人滿意的狀態以解決給定任務。以下是一個多步智慧體如何解決一個簡單數學問題的示例

✅ 何時使用智慧體 / ⛔ 何時避免使用它們
當您需要 LLM 來確定應用程式的工作流時,智慧體非常有用。但它們通常是殺雞用牛刀。問題是:我是否真的需要工作流的靈活性才能有效地解決手頭的任務?如果預定的工作流經常不足,則意味著您需要更大的靈活性。讓我們舉一個例子:假設您正在開發一個處理衝浪旅行網站客戶請求的應用程式。
您可以提前知道請求將屬於兩個類別中的一個(基於使用者選擇),並且您為這兩個類別中的每個類別都有預定義的工作流。
- 想了解旅行資訊?⇒ 讓他們使用搜索欄搜尋您的知識庫
- 想與銷售人員交談?⇒ 讓他們填寫聯絡表格。
如果這種確定性工作流適用於所有查詢,那麼請盡情編寫所有程式碼!這將為您提供一個 100% 可靠的系統,沒有任何由於讓不可預測的 LLM 干預您的工作流而引入的錯誤風險。為了簡單和健壯性,建議避免使用任何代理行為。
但是,如果工作流無法提前確定得那麼好呢?
例如,使用者想問:“我星期一可以來,但我忘了帶護照,所以可能會延遲到星期三,星期二早上可以帶我和我的東西去衝浪,併購買取消保險嗎?”這個問題取決於許多因素,上面預先確定的任何標準可能都不足以滿足此請求。
如果預定的工作流經常不足,則意味著您需要更大的靈活性。
這就是代理設定有幫助的地方。
在上面的例子中,您只需建立一個多步代理,它可以訪問天氣 API 以獲取天氣預報、Google Maps API 以計算旅行距離、員工可用性儀表板以及知識庫上的 RAG 系統。
直到最近,計算機程式還侷限於預設的工作流,試圖透過堆積 if/else 開關來處理複雜性。它們專注於極其狹窄的任務,例如“計算這些數字的總和”或“找到此圖中的最短路徑”。但實際上,大多數現實生活中的任務,例如我們上面提到的旅行示例,都不適合預設的工作流。代理系統為程式打開了廣闊的現實世界任務!
程式碼智慧體
在多步智慧體中,在每一步,LLM 都可以以呼叫外部工具的形式編寫一個動作。一種常見的(Anthropic、OpenAI 和許多其他公司使用的)編寫這些動作的格式通常是不同程度的“將動作編寫為工具名稱和要使用的引數的 JSON,然後您解析該 JSON 以瞭解要執行哪個工具以及使用哪個引數”。
多篇 研究 論文 表明,在程式碼中呼叫 LLM 工具效果更好。
其原因很簡單,我們**專門設計了我們的程式碼語言,使其成為表達計算機執行操作的最佳方式**。如果 JSON 片段是更好的表達方式,那麼 JSON 將是頂級的程式語言,而程式設計將是人間地獄。
下圖摘自 可執行程式碼操作能激發更好的 LLM 智慧體,說明了在程式碼中編寫操作的一些優點

在程式碼中而不是 JSON 類似片段中編寫操作提供了更好的
- **可組合性:** 您可以將 JSON 操作相互巢狀,或者定義一組 JSON 操作供以後重用,就像您可以定義一個 Python 函式一樣嗎?
- **物件管理:** 如何在 JSON 中儲存
generate_image
等操作的輸出? - **通用性:** 程式碼旨在簡單地表達計算機可以做的任何事情。
- **LLM 訓練資料中的表示:** 大量高質量的程式碼操作已包含在 LLM 的訓練資料中,這意味著它們已經為此進行了訓練!
介紹 smolagents:讓智慧體變得簡單 🥳
我們構建 smolagents
的目標是
✨ **簡單性**:智慧體的邏輯程式碼只有約數千行(請參閱 此檔案)。我們將抽象層保持在原始程式碼之上的最小形態!
🧑💻 **一流的程式碼智慧體支援**,即編寫程式碼動作的智慧體(而不是“用於編寫程式碼的智慧體”)。為了確保安全,我們透過 E2B 支援在沙盒環境中執行。
- 除了
CodeAgent
類之外,我們仍然支援將動作作為 JSON/文字 blob 編寫的標準ToolCallingAgent
。
🤗 **Hub 整合**:您可以將工具分享到 Hub 並從 Hub 載入工具,未來還會更多!
🌐 **支援任何 LLM**:它支援在 Hub 上以 transformers
版本載入或透過我們的推理 API 託管的模型,但也透過我們的 LiteLLM 整合支援來自 OpenAI、Anthropic 和許多其他公司的模型。
smolagents
是 transformers.agents
的繼任者,未來將取代它,因為 transformers.agents
將被棄用。
構建智慧體
要構建智慧體,您至少需要兩個元素
tools
:智慧體可以訪問的工具列表model
:將作為智慧體引擎的 LLM。
對於 model
,您可以使用任何 LLM,無論是使用我們利用 Hugging Face 免費推理 API 的 HfApiModel
類的開放模型(如上面的豹子示例所示),還是可以使用 LiteLLMModel
來利用 litellm 並從 100 多個不同的雲 LLM 中進行選擇。
對於工具,您只需建立一個帶有輸入和輸出型別提示的函式,以及提供輸入描述的文件字串,然後使用 @tool
裝飾器將其轉換為工具。
以下是如何建立一個從 Google 地圖獲取旅行時間的自定義工具,以及如何將其用於旅行規劃智慧體
from typing import Optional
from smolagents import CodeAgent, HfApiModel, tool
@tool
def get_travel_duration(start_location: str, destination_location: str, transportation_mode: Optional[str] = None) -> str:
"""Gets the travel time between two places.
Args:
start_location: the place from which you start your ride
destination_location: the place of arrival
transportation_mode: The transportation mode, in 'driving', 'walking', 'bicycling', or 'transit'. Defaults to 'driving'.
"""
import os # All imports are placed within the function, to allow for sharing to Hub.
import googlemaps
from datetime import datetime
gmaps = googlemaps.Client(os.getenv("GMAPS_API_KEY"))
if transportation_mode is None:
transportation_mode = "driving"
try:
directions_result = gmaps.directions(
start_location,
destination_location,
mode=transportation_mode,
departure_time=datetime(2025, 6, 6, 11, 0), # At 11, date far in the future
)
if len(directions_result) == 0:
return "No way found between these places with the required transportation mode."
return directions_result[0]["legs"][0]["duration"]["text"]
except Exception as e:
print(e)
return e
agent = CodeAgent(tools=[get_travel_duration], model=HfApiModel(), additional_authorized_imports=["datetime"])
agent.run("Can you give me a nice one-day trip around Paris with a few locations and the times? Could be in the city or outside, but should fit in one day. I'm travelling only with a rented bicycle.")
在收集旅行時間和執行計算後,智慧體返回最終方案
One-day Paris bike trip itinerary:
1. Start at Eiffel Tower at 9:00 AM.
2. Sightseeing at Eiffel Tower until 10:30 AM.
3. Travel to Notre-Dame Cathedral at 10:46 AM.
4. Sightseeing at Notre-Dame Cathedral until 12:16 PM.
5. Travel to Montmartre at 12:41 PM.
6. Sightseeing at Montmartre until 2:11 PM.
7. Travel to Jardin du Luxembourg at 2:33 PM.
8. Sightseeing at Jardin du Luxembourg until 4:03 PM.
9. Travel to Louvre Museum at 4:12 PM.
10. Sightseeing at Louvre Museum until 5:42 PM.
11. Lunch break until 6:12 PM.
12. Planned end time: 6:12 PM.
構建工具後,將其分享到 Hub 就像這樣簡單
get_travel_duration.push_to_hub("{your_username}/get-travel-duration-tool")
您可以在 這個空間 下看到結果。您可以在 空間中的 tool.py 檔案 下檢視工具的邏輯。如您所見,該工具實際上被匯出為一個繼承自 Tool
類的類,這是我們所有工具的底層結構。
開放模型在智慧體工作流中的能力如何?
我們建立了 CodeAgent
例項,並使用一些領先的模型,在 此基準測試 上進行了比較,該基準測試從幾個不同的基準測試中收集問題,以提供各種挑戰的混合。
在此處查詢基準測試 以獲取有關所用代理設定的更多詳細資訊,並檢視程式碼代理與工具呼叫代理的比較(劇透:程式碼效果更好)。
這項比較表明,開源模型現在可以與最好的閉源模型媲美!