文章目錄
- 逐段講清 **LLM Function Calling(函數調用)** 的典型鏈路。
- 1. 角色與概念 | Actors & Concepts
- 2. 全流程時序 | End-to-End Sequence
- 3. 關鍵細節 | Key Implementation Notes
- 4. 最小可用示例(偽代碼) | Minimal Example (Pseudo-Python)
- 5. 常見坑 / FAQ
- TL;DR
逐段講清 LLM Function Calling(函數調用) 的典型鏈路。
1. 角色與概念 | Actors & Concepts
ZH:
- 開發者 (Developer):用 JSON-Schema 描述可調用函數。
- 用戶 (User):提出自然語言請求。
- 模型 (LLM):在推理時決定是否調用函數、選哪一個、填什么參數。
- 執行器 (Caller / Tool Runtime):真正跑代碼或訪問外部 API,把結果回給模型。
EN –
- Developer supplies JSON-Schema definitions of callable functions.
- User sends a request in natural language.
- LLM decides whether, and how, to call a function.
- Caller / Tool Runtime executes the function and returns results to the model.
2. 全流程時序 | End-to-End Sequence
# | 步驟 (ZH) | Step (EN) |
---|---|---|
1 | 注冊函數:開發者在 functions 字段傳入 JSON-Schema,示例:{"name":"weather","parameters":{"type":"object","properties":{"location":{"type":"string"}}}} | Register functions via the functions array in the API call, giving JSON-Schema for each. |
2 | 輸入消息:messages=[{"role":"user","content":"今天天氣如何?"}] | User message is sent in messages . |
3 | 模型推理:LLM 讀取系統+用戶信息,若判斷需要函數→輸出 role:"assistant", "name":"weather", "arguments":{...} | Model reasoning: If it decides a function is needed, it emits a tool call with role:"assistant" and name , arguments . |
4 | 執行器調用:客戶端檢測到 name 字段→調用本地或遠程函數→得到返回值,如 {"temp":25} | Caller executes detected function, obtains result JSON. |
5 | 結果回注:把結果作為 role:"function", "name":"weather", "content":"{\"temp\":25}" 再塞進 messages | Inject result back as a function role message so the model can see it. |
6 | 模型二次生成:LLM 看到函數輸出后,再生成最終自然語言回答。 | Second pass: model crafts the final user-visible response, informed by result. |
從開發者視角看,就是 “定義 → 監聽 → 調用 → 回注” 四件事。
From the dev perspective: define → watch → call → inject.
3. 關鍵細節 | Key Implementation Notes
-
JSON-Schema 精度
- 字段類型、必選/可選決定模型填參質量。盡量用
enum
,minimum
,pattern
等約束減少幻覺。 - Use rich JSON-Schema constraints (enum, minimum, pattern) to steer the model toward valid args.
- 字段類型、必選/可選決定模型填參質量。盡量用
-
多輪調用
- 模型可串聯多次函數:例如先
search_flights
再book_flight
。保持每輪都把結果作為function
role 回注即可。 - Chained calls work: keep injecting each result back as a
function
message.
- 模型可串聯多次函數:例如先
-
流式 (Streaming)
- 在 OpenAI 流接口(
stream=true
)里,tool_calls
δ塊先到,客戶端可即時觸發執行。 - With streaming, tool-call deltas arrive early, enabling near-real-time actions.
- 在 OpenAI 流接口(
-
錯誤處理
- 若執行失敗,把錯誤描述同樣作為
function
消息交給模型,讓它決定重試/解釋。 - Return errors as
function
role messages so the model can handle retries or apologies.
- 若執行失敗,把錯誤描述同樣作為
-
安全與權限
- 在執行器側校驗參數,避免模型注入惡意 shell 字符串。
- Validate args server-side; the JSON schema itself is not a security boundary.
4. 最小可用示例(偽代碼) | Minimal Example (Pseudo-Python)
# 1. define schema
functions = [{"name": "weather","description": "Get current weather","parameters": {"type": "object","properties": {"location": {"type": "string"}},"required": ["location"]}
}]# 2. first API call
messages = [{"role":"user","content":"幫我查一下北京天氣"}]
resp = openai.ChatCompletion.create(model="gpt-4o",messages=messages,functions=functions)# 3. if resp.choices[0].finish_reason == "tool_call":
tool_call = resp.choices[0].message
args = json.loads(tool_call["arguments"])
result = get_weather(args["location"])# 4. feed back
messages += [tool_call,{"role":"function","name":"weather","content":json.dumps(result)}
]
final = openai.ChatCompletion.create(model="gpt-4o",messages=messages)
print(final.choices[0].message["content"])
5. 常見坑 / FAQ
問題 | 處理建議 |
---|---|
模型拒絕填參數 | 檢查 system prompt 是否允許工具;確保 schema 名稱易懂;給示例調用。 |
參數格式錯位 | 使用 json.loads() 校驗;在 schema 里加 format , pattern 。 |
連續調用失序 | 每輪都把 完整歷史+最新函數結果發回;保持 deterministic。 |
TL;DR
- Function Calling = LLM decides + runtime executes + LLM finishes。
- 只需掌握 JSON-Schema 定義、工具消息注入、循環兩輪,即可把“智能體”接入任意后端邏輯。
Master the pattern once and you can wire your Llama/GPT/Claude agent to databases, SaaS APIs, or even a coffee machine.