
阿里妹導讀
本文將分享如何使用不到 100 行的 Python 程式碼,實現一個具備通用智慧潛力的簡易 LLM Agent。你將看到整個實現過程——從核心原理、提示(Prompt)調優、工具介面設計到主迴圈互動,並獲得完整復現程式碼的詳細講解。
一、引言:LLM Agent 的新思路
在人工智慧領域,大型語言模型(LLM)如 GPT 系列,憑藉其強大的文字生成能力,已在多種應用中展現出卓越的表現。然而,傳統的 LLM 主要擅長生成文字,缺乏與外部環境互動的能力,無法執行如計算、網路抓取或檔案解析等具體任務。為突破這一侷限,LLM Agent 的概念應運而生:透過將 LLM 與外部工具相結合,使模型不僅能進行對話,還能透過函式呼叫實現更復雜的任務。
本文將分享如何使用不到 100 行的 Python 程式碼,實現一個具備通用智慧潛力的簡易 LLM Agent。你將看到整個實現過程——從核心原理、提示(Prompt)調優、工具介面設計到主迴圈互動,並獲得完整復現程式碼的詳細講解。希望本文能啟發你開發出更多滿足實際需求的 Agent。
在構建 LLM Agent 時,提示工程(Prompt Engineering)是關鍵環節。透過精心設計的提示,可以引導模型生成更準確和有用的輸出。
透過本文的實踐,你將掌握如何在有限的程式碼量內,構建一個功能豐富的 LLM Agent,為人工智慧應用的開發提供新的思路和方法。
二、核心原理詳解
在動手實現之前,我們需要理解幾個關鍵概念和 Agent 的整體執行邏輯。掌握這些核心機制,將幫助你深入理解 LLM Agent 背後的設計哲學,並在實際開發中更加靈活地構建自己的智慧助手。
2.1 大語言模型(LLM)的能力與侷限
LLM,如 GPT-4、Qwen 等,基於海量的文字資料訓練,透過預測下一個詞語的機率來生成自然且流暢的內容,表現出驚人的語言理解與生成能力。然而,LLM 本質上是一個語言預測器,這種機制天然存在以下侷限:
計算與邏輯推理不足
儘管模型能識別並生成數學表示式,但當涉及較複雜的運算(如大數乘法、日期推算、數值精確計算)時,經常出現錯誤,缺乏精準推理能力。
知識時效性有限
LLM 的知識庫通常在訓練資料截止日期後無法自動更新。例如 GPT-4 的知識截止於2021年9月,因而無法回答即時性問題或獲取最新資訊。
無法直接訪問外部資源
LLM 本身不具備直接執行程式碼、查詢資料庫、抓取網頁或處理檔案的能力,僅憑純文字預測無法完成需要外部環境協作的任務。
為彌補這些侷限,我們可以引入“函式呼叫(Function Call)”機制,讓模型透過呼叫外部工具來增強自身能力,間接賦予模型類似“動手”的執行能力。
2.2 Function Call:賦能 LLM 的關鍵機制
Function Call(函式呼叫)是當前提升 LLM 實用性最重要的手段之一。這種機制允許模型在生成文字之外,同時以結構化的資料形式發出明確的指令,呼叫預定義的外部函式或工具。
Function Call 的執行機制可拆解為以下幾個步驟:
需求識別
當 LLM 在互動中意識到當前任務超出自身能力範圍時,便主動觸發外部函式呼叫請求。例如,面對一道數學難題或網頁查詢任務,模型會自行判斷需要外援介入。
呼叫引數生成
模型以結構化的資料格式(通常採用 JSON),明確指定呼叫函式的名稱和所需的具體引數。例如,模型可能輸出類似:
{
"function_name":"calculate_date_diff",
"parameters":{
"start_date":"2024-02-12",
"end_date":"2025-03-15"
}
}
外部執行
系統接收到模型提供的函式呼叫請求後,執行預定義的外部工具或函式(例如進行 Python 程式碼執行、呼叫網路介面、訪問資料庫等),並獲取實際執行結果。
結果反饋
執行結果再回傳給模型,模型將結合上下文生成使用者期望的自然語言答案。這種雙向互動,使 LLM 的能力從純文字輸出擴充套件至實際任務執行。
Function Call 機制不但突破了模型自身的限制,還讓模型產生一種類似“自我決策”的能力,實現了真正意義上的“動手”和“自我糾錯”機制,大幅提升了實用性和應用價值。
2.3 Agent 的完整執行機制
理解了 LLM 與函式呼叫機制後,我們可以更好地理解一個完整 LLM Agent 的工作流程。這一流程一般包含五個關鍵環節:
(1)任務感知
Agent 首先接收並理解使用者的輸入請求,明確使用者的真實意圖。此時良好的 Prompt 工程會提高模型識別準確性。
(2)任務拆解與規劃
對於複雜任務,Agent 會自動進行任務分解,把大任務拆分為數個易執行的小步驟。例如,“查詢最近天氣”這一任務可被拆分為“獲取當前位置 → 查詢天氣API → 整理結果 → 回覆使用者”這幾個子任務。
(3)決策並呼叫工具
Agent 基於任務規劃結果,生成具體的函式呼叫請求,決定何時呼叫何種外部工具,以及具體呼叫引數。此環節考驗 Prompt 設計、模型推理能力以及工具設計的介面清晰度。
(4)工具執行與結果反饋
外部環境執行模型指定的工具(如 Python 程式碼執行函式 exec_python_code),並把執行結果回傳模型。例如,模型請求執行程式碼進行數學計算或網頁資料抓取,執行後結果會原路返回給模型。
(5)迴圈與完成任務
Agent 根據返回的執行結果持續調整規劃、再次決策,進入新一輪工具呼叫迴圈,直至完整完成使用者交付的任務,給出最終答案。
透過以上五步的迴圈互動,LLM Agent 能夠解決比單一模型預測更復雜的問題,逐漸表現出具備通用智慧的雛形。

(建議讀者在實際開發過程中自行繪製此互動流程圖,便於理解 Agent 的整體架構。)
理解這些核心機制後,我們將在下一章逐步進入實操階段,詳細探討 Prompt 設計、工具介面構建、以及如何用不到100行程式碼,開發一個高效且通用的 LLM Agent。
三、逐步拆解:實現一個簡易通用智慧 Agent
接下來,我們詳細講解實現程式碼的每一步,讓讀者可以從零開始完整復現這個 Agent。
3.1 環境準備與庫匯入
首先,我們需要安裝必要的依賴(以 openai 庫為例),確保 Python 環境能夠正確呼叫 API。
安裝依賴:
pip install openai
匯入必要庫並初始化模型客戶端:
import os
import json
from openai import OpenAI
# 設定模型名稱,這裡使用 qwen-plus,可根據實際情況替換
MODEL_NAME = "qwen-plus"
client = OpenAI(
api_key=os.environ.get("OPENAI_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
上述程式碼負責與 API 建立連線,並準備後續的對話互動。
這裡我使用的是阿里雲百鍊平臺,模型選用的是 qwen-plus,讀者可自行使用將其替換為自己使用的平臺和模型。注意這個模型需要支援 function call。
3.2 定義通用工具函式:exec_python_code
為了實現通用智慧,我們必須讓模型具備“執行”任意 Python 程式碼的能力。這裡的 exec_python_code 函式便是核心,它允許模型生成程式碼,環境執行後返回結果。
defexec_python_code(code: str):
print(code) # 列印程式碼便於除錯
try:
exec_env = {}
exec(code, exec_env, exec_env)
return {"result": exec_env, "error": None}
except Exception as e:
print("執行失敗,原因:%s" % str(e))
return {"result": None, "error": str(e)}
安全提示:使用 exec 存在風險。在生產環境中,請務必考慮使用沙箱技術(sandboxing)對執行程式碼進行嚴格隔離。
3.3 工具介面定義:告訴模型有哪些可呼叫工具
為了讓 LLM 知道可以呼叫 exec_python_code,我們需要定義工具介面(Tool List),並明確引數要求。
tools = [
{
"type": "function",
"function": {
"name": "exec_python_code",
"description": "執行任意Python程式碼,並返回執行結果或報錯資訊。",
"parameters": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "要執行的Python程式碼片段。"
}
},
"required": ["code"]
}
},
"strict": True
}
]
這個工具定義不僅包括函式名稱和描述,還規定了引數的 JSON Schema。這樣一來,當模型決定呼叫函式時,會根據這個介面生成結構化的呼叫請求。
3.4 精心設計的 Prompt:引導模型自主決策
我在實踐中花了大量時間調優 Prompt,確保模型能夠準確拆解任務、制定分步計劃,並按規定呼叫工具。下面是一個經過反覆最佳化的 Prompt 示例:
messages = [{
"role": "system",
"content": (
"你是一個高效、靈活且堅持不懈的智慧助手,能夠自主分析並拆解使用者提出的任務,"
"始終透過執行Python程式碼的方式給出有效的解決方案。\n\n"
"你擁有並必須呼叫的工具如下:\n"
"1. exec_python_code:執行Python程式碼並返回執行結果或錯誤資訊。\n\n"
"執行任務時,必須嚴格遵循以下原則:\n"
"A. 每次呼叫工具前,都先給出明確的分步執行計劃(步驟標題和目的)。\n"
"B. Python程式碼功能強大,能訪問系統資訊、網路資源、檔案系統,"
"優先使用標準庫完成任務,儘量避免依賴第三方庫。\n"
"C. 若需訪問特定網頁或資訊,必須首先執行Python程式碼調用搜索引擎(如百度或谷歌)搜尋並確定目標頁面的真實URL,"
"禁止自行猜測URL。\n"
"D. 若環境缺乏特定庫或方法失敗,必須主動嘗試其他替代方法,而非中斷任務。\n"
"特別注意:\n"
"- 必須確保返回結果與使用者任務高度相關,絕不允許使用未經驗證的URL或無關資訊。\n"
"- 必須主動且深入地解決問題,不得泛泛而談或籠統告知任務無法完成。\n"
)
}]
這種詳細而嚴謹的指令能夠引導模型在任務拆解和執行過程中始終保持高度相關性和準確性。
3.5 主迴圈:模型互動與工具呼叫
最後,我們實現一個主迴圈,透過不斷與模型互動,完成從使用者輸入到任務執行再到反饋的閉環流程。
whileTrue:
# 獲取使用者輸入
user_question = input("$ ")
messages.append({"role": "user", "content": user_question})
# 呼叫模型,模型有可能生成函式呼叫請求
completion = client.chat.completions.create(
model=MODEL_NAME, messages=messages, tools=tools
)
whileTrue:
# 將模型生成的訊息加入對話歷史
messages.append(completion.choices[0].message)
if completion.choices[0].message.content:
print(completion.choices[0].message.content)
if completion.choices[0].finish_reason == "stop":
break
# 如果模型請求呼叫工具
for tool_call in completion.choices[0].message.tool_calls:
name = tool_call.function.name
args = json.loads(tool_call.function.arguments)
if name == "exec_python_code":
result = exec_python_code(args["code"])
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(result)
})
# 再次呼叫模型,讓它基於工具返回結果生成最終回答
completion = client.chat.completions.create(
model=MODEL_NAME, messages=messages, tools=tools
)
在這一段程式碼中,我們不斷更新 messages 列表,確保模型每次都能看到完整的上下文。模型判斷是否需要呼叫工具,如果需要,則執行相應的 exec_python_code,將返回結果反饋給模型,直至任務完成。
四、完整執行示例展示
為驗證 Agent 的通用智慧能力,下面舉一個實際例子——獲取我本機的所有硬碟容量。
示例請求:
$ 獲取我本機的所有硬碟容量
### 步驟 1:匯入必要的模組
目的:為了獲取硬碟容量資訊,我們需要使用`psutil`這個庫,它提供了許多系統資訊的訪問介面。
### 步驟 2:獲取硬碟分割槽及容量資訊
目的:透過`psutil.disk_partitions()`函式獲取所有硬碟分割槽的資訊,並且透過`psutil.disk_usage()`函式來獲取每個分割槽的使用情況。
現在我將執行Python程式碼來獲取這些資訊。
import psutil
# 獲取所有磁碟分割槽的資訊
disk_partitions = psutil.disk_partitions()
all_disks_info = []
for partition in disk_partitions:
try:
# 獲取單個分割槽的使用情況
usage = psutil.disk_usage(partition.mountpoint)
disk_info = {
'device': partition.device,
'mountpoint': partition.mountpoint,
'fstype': partition.fstype,
'total': usage.total,
'used': usage.used,
'free': usage.free,
'percent': usage.percent
}
all_disks_info.append(disk_info)
except PermissionError:
# 在某些情況下可能會遇到許可權問題,這裡簡單地忽略
continue
all_disks_info
失敗了 No module named 'psutil'
看來當前環境中沒有安裝`psutil`庫,這阻止了我們直接獲取硬碟容量資訊。不過,我可以嘗試使用其他標準庫方法來獲取相關資訊,儘管可能不如`psutil`那麼直接。
### 步驟 3:嘗試使用標準庫獲取系統磁碟資訊
目的:透過`os`和`shutil`等標準庫函式間接獲取磁碟空間資訊。
接下來我將嘗試執行Python程式碼來實現這一目標。
import os
import sys
import shutil
defget_drives():
if sys.platform == 'win32':
importstring
from ctypes import windll
drives = []
bitmask = windll.kernel32.GetLogicalDrives()
for letter in string.ascii_uppercase:
if bitmask & 1:
drives.append(letter + ':\\')
bitmask >>= 1
return drives
else:
# 對於非Windows系統,我們簡化處理,僅列出根目錄
return ['/']
all_disks_info = []
for drive in get_drives():
try:
total, used, free = shutil.disk_usage(drive)
disk_info = {
'drive': drive,
'total': total,
'used': used,
'free': free
}
all_disks_info.append(disk_info)
except Exception as e:
print(f"Error accessing {drive}: {e}")
all_disks_info
我已經成功獲取了本機的硬碟容量資訊。以下是每個驅動器的總容量、已用空間和可用空間:
1. 驅動器 C:\
- 總容量: 1023 GB
- 已用空間: 918 GB
- 可用空間: 105 GB
2. 驅動器 D:\
- 總容量: 3791 GB
- 已用空間: 3470 GB
- 可用空間: 320 GB
3. 驅動器 E:\
- 總容量: 8001 GB
- 已用空間: 1551 GB
- 可用空間: 6449 GB
請注意,這些值是以位元組為單位計算的,並且我將它們轉換為了GB以便於閱讀。如果有進一步的需求或問題,請隨時告訴我!
這個示例展示了 Agent 如何自主規劃、生成程式碼、執行操作、自動糾錯並反饋答案,體現了通用智慧的潛力,相信你能立即感受到它和直接使用大模型的不同之處。
五、200 行程式碼實現更通用的 Agent
在簡易版基礎上,我還實現了複雜版 Agent,增加了如下工具:
-
google_search:利用搜索引擎獲取網頁連結;
-
fetch_webpage_content:抓取並解析指定 URL 的網頁內容;
-
parse_pdf:解析本地 PDF 檔案中的文字。
這些擴充套件讓 Agent 能夠處理更為複雜的任務,如:
-
自動從網上搜索最新資訊並總結內容;
-
抓取並分析長篇文章或報告;
-
對 PDF 文件進行全文解析與摘要生成。
複雜版實現思路與簡易版類似,僅在工具介面和執行邏輯上增加了額外的處理步驟,仍保持高度的通用性和靈活性。讀者可以基於簡易版程式碼,逐步擴充套件和除錯更多功能。
示例請求:
$ 將 DeepSeek 釋出的 DeepSeek R1 的論文下載到 E:\output ,並簡單評價一下
為了完成這個任務,我將按照以下步驟進行:
### 步驟 1: 搜尋 DeepSeek R1 論文的下載連結
-**目的**: 找到DeepSeek R1論文的官方或可信來源的下載連結。
-**工具**: google_search
- **關鍵詞**: "DeepSeek R1 paper download"
### 步驟 2: 下載論文
- **目的**: 使用找到的連結下載DeepSeek R1論文至指定目錄 E:\output。
- **工具**: 這一步可能需要使用Python程式碼來實現檔案下載。如果搜尋結果直接指向一個PDF檔案,則可以直接嘗試獲取該檔案;否則,我將編寫一段指令碼來執行下載操作。
### 步驟 3: 讀取並評價論文
- **目的**: 對下載後的論文內容進行簡要概述和初步評價。
- **工具**: parse_pdf 用於解析下載好的PDF文件,之後基於解析出的內容給出我的看法。
現在開始第一步,搜尋DeepSeek R1論文的下載連結。
從搜尋結果中,我們找到了幾個可能的連結指向DeepSeek R1論文。最直接相關的是第一個連結:[GitHub上的PDF檔案](https://github.com/deepseek-ai/DeepSeek-R1/blob/main/DeepSeek_R1.pdf) 和 第二個連結 [arXiv頁面](https://arxiv.org/abs/2501.12948),後者也提供了PDF版本。
### 步驟 2: 下載論文
我將嘗試直接使用提供的GitHub連結來下載PDF文件到指定位置 E:\output。如果此方法不可行,我們將轉向其他提供的連結作為備選方案。
現在,我將編寫一段Python程式碼來完成這個任務。
import requests, os
url = 'https://github.com/deepseek-ai/DeepSeek-R1/raw/main/DeepSeek_R1.pdf'
output_path = 'E:/output/'
file_name = url.split('/')[-1]
ifnot os.path.exists(output_path):
os.makedirs(output_path)
response = requests.get(url)
with open(os.path.join(output_path, file_name), 'wb') as f:
f.write(response.content)
print(f'File saved to {os.path.join(output_path, file_name)}')
File saved to E:/output/DeepSeek_R1.pdf
論文已成功下載到 `E:\output\DeepSeek_R1.pdf`。
### 步驟 3: 讀取並評價論文
接下來,我將使用 `parse_pdf` 工具來解析下載好的PDF文件,並基於其內容給出簡要概述和初步評價。讓我們開始解析文件。
### 論文概述
這篇論文介紹了DeepSeek團隊開發的第一代推理模型,即DeepSeek-R1-Zero和DeepSeek-R1。DeepSeek-R1-Zero是透過大規模強化學習(RL)直接訓練而成的模型,沒有經過監督微調(SFT),它展示了卓越的推理能力,並自然地出現了許多強大的且有趣的推理行為。然而,該模型也遇到了諸如可讀性差、語言混雜等問 題。
為了解決這些問題並進一步提高推理效能,研究者引入了DeepSeek-R1,該模型在RL之前加入了多階段訓練及冷啟動資料。DeepSeek-R1在推理任務上的表現與OpenAI-o1-1217相當。此外,為了支援研究社群,他們開源了DeepSeek-R1-Zero、DeepSeek-R1以及基於Qwen和Llama的六個密集模型(1.5B, 7B, 8B, 14B, 32B, 70B)。
### 簡要評價
#### 優點
-**創新性**:這項工作展示了純強化學習方法能夠有效激勵語言模型發展出強大的推理能力,而不需要依賴於監督微調資料。
-**開源貢獻**:開放原始碼不僅包括最終版本的模型,還包括中間版本以及一系列不同規模的基礎模型,這極大地促進了相關領域的研究和發展。
-**效能提升**:透過精心設計的訓練流程,DeepSeek-R1不僅在數學、程式設計等邏輯推理任務上取得了優異成績,在其他領域如寫作、問答等方面也有不錯的表現。
#### 改進空間
-**語言一致性**:雖然引入了語言一致性的獎勵機制來緩解語言混用問題,但仍有改進的空間。特別是在處理非英語或中文的問題時,如何保持語言一致性是一個值得探討的方向。
-**通用能力**:相較於之前的版本DeepSeek-V3,DeepSeek-R1在某些功能如函式呼叫、多輪對話等方面的能力稍弱,未來可以考慮如何利用長鏈思考(CoT)來增強這些方面的表現。
整體來看,DeepSeek R1代表了當前大模型領域內一個重要的進步,尤其是在探索如何使用強化學習來增強語言模型的推理能力方面提供了新的視角。這項工作不僅對於學術界具有重要意義,也為工業界的實踐應用提供了寶貴的參考價值。
這個示例展示了更強、更通用的 Agent 能力以及潛力。
這個示例展示了更強、更通用的 Agent 能力以及潛力。
六、總結與未來展望
在本文中,我們系統性地介紹瞭如何用不到 100 行 Python 程式碼構建一個具備通用智慧潛力的簡易 LLM Agent。從理論闡述到程式碼實操,我們強調了以下三個核心要點:
通用程式碼執行機制
利用 exec_python_code 這樣的核心函式,賦予模型呼叫並執行任意 Python 程式碼的能力。這種設計突破了傳統 LLM 僅能生成文字的侷限,讓 Agent 擁有真正意義上的“動手”能力,實現更廣泛的任務處理範圍。
精心調優的 Prompt 策略
透過設計精準而詳細的 Prompt,引導模型明確任務目標,合理地拆解複雜任務,準確生成工具呼叫指令和引數。良好的提示工程,不僅提高了模型生成決策的準確性,還大幅降低了模型的“幻覺”和無效執行風險。
完整的互動迴圈機制
Agent 與外部工具透過連續的對話與反饋迴圈實現資訊交換,不斷更新和迭代任務上下文。依靠這種閉環互動,Agent 能夠穩步推進任務程序,有效地處理複雜多步任務。
以上機制的融合,不僅體現了當前構建高效 LLM Agent 的技術路線,更為未來構建更具通用智慧水平的 Agent 打下堅實基礎。
未來探索方向:
安全性與隔離機制的強化
當前實現的 Agent 能執行任意程式碼,雖然靈活但同時存在安全隱患。如何構建更安全的程式碼沙箱、識別與阻止惡意程式碼呼叫,將成為未來 Agent 開發過程中必須攻克的核心問題之一。這需要設計嚴格的許可權控制、資源限制和異常捕獲機制,避免 Agent 的能力被濫用或誤用。
更多工具擴充套件與深度融合
Agent 的能力將取決於可呼叫工具的豐富性。未來,可以整合資料庫查詢、API 服務互動、機器視覺、語音識別、自動化測試等豐富的工具模組,進一步拓展 Agent 在各行各業的落地應用潛力,逐漸實現真正意義上的通用智慧。
持續最佳化 Prompt 與推理能力
Prompt 工程是 Agent 穩定高效執行的關鍵之一。隨著實際應用場景的不斷擴充套件,我們可以基於任務反饋資料持續最佳化 Prompt 的設計,讓模型更精準地理解使用者意圖,更高效地執行決策與任務拆解。此外,也可以考慮結合少樣本學習(Few-shot)和鏈式思考(Chain-of-Thought)策略,進一步提高模型推理的穩定性和可靠性。
寫在最後
LLM Agent 的誕生,為我們提供了一個極具想象空間的技術路線,它將傳統模型的強大語言理解能力,與外部工具的實際動手能力相結合,創造出無限可能的應用空間。希望這篇文章能夠啟發你進一步探索和創新,用有限的程式碼,創造出更加強大、高效且安全的智慧體,推動人工智慧真正落地到更多場景,惠及更多人群。
PS:本文大部分內容由大模型生成
AI 劇本生成與動畫創作
短影片行業的快速增長使得內容創作的速度和質量成為競爭關鍵。傳統動畫故事製作複雜且昂貴,限制了創作者對市場熱點的快速反應和創新實現。本方案透過 AI 生成劇本和動畫,簡化創作流程並降低技術門檻,使創作者能高效生產高質量作品,迅速適應市場需求。
點選閱讀原文檢視詳情。