作者:donx
GPTs全景解析 GPTs 是什么
GPTs 是 AI target=_blank class=infotextkey>OpenAI 在2023年11月發布的新版本,具有可定制性和完成特定任務的強大功能。它提供了一種新的方式來使用ChatGPT,可以讓用戶根據自己的需求定制化,并與其他用戶共享。
以下是OpenAI 對它的能力介紹。
You can now create custom versions of ChatGPT that combine instructions, extra knowledge, and any combination of skills. (現在您可以創建定制版的ChatGPT,將指令、額外知識和任意技能組合起來。)
GPTs 提供了一種更智能、更個性化的體驗,無需每次都進行教育,使用戶能夠更快地獲得答案。它可以通過組合指令、額外知識和任意技能,來適應各種場景。用戶可以通過OpenAI的平臺創建自己的GPT,并與其他用戶共享。
但是 GPTs 提供的方式是讓所有人都可以得到定制版的ChatGPT,用戶可以根據自己的生活,工作,學習等不同的場景,制定適合自己的ChatGPT,并且可以和其他人進行共享。
任何人都可以通過OpenAI的平臺搭建自己的GPTs,用戶不需要懂得編程或者技術,只要擁有自己的idea,就可以創建屬于自己的GPTs。
創建GPT的過程簡單且直觀。用戶可以通過對話形式,為GPT提供指令和額外的知識庫,然后選擇所需的能力,例如聯網、繪圖、分析數據等。這可以在OpenAI的搭建平臺上進行嘗試。
例如,OpenAI 提供了如下一些GPTs,例如
- 數據分析GPTs: 支持上傳文件,并且執行代碼進行數據分析
- Game Time GPTs:支持對桌游或者卡牌游戲進行解釋等

OpenAI 提供了 GPTs 商店(暫時還沒有第三方的GPTs)方便用戶進行 GPTs 的分享和使用。GPTs 的引入方便了用戶可以更大限度地使用OpenAI ChatGPT 的能力。
- 可以快速地根據自己的需求定制 ChatGPT
- OpenAI 相信最好的GPTs,肯定是由社區創建的,所以它選擇成為一個平臺,只有最終的基礎的插件或者功能它會開發,其他的能力均由開發者研發。
- 開發者可以將將GPT和內部數據庫等進行連接,從而獲取數據
- 企業版用戶可以創建內部的GPTs
登陸 OpenAI 網站,選擇 Explore,然后再 My GPTs 中選擇 create a GPTs.

有兩種方式可以進行GPTs 的創建:
- 通過對話的方式進行,選擇 Create
- 通過配置的方式進行,選擇 Configure
只需要將需要的配置進行設置,就能得到一個想到的GPTs的能力。
例如下面設置的一個游戲GPTs,我們通過配置,使得GPT可以進行數據分析,并且可以使用
- Web Browsing:網頁瀏覽能力
- Code Interpreter:代碼編寫以及執行能力
下圖是這個數據分析助手的一個demo情況,用戶可以在兩三分鐘內快速實現一個AI助手。

GPTs 的問題與漏洞
- GPTs 安全性存在一定的問題,網上有針對GPTs提示詞泄露攻擊,并且可以得到結果。具體可以查看 OpenAI 的 GPTs 提示詞泄露攻擊與防護實戰
- GPTs 暫無私有化部署,并且在微軟 Azure API 中不支持
- AI 的數據安全問題是無法保證的,目前有傳言認為 Sam 的出走是因為在產品商業化和AI安全性的選擇導致的(參考)。
Assistants API 允許用戶在自己的應用中通過API實現類似 GPTs 的 AI 助理,目前支持的能力和GPTs一樣(截止2023年11月12日),允許接入三種不同類型的 tools:
- 代碼解釋器(Code Interpreter)
- 知識庫集成(Retrieval)
- 函數調用(Function calling)
通過構建 AI 助手,用戶可以通過指令(instructions)設置助手的角色和能力。然后,AI 助手將利用其強大的大語言模型能力、各種工具(tools)和知識庫來回答用戶的問題。
Assistants API實踐案例
用戶可以通過Assistant playground 進行Assistants API 的探索,參考以下教程使用 API 進行 AI Assistant 集成。
通常進行 Assistants API 集成需要一下四個步驟:

- 首先創建一個AI助手 (Assistant)。
- 通過自定義指令(custom instructions)進行 AI 助手能力定義,實現 AI 助手的形象和能力定位。
- 選擇基礎模型,可以選擇 GPT-3.5、GPT-4 等作為基礎模型。
- 選擇擴展能力 tools 例如 code interpreter, retrieval 以及其他的 function call 工具。
- 創建一個對話(Thread) 進行一個交流。
- 在對話中傳入消息(Messages),進行提問。
- 在對話中進行執行(Run),AI Assistant 會自動運行相關的tools。
下面的例子會一步一步進行AI Assistant的構建。
步驟 1: 創建一個AI助手
一個 AI assistant 可以通過下面的幾個參數進行配置:
- 指令(Instructions): 針對AI助手和模型,定制他們的表現和響應行為。
- 模型(Model): 提供了各種供選擇的 GPT-3.5 或者 GPT-4 模型,包括自己進行精細調校的模型。如果希望使用信息檢索工具(Retrieval tool),則需要采用 gpt-3.5-turbo-1106或者 gpt-4-1106-preview模型。
- 工具(Tools): Assistant API 支持使用OpenAI自行開發的 Code Interpreter 編碼解釋器以及 Retrieval 召回工具。
- 函數(Functions): API 支持用戶使用自定義的函數作為額外工具使用,類似 Open AI 的 function calling 特性。
在這個例子中,我們會創建一個自己的數學導師,使用到 Code Interpreter 能力:
# Upgrade to Python/ target=_blank class=infotextkey>Python SDK v1.2 with pip install --upgrade openai assistant = client.beta.assistants.create( name="Math Tutor", # 助手的名字 instructions="You are a personal math tutor. Write and run code to answer math questions.", #助手能力 tools=[{"type": "code_interpreter"}], #助手的工具 model="gpt-4-1106-preview" #模型選擇 ) 步驟 2: 創建一個對話 Thread
一個 Thread 就代表了一個對話。OpenAI 建議每個用戶在開始對話的時候都創建一個 Thread,把所有用戶相關的內容和文件都通過在 Thread 創建Message完成。
可以將 Thread 理解為與 AI 助手創建的一個對話窗口,所有的對話行為都在這個Thread 中進行。
thread = client.beta.threads.create
Threads 本身并無大小限制,因此你可以在單個 Thread 對話中發送任意數量的消息(Messages)。API 會自動對請求的消息進行適當的處理,以確保請求滿足模型的最大窗口長度限制,如通過截斷等方式進行調整。
步驟3: 在對話(Thread) 中傳入 消息(Message)
一個消息可以包含用戶的文本輸入,還有可能包含用戶上傳的文件。盡管目前還不支持圖片,但OpenAI將在不久的將來添加這一功能。
message = client.beta.threads.messages.create( thread_id=thread.id, #需要傳入的Thread ID role="user", content="I need to solve the equation `3x + 11 = 14`. Can you help me?" )
如果現在你展示在對話Thread 中的所有消息,你會看到這條消息被加入到了對話中:
{ "object": "list", "data": [ { "created_at": 1696995451, "id": "msg_4rb1Skx3XgQZEe4PHVRFQhr0", "object": "thread.message", "thread_id": "thread_34p0sfdas0823smfv", "role": "user", "content": [{ "type": "text", "text": { "value": "I need to solve the equation `3x + 11 = 14`. Can you help me?", "annotations": [] } }], ... 步驟 4: 執行AI助手
為了得到AI 助手的結果,你需要創建一個 Run對象,這使得AI 助手可以獲取對話的消息,并決定是使用工具(tools)回答用戶的問題,還是僅僅依賴模型自身的能力進行問題解答。
當 AI 得到答案,會在對話(Thread)的消息列表中加入角色(*role="assistant"*)的一個回復。
run = client.beta.threads.runs.create( thread_id=thread.id, assistant_id=assistant.id, instructions="Please address the user as Jane Doe. The user has a premium account." ) 步驟5: 展示AI 助手的回復
當我們需要獲取AI回復的時候,可以對 Run對象進行不斷的查詢,獲取當前執行的狀態。
run = client.beta.threads.runs.retrieve( thread_id=thread.id, run_id=run.id )
當狀態碼 == completed時,代表AI已經完成回復,并且可以在Thread 中看到AI的回答。
messages = client.beta.threads.messages.list( thread_id=thread.id )
最后我們就可以把內容展示給用戶,下面是一個例子。AI給出了兩個回答(role== assistant)

可以通過運行步驟 Run Steps,獲取執行的中間狀態,從而提供給用戶中間結果以及使用的tools等信息。
步驟*: Playground 今天調試和測試
開發者可以在 Playground 中進行調試和測試,具體如下,其具體的能力和GPTs比較相似,只是可以看到更多的debug信息。也是可視化的具體界面。

Assistants API工作機制剖析
Assistant API 的目標是幫助開發者更高效地開發出功能強大的AI助手,這些助手可以有效地利用OpenAI提供的多項能力以及用戶自身構建的工具。
- AI 助手可以調用 OpenAI 的模型,并通過特定的指令來定義助手的行為特性和能力。
- AI 助手可以同時調用多個工具tools,這些工具可以是 OpenAI 自己開發的工具,例如 like Code interpreter 和 Knowledge retrieval 也可以是用戶自己通過 Function calling自己實現的工具。這樣,AI助手就能拓寬其解決問題的能力范圍。
- AI 助手可以訪問持久化的對話,新引入的對話Thread功能簡化了AI應用的對話管理工作。用戶只需要創建一次對話(Thread),就可以在后續快速地訪問并與其進行對話,并輕松獲取答案,這樣就無需再關心模型對對話窗口的限制。
- AI 助手可以訪問多種類型的文件。 AI助手可以在初始化創建時訪問文件,或是在對話初始化的時候獲取文件。它也可以在使用工具時創建新的文件,然后在之后的調用中引用這些文件。

從我們上述的講解內容中,我們可以很清楚,AI助手API的調用主要由 Assistant、Thread、Message、Run 和 Run Step 這五個對象組成
對象(OBJECT)含義助手對象(Assistant)調用 OpenAI 模型的任務型 AI,該AI 具備訪問 tools 的能力對話(Thread)用戶和AI之間的對話。Thread 對話存儲消息,并且自動處理文本長度超出限制的問題消息(Message)消息由用戶或者AI產生,可以包含文本,圖片(暫時不支持),或者文件。消息在一個Thread對話中以有序列表形式存儲執行(Run)通過AI助手對某個對話進行顯式執行。AI助手根據自身的配置信息和Thread中的消息內容,調用不同的工具(tools),從而得出回復。執行得到的結果會被存儲在Thread的消息中,作為AI的回復執行步驟(Run Step)執行(Run)的中間過程詳細記錄。包括AI使用了哪些tool,或者產生了哪些消息。這個對象可以幫助開發者理解AI如何得出最終的結果
創建一個AI Assistant 對象
創建一個AI 助手對象非常簡單,只需要指定使用的語言 model,然后通過instruction 指令規定AI 助手的性格以及能力(或者是目標)。
- name: AI 助手的名字
- instructions: 該參數指定了AI的性格以及目標或者能力,這個很重要,會影響AI助手的輸出可靠性。
- tools:list,可以傳入最多128個tools,可以使用 OpenAI 自己的 Code Interpreter 和 retrieval 工具,或者是自己構建的第三方 functioncalling.
- file_ids: list,文件的ID,這里傳入的文件ID 可以將文件傳給Code Interpreter 和 retrieval使用。文件需要通過File的上傳接口 進行上傳,并且需要將接口的purpose設置成 assistants. 一個AI 助手可以使用最多20個文件。每個文件最多512M。
文件上傳:
file = client.files.create( file=open("speech.py", "rb"), purpose='assistants' )
AI助手創建:
assistant = client.beta.assistants.create( name="Data visualizer", instructions="You are great at creating beautiful data visualizations. You analyze data present in .csv files, understand trends, and come up with data visualizations relevant to those trends. You also share a brief text summary of the trends observed.", model="gpt-4-1106-preview", tools=[{"type": "code_interpreter"}], file_ids=[file.id] ) 管理對話和消息
對話(Thread)和消息(Messages)代表了AI 助手和用戶的聊天。一個對話中消息的個數是沒有限制的,一旦消息的內容超過了模型可以處理的最長的窗口長度,Thread會自動舍棄最舊的消息,包含盡可能多的消息內容。(注意,該策略OpenAI可能會更新)
Thread 和 Messages 的創建如下:
thread = client.beta.threads.create( messages=[ { "role": "user", "content": "Create 3 data visualizations based on the trends in this file.", "file_ids": [file.id] } ] )
messages 可以有如下兩種角色(role):
- user: 用戶消息
- assistant: AI 助手的回復 messages消息可以包含文本,圖片,以及文件。但是目前的API暫時不支持圖片消息,相信很快就能支持
消息注解Message annotationsAI 助手返回的消息可能會包含 Message annotations,存儲在content 的對象中。注解(Annotations)提供了如何解析消息的信息;
目前支持兩種不同的注解:
- file_citation: 該注解是 retrieval工具提供的,它定了了參考的內容的來源。
- file_path:該注解是 code_interpreter工具提供,指定了參考文件的地址目錄。
當返回的內容有注解的時候,我們需要進行解析,將其轉化成用戶可以理解的文本,例如下面的代碼可以將參考文本以及下載鏈接進行解析,方便用戶理解回復。
# Retrieve the message object import openai as client message = client.beta.threads.messages.retrieve( thread_id="...", message_id="..." ) # Extract the message content message_content = message.content[0].text annotations = message_content.annotations citations = [] # Iterate over the annotations and add footnotes for index, annotation in enumerate(annotations): # Replace the text with a footnote message_content.value = message_content.value.replace(annotation.text, f' [{index}]') # Gather citations based on annotation attributes if (file_citation := getattr(annotation, 'file_citation', None)): cited_file = client.files.retrieve(file_citation.file_id) citations.Append(f'[{index}] {file_citation.quote} from {cited_file.filename}') elif (file_path := getattr(annotation, 'file_path', None)): cited_file = client.files.retrieve(file_path.file_id) citations.append(f'[{index}] Click to download {cited_file.filename}') # Note: File download functionality not implemented above for brevity # Add footnotes to the end of the message before displaying to user message_content.value += 'n' + 'n'.join(citations) 執行(Run)和執行步驟(Run Steps)
當我們需要AI Assistant 對用戶問題進行回復,,需要創建一個Run對象,該對象包含了兩個參數:
- thread_id: 之前創建的Thread的id
- assistant_id: 該AI Assistant 的id
通常情況下,我們在創建 Assistant 對象的時候,已經指定了model和tools,但是我們仍可以在創建執行對象(Run)的時候,進行重新指定。
run = client.beta.threads.runs.create( thread_id=thread.id, assistant_id=assistant.id, model="gpt-4-1106-preview", instructions="additional instructions", tools=[{"type": "code_interpreter"}, {"type": "retrieval"}] )
注意:file_ids不可以在執行中進行修改,需要使用修改Assistant的API進行修改
執行的生命周期(Run lifecycle)
Run對象有不同的狀態


獲取進度 Polling for updates
為了可以及時獲取執行的進度,可以設置定時獲取 retrieve the Run 執行狀態。你可以獲取每次 Run 的執行狀態,從而決定下一步該做什么。 目前還不支持 streaming 的輸出(2023-11-12日)
對話鎖 Thread locks當執行對象 Run處于進行中 in_progress的狀態的時候,對話Thread 對象會被鎖上,這意味著:
- 新消息不能加到對話中
- 新的執行Run 不能被創建
執行步驟 Run steps
當執行進入 in_progress后,會有下面四種可能的狀態,分別是
- 完成
- 失敗
- 取消
- 超時

執行步驟Run steps可能耗時比較長,為了能了解執行的細節,我們可以通過 step_details這個字段進行觀察,包含了兩種類型的內容:
- message_creation: 展示了產生了什么消息
- tool_calls: 展示了使用了什么tool
目前是beta 版本,將會持續解決后續這些如下問題
- 支持流式輸出
- 支持通知的功能,可以在無需輪詢的情況下共享對象狀態更新
- 支持 DALL·E 作為工具
- 支持用戶上傳圖片
Code Interpreter(代碼解釋器) 允許 Assistant API 去創建并且執行代碼。這個代碼解釋器能力,支持多種文件處理,以及代碼執行。
代碼解釋器能夠通過代碼運行,完成多種困難的任務,并且能解決很多GPT地薄弱能力,例如數學能力等。Code Interpreter 支持如果發現自己的代碼執行失敗了,會通過多輪重試,直到執行成功。
開啟Code Interpreter
如果需要開啟 Code Interpreter 能力,只需要在tools參數中加入 Code Interpreter, 如 tools=[{"type": "code_interpreter"}]即可。
import openai as client assistant = client.beta.assistants.create( instructions="You are a personal math tutor. When asked a math question, write and run code to answer the question.", model="gpt-4-1106-preview", tools=[{"type": "code_interpreter"}] )
模型之后會選擇是否使用 Code Interpreter 去運行用戶的請求。
在 Code Interpreter 中傳入文件
Code Interpreter 可以解析多種不同類型的文件,所以當你需要處理大量的數據時,AI Assistant 允許你傳入自己的文件進行分析。
注意:上傳的文件需要設置 purpose='assistants'
# Upload a file with an "assistants" purpose import openai as client file = client.files.create( file=open("speech.py", "rb"), purpose='assistants' ) # Create an assistant using the file ID assistant = client.beta.assistants.create( instructions="You are a personal math tutor. When asked a math question, write and run code to answer the question.", model="gpt-4-1106-preview", tools=[{"type": "code_interpreter"}], file_ids=[file.id] )
如果需要指定 對話級別的文件訪問(即改文件只在這個對話中可以被訪問),則可以使用如下的代碼:
thread = client.beta.threads.create( messages=[ { "role": "user", "content": "I need to solve the equation `3x + 11 = 14`. Can you help me?", "file_ids": [file.id] } ] )
文件最大可以支持512 MB,z支持的格式包含 .csv, .pdf, .json 和其他格式
知識庫獲取 Knowledge Retrieval
知識庫獲取是克服 ChatGPT 知識儲備時效性問題,以及數據私有化的有效手段,例如利用知識庫獲取能力,可以把業務數據知識庫集成到GPT中。
開發者可以將文件(知識庫)上傳到AI 助手中,Open AI 會自動化對文檔進行分塊,加索引(index)以及embedding存儲和實現向量化檢索。
所以不需要用戶自己進行這一系列操作就可以完成知識庫檢索的能力。
開啟知識庫檢索
Assistant 如果需要開啟知識庫增強,只需要在初始化中的 tools加入 tools=[{"type": "retrieval"}]參數。
assistant = client.beta.assistants.create( instructions="You are a customer support chatbot. Use your knowledge base to best respond to customer queries.", model="gpt-4-1106-preview", tools=[{"type": "retrieval"}] ) 工作原理
模型會自動地根據你的輸入進行內容的選擇,主要的召回邏輯如下:
- 短文檔直接傳入GPT
- 對于長文檔進行向量化召回
跟 ChatGPT 的 Completion API 一樣,Assistant API 也支持 function calling。 Function Calling 允許你將函數的描述告訴AI 助手,包含了函數的定義以及參數等,然后 AI 助手會智能調用。
但是 Assistant API 不會直接調用函數,而是將函數的參數和函數返回,等待你提交函數調用結果,才會進行下一步的執行。
定義函數
首先需要按照如下的樣例遞交函數定義
{ "type": "function", # 類型一定是function "function": { "name": "getCurrentWeather", # 函數名 "deion": "Get the weather in location", #函數的描述 "parameters": { # 函數的參數 "type": "object", "properties": { "location": {"type": "string", "deion": "The city and state e.g. San Francisco, CA"}, "unit": {"type": "string", "enum": ["c", "f"]} }, "required": ["location"] } } }
然后將函數的參入 Assistant API的tools 參數中。例如下面的例子,定義了一個天氣機器人,可以獲取天氣信息。 包含了兩個函數:
- getCurrentWeather:獲取城市的天氣
- getNickname: 獲取城市別名
當 初始化一個執行(Run) 的時候,如果調用了一個function,則會進入到 pending的狀態。需要你進行提交函數的結果。
模型支持并發調用,參考 parallel function calling
如下的返回結果,可以看到 required_action是需要提交的函數調用的函數名和參數。這里面可以 獲取 call id , 用于提交使用函數結果使用。
{ "id": "run_3HV7rrQsagiqZmYynKwEdcxS", "object": "thread.run", "assistant_id": "asst_rEEOF3OGMan2ChvEALwTQakP", "thread_id": "thread_dXgWKGf8Cb7md8p0wKiMDGKc", "status": "requires_action", "required_action": { "type": "submit_tool_outputs", "submit_tool_outputs": { "tool_calls": [ { "id": "call_Vt5AqcWr8QsRTNGv4cDIpsmA", # 返回的call id,用于提交使用 "type": "function", "function": { "name": "getCurrentWeather", "arguments": "{"location":"San Francisco"}" } }, { "id": "call_45y0df8230430n34f8saa", "type": "function", "function": { "name": "getNickname", "arguments": "{"location":"Los Angeles"}" } } ] } }, ... 提交函數結果
需要對于每個函數都進行 提交函數輸出 ,對于每個輸出的結果需要提交給哪個函數,則是對應了函數調用返回的 required_action中的 tool_call_id。
具體的代碼如下。
run = client.beta.threads.runs.submit_tool_outputs( thread_id=thread.id, # 對話id run_id=run.id, # 執行id tool_outputs=[ { "tool_call_id": call_ids[0], # call id "output": "22C", }, { "tool_call_id": call_ids[1], "output": "LA", }, ] ) LangChain 集成 Assistant API
截止2023-11-15日,LangChain 集成API 還只是一個實驗版本 langchain-experimental,未有正式版本。所以需要使用的讀者,可以使用如下版本:
!pip install -U -q "langchain==0.0.331rc2" langchain-experimental "openai>=1.1" import os os.environ["OPENAI_API_KEY"] = 'YOUR OPENAI KEY' # !pip install -U -q "langchain==0.0.331rc2" langchain-experimental "openai>=1.1" from langchain_experimental.openai_assistant import OpenAIAssistantRunnable import openai as client file = client.files.create( file=open("TEST.csv", "rb"), purpose='assistants' ) interpreter_assistant = OpenAIAssistantRunnable.create_assistant( name="data analysis assistant", instructions="You are a profession data analysis. When asked a question, write and run Python code to answer the question.", tools=[{"type": "code_interpreter"}], file_ids=[file.id], model="gpt-4" ) output = interpreter_assistant.invoke( {"content": "最近2周活躍表現最突出的是哪一天?", "file_ids": [file.id] }) output

其他更多的內容可以參考:langchain cookbook
使用curl調用 Assistant API
具體可以參考如下的 Jupyter Notebook
Capabilities 和 Actions
我們在創建 GPTs 的時候,可以給GPTs 提供多種不同的能力
- Knowledge:知識庫
- Capabilities(內置能力):包含了 OpenAI 提供的基礎能力,主要包含了,這些能力都是最重要最基礎的,所以OpenAI選擇自己做。
- Web Browsing(網絡瀏覽能力)
- DALLE Image Generation(圖片生成能力)
- Code Interpreter(代碼能力)
- Actions:動作,指的是GPTs的其他能力,類似于額外的能力插件,OpenAI不可能幫用戶把所有的業務需求的能力都提供了額,所以它提供了一個接口,方便用戶可以使用規定的接口協議,給GPT提供額外的能力。目前Actions 采用的是OpenAPI的接口協議,方便GPT調用外部的API。具體的使用可以參考下面教程。
雖然 GPTs 和 Assistant API 都是為了創建自定義的 AI 助手創建的,到那時兩者的方法和使用的場景不同。reference
GPTs 有著簡單易用的前端交互,可以很快速地方便小白用戶快速搭建 AI 助手,可以快速地驗證方案和效果,并且可以很快速的在 GPTs 的商店中進行分享。
然而, Assistant API 需要通過API的方式進行操作,雖然可以使用 Assistant API 的 Assistant playground 進行配置使用,但是其主要的目的還是為開發者提供一個API 方式,方便開發者可以在在自己的應用中,快速集成這些能力。
參考資料
- YouTube:OpenAI Assistants API 極簡入門(附LangChain集成)
- OpenAI Assistants API with LangChain
- langchain cookbook
- Assistant playground
- introducing GPTs
- OpenAI Assistants API
- Difference of GPT’s and Assistants
- OpenAI Announces GPTs & Assistants. What is the difference?






