在開發 AI 應用時,很多開發者對語言模型的函式呼叫機制存在誤解。實際上,當 LLM 回傳函式呼叫時,它只是提供函式名稱和相關引數,並不會實際執行該函式。這個重要的區別決定了我們如何設計與實作 AI 系統的互動流程。
函式呼叫的完整生命週期
當 LLM 建議呼叫某個函式時,開發者必須在客戶端應用程式中完成一個閉環流程。
函式呼叫生命週期流程圖
此圖詳細描繪了從使用者請求到最終 AI 回應的完整函式呼叫流程。
這個流程確保了 AI 系統的安全性和可控性,同時也為開發者提供了靈活整合外部工具的能力。
實作函式呼叫:推薦系統範例
讓我們透過一個實際的推薦系統範例來理解函式呼叫的完整流程。
1. 推薦函式的實作
首先,我們需要定義一個推薦函式,它將根據不同主題提供建議。
import json
def recommend(topic, rating="good"):
"""根據主題和評分提供推薦"""
if "time travel" in topic.lower():
return json.dumps({"topic": "time travel", "recommendation": "Back to the Future", "rating": rating})
elif "recipe" in topic.lower():
return json.dumps({"topic": "recipe", "recommendation": "Classic Carbonara", "rating": rating})
elif "gift" in topic.lower():
return json.dumps({"topic": "gift", "recommendation": "A good book", "rating": rating})
else:
return json.dumps({"topic": topic, "recommendation": "unknown"})
此函式根據輸入的 topic
提供不同的推薦,並以 JSON 格式回傳結果。
2. 建立對話請求
接下來,我們需要構建傳送給 LLM 的請求,包含使用者訊息和工具定義。
user_request = "請為我推薦以下三樣東西:一部時間旅行電影、一道食譜和一份禮物。"
messages = [{"role": "user", "content": user_request}]
tools = [
{
"type": "function",
"function": {
"name": "recommend",
"description": "為任何主題提供推薦。",
"parameters": {
"type": "object",
"properties": {
"topic": {"type": "string", "description": "需要推薦的主題。"},
"rating": {"type": "string", "description": "推薦的評分。", "enum": ["good", "bad", "terrible"]},
},
"required": ["topic"],
},
},
}
]
tools
陣列詳細定義了 recommend
函式的結構,這能幫助 LLM 正確地生成函式呼叫。
3. 處理函式呼叫與執行
當 LLM 決定使用函式時,我們需要提取並執行這些函式呼叫。
from openai import OpenAI
client = OpenAI() # 假設 API 金鑰已設定
# 第一步:讓 LLM 生成函式呼叫
response = client.chat.completions.create(
model="gpt-3.5-turbo-1106",
messages=messages,
tools=tools,
tool_choice="auto",
)
response_message = response.choices[0].message
tool_calls = response_message.tool_calls
# 第二步:執行函式並收集結果
if tool_calls:
available_functions = {"recommend": recommend}
messages.append(response_message) # 將 AI 的回應(包含函式呼叫)加入歷史
for tool_call in tool_calls:
function_name = tool_call.function.name
function_to_call = available_functions[function_name]
function_args = json.loads(tool_call.function.arguments)
function_response = function_to_call(**function_args)
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
})
# 第三步:將函式結果傳回 LLM 以生成最終回應
second_response = client.chat.completions.create(
model="gpt-3.5-turbo-1106",
messages=messages,
)
print(second_response.choices[0].message.content)
這個流程的核心在於兩次 API 呼叫:第一次是為了讓 LLM 生成函式呼叫的指令,第二次是將函式執行的結果傳回,讓 LLM 生成最終的自然語言回應。
進階框架:Microsoft Semantic Kernel
雖然手動處理函式呼叫是可行的,但在複雜系統中會變得繁瑣。Semantic Kernel (SK) 是微軟開發的開源框架,旨在簡化這一過程。
SK 的核心是外掛 (Plugins),它們是技能和函式的封裝。SK 使用與 OpenAI 相容的定義,使其能夠無縫消費和發布外掛,極大地簡化了構建複雜 AI 應用的過程。對於需要整合多個工具和服務的複雜代理系統,採用 SK 這樣的框架是更佳的選擇。
結論
函式呼叫機制為 LLM 提供了與外部世界互動的能力,極大地擴充了 AI 系統的實用性。理解 LLM 僅生成呼叫指令而非直接執行的核心概念,是構建安全、有效 AI 應用的基礎。透過本文的範例,我們展示了從函式定義到結果整合的完整流程。對於更複雜的應用,Semantic Kernel 等框架提供了更結構化、更強大的解決方案,值得開發者深入探索。