目錄
什么是Function Calling
示例 1:調用本地函數
Function Calling 的注意事項
支持 Function Calling 的國產大模型
百度文心大模型
MiniMax
ChatGLM3-6B
訊飛星火 3.0
通義千問
幾條經驗總結
什么是Function Calling
? ? ?Function Calling 是一種函數調用機制,在使用 大模型進行prompt 提問時,大模型現有的知識庫不一定有能力立即回答你的問題,但我們在提問時可以告訴大模型,我們有幾個函數,讓它結合我們的提問告訴程序,應該去調用哪個函數,并從給的提問中解析出參數。程序會根據大模型返回的函數和入參生成一個結果。然后程序將 最初的提問和函數調用結果一并發給 大模型進行 prompt ,這個時候,大模型就能回答出我們的問題了。
? ? ?舉例:
? ? ? 1. 我們調用API向大模型提問:推薦北京五道口附近的咖啡店。同時告訴大模型,我們定義了一個函數,這個函數需要參數是:地名、關鍵詞
? ? ? 2. 大模型從我們的提問中解析出地名、關鍵詞和函數的對應關系返回。如:地點搜索函數,入參是 北京五道口,咖啡店。
? ? ? 3. 程序根據大模型返回的參數調用 高德API返回咖啡店的位置信息。、
? ? ? 4. 程序將咖啡店的位置信息和最初的提問一并告訴大模型。
? ? ? 5. 大模型基于程序給的信息就能回答出這個問題了。
Function Calling 完整的官方接口文檔:https://platform.openai.com/docs/guides/function-calling?
示例 1:調用本地函數
需求:實現一個回答問題的 AI。題目中如果有加法,必須能精確計算。
# 初始化
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
import json_ = load_dotenv(find_dotenv())client = OpenAI()def print_json(data):"""打印參數。如果參數是有結構的(如字典或列表),則以格式化的 JSON 形式打印;否則,直接打印該值。"""if hasattr(data, 'model_dump_json'):data = json.loads(data.model_dump_json())if (isinstance(data, (list))):for item in data:print_json(item)elif (isinstance(data, (dict))):print(json.dumps(data,indent=4,ensure_ascii=False))else:print(data)def get_completion(messages, model="gpt-3.5-turbo"):response = client.chat.completions.create(model=model,messages=messages,temperature=0.7,tools=[{ # 用 JSON 描述函數。可以定義多個。由大模型決定調用誰。也可能都不調用"type": "function","function": {"name": "sum","description": "加法器,計算一組數的和","parameters": {"type": "object","properties": {"numbers": {"type": "array","items": {"type": "number"}}}}}}],)return response.choices[0].messagefrom math import *prompt = "Tell me the sum of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10."
# prompt = "桌上有 2 個蘋果,四個桃子和 3 本書,一共有幾個水果?"
# prompt = "1+2+3...+99+100"
# prompt = "1024 乘以 1024 是多少?" # Tools 里沒有定義乘法,會怎樣?
# prompt = "太陽從哪邊升起?" # 不需要算加法,會怎樣?messages = [{"role": "system", "content": "你是一個數學家"},{"role": "user", "content": prompt}
]
response = get_completion(messages)# 把大模型的回復加入到對話歷史中。必須有
messages.append(response)print("=====GPT 第一次回復=====")
print_json(response)# 如果返回的是函數調用結果,則打印出來
if (response.tool_calls is not None):# 是否要調用 sumtool_call = response.tool_calls[0]if (tool_call.function.name == "sum"):# 調用 sumargs = json.loads(tool_call.function.arguments)result = sum(args["numbers"])print("=====函數返回結果=====")print(result)# 把函數調用結果加入到對話歷史中messages.append({"tool_call_id": tool_call.id, # 用于標識函數調用的 ID"role": "tool","name": "sum","content": str(result) # 數值 result 必須轉成字符串})# 再次調用大模型print("=====最終 GPT 回復=====")print(get_completion(messages).content)
=====GPT回復===== {"content": null,"role": "assistant","function_call": null,"tool_calls": [{"id": "call_4Crnxkt4kj0bOspDxIiAJ6lD","function": {"arguments": "{\"numbers\":[1,2,3,4,5,6,7,8,9,10]}","name": "sum"},"type": "function"}] } =====函數返回===== 55 =====最終回復===== The sum of 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10 is 55.
劃重點:
- Function Calling 中的函數與參數的描述也是一種 Prompt
- 這種 Prompt 也需要調優,否則會影響函數的召回、參數的準確性,甚至讓 GPT 產生幻覺
Function Calling 的注意事項
劃重點:
- 只有?
gpt-3.5-turbo-1106
?和?gpt-4-1106-preview
?及更高版本的模型可用本次課介紹的方法 - 使用模型別名?
gpt-3.5-turbo
?和?gpt-4-turbo
?會調用最新模型,但要防范模型升級帶來的負面效果,做好充足測試 - 函數聲明是消耗 token 的。要在功能覆蓋、省錢、節約上下文窗口之間找到最佳平衡
- Function Calling 不僅可以調用讀函數,也能調用寫函數。但官方強烈建議,在寫之前,一定要有真人做確認
支持 Function Calling 的國產大模型
- 國產大模型基本都支持 Function Calling 了
- 不支持 FC 的大模型,某種程度上是不大可用的
百度文心大模型
官方文檔:文心千帆文檔首頁-百度智能云
百度文心 ERNIE-Bot 系列大模型都支持 Function Calling,參數大體和 OpenAI 一致,支持 examples。
MiniMax
官方文檔:MiniMax-與用戶共創智能
- 這是個公眾不大知道,但其實挺強的大模型,尤其角色扮演能力
- 如果你曾經在一個叫 Glow 的 app 流連忘返,那么你已經用過它了。現在叫「星野」
- 應該是最早支持 Function Calling 的國產大模型
- V2 版 Function Calling 的 API 和 OpenAI 完全一樣,但其它 API 有很大的特色
ChatGLM3-6B
官方文檔:ChatGLM3/tools_using_demo at main · THUDM/ChatGLM3 · GitHub
- 最著名的國產開源大模型,生態最好
- 早就使用?
tools
?而不是?function
?來做參數,其它和 OpenAI 1106 版之前完全一樣
訊飛星火 3.0
官方文檔:星火認知大模型Web API文檔 | 訊飛開放平臺文檔中心
和 OpenAI 1106 版之前完全一樣
通義千問
官方文檔:如何使用通義千問API_模型服務靈積(DashScope)-阿里云幫助中心
和 OpenAI 接口完全一樣。
幾條經驗總結
在傳統與 AI 之間徘徊:
- 詳細拆解業務 SOP,形成任務 flow。每個任務各個擊破,當前別幻想模型一攬子解決所有問題
- 不是所有任務都適合用大模型解決。傳統方案,包括傳統 AI 方案,可能更合適
- 一定要能評估大模型的準確率(所以要先有測試集,否則別問「能不能做」)
- 評估 bad case 的影響面
- 大模型永遠不是 100% 正確的,建立在這個假設基礎上推敲產品的可行性