How Assistants work

Assistants (助理) 如何運作

Assistants API 旨在幫助開發人員構建能夠執行多種任務的強大 AI 助理.

  1. Assistants 可以用特定指令調用 OpenAI 的模型, 以調整它們的個性和能力.

  2. Assistants 可以並行(parallel)訪問多個工具. 這些可以是 OpenAI 托管的工具 - 如 Code interpreterKnowledge retrieval - 或者是您構建/托管的工具(通過 Function calling).

  3. Assistants 可以訪問持久的 Threads. Threads 通過儲存消息歷史和在對話對於模型的上下文長度變得太長時進行截斷, 簡化了 AI 應用開發。您創建一個 Thread, 然後隨著使用者回覆簡單地追加消息至其中.

  4. Assistants 可以訪問幾種格式的檔案(Supported file) - 無論是作為它們創建時的一部分, 還是作為 Assistant 與使用者之間的 Threads 的一部分. 當使用工具時, Assistants 還可以建立檔案(例如,圖片、試算表等)並在它們建立的 Messages 中引用它們參考的檔案。

Objects

Use personal finance bot for example

OBJECT WHAT IT REPRESENTS
Assistant 使用 OpenAI 模型並調用工具的特定目的 AI
Thread Assistant 和使用者之間的對話會話. Threads 儲存消息並自動處理截斷,以適應模型的上下文容量
Message 由 Assistant 或使用者建立的訊息. Message 可以包括文字文本, 圖片和其他檔案. 或使用者建立的消息. Message 作為一個 list 儲存在 Thread
Run Thread 上呼叫 Assistant. Assistant 使用它的配置和 Thread 上的 Messages 執行工作, 通過調用模型和工具. 作為 Run 的一部分, Assistant 將 Message 追加到 Thread
Run Step Assistant 作為 Run 的一部分, 所採取的詳細步驟清單. Assistant 可以在運行中調用工具或創建 Messages. 檢查 Run Steps 可以讓您監看 Assistant 如何得出最終結果

創建 Assistants

建議使用最新的 model

要開始創建一個 Assistant 僅需指定要使用的 model. 但您可以進一步自定義 Assistant 的行為:


例如, 要創建一個能夠基於 .csv 檔案創建資料視覺化的 Assistant, 首先上傳一個檔案.

const file = await openai.files.create({
  file: fs.createReadStream("mydata.csv"),
  purpose: "assistants",
});

然後用上傳的檔案創建 Assistant.

const assistant = await openai.beta.assistants.create({
  name: "Data visualizer",
  description: "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]
});

您可以為每個 Assistant 附加最多 20 個檔案, 每個檔案最大可為 512 MB. 此外, 您組織上傳的所有檔案的大小不應超過 100GB. 您可以通過我們的幫助中心申請增加這個存儲限制.

您還可以使用 AssistantFile 物件來創建、刪除或查看 Assistant 和 File 物件之間的關聯. 請注意, 刪除 AssistantFile 不會刪除原始檔案物件, 它僅僅刪除該檔案與 Assistant 之間的關聯. 要刪除一個檔案, 請改用檔案刪除端點.

管理 Threads 與 Messages

ThreadsMessages 代表了 Assistant 和使用者之間的一次對話會期(session). 您可以在一個 Thread 中儲存無限數量的 Messages. 一旦訊息的大小超過模型的上下文窗口大小, Thread將會聰明地截斷它們以符合. 您可以創建一個包含初始 Message 列表的 Thread, 如下所示:

const thread = await openai.beta.threads.create({
  messages: [
    {
      "role": "user",
      "content": "Create 3 data visualizations based on the trends in this file.",
      "file_ids": [file.id]
    }
  ]
});

Message 可以包含文本, 圖像或檔案. 目前,使用者建立的訊息不能包含圖像檔案, 但計劃在未來增加對此的支持.

Message 的註解

由 Assistant 創建的 Message 可能在 content 陣列中包含註解(annotations). annotation 提供如何註解 Message 中文字的訊息.

有兩種類型的 Annotations:

Message 物件中存在 annotations 時, 您會在文字文本中看到應該用 annotation 替換的難以辨識的模型生成子串. 這些字串可能看起來像 【13†source】sandbox:/mnt/data/file.csv. 以下是一個 Python 代碼片段示例, 它用註解中的信息替換這些字串.

# 檢索訊息物件
# Retrieve the message object
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 <here> 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)

Runs 與 Run Steps

當您從使用者在 Thread 中獲得所有需要的上下文後, 您可以選擇一個 Assistant 來運行這個 Thread.

const run = await openai.beta.threads.runs.create(
  thread.id,
  { assistant_id: assistant.id }
);

預設情況下, 一次運行會使用在 Assistant 物件中指定的模型(model)和工具(tools)配置, 但您可以在 建立 Run 時覆蓋大部分這些設置, 以增加靈活性.

const run = await openai.beta.threads.runs.create(
  thread.id,
  {
    assistant_id: assistant.id,
    model: "gpt-4-1106-preview",
    instructions: "additional instructions",
    tools: [{"type": "code_interpreter"}, {"type": "retrieval"}]
  }
);

注意: 與 Assistant 相關聯的 file_ids 在創建 Run 期間不能被覆蓋. 您必須使用 modify Assistant 端點來執行此操作.

Run 的生命週期

Run 物件可以有多個狀態.

Run objects can have multiple statuses

STATUS 定義
queued Runs 首次建立或當你完成了 required_action, 它們會被移至 queued 狀態. 它們應該會幾乎立刻移動到 in_progress.
in_progress in_progress 時, Assistant 會使用模型(model)和工具(tools)執行步驟. 您可以通過檢查 Run Steps 來查看 Run 執行進度.
completed Run 成功完成! 您現在可以查看 Assistant 增加到 Thread 中的所有 Messages, 以及 Run 採取的所有步驟. 您也可以通過向 Thread 中添加更多使用者 Messages 並創建另一次 Run 來繼續此 Thread.
requires_action 當使用 Function calling 工具時, Run 會在模型確定要調用的函數的名稱和參數後, 移至 required_action 狀態. 然後, 您必須運行這些函數並提交輸出, 之後 Run 才能繼續. 如果在過期時間戳(建立後大約10分鐘)之前沒有提供輸出, Run 將移至expired(過期)狀態.
expired 這發生在函數調用輸出未在 expires_at 標記的時間之前提交造成 Run 過期的情況. 此外, 如果 Run 執行時間過長, 超出expires_at 所標記的時間, 我們的系統將使 Run 過期
cancelling 您可以嘗試使用 Cancel Run 端點來取消 in_progress '狀態中的 Run. 一旦嘗試取消成功, 運行的狀態將移至 cancelled. 此取消操作是嘗試執行而不保證成功.
cancelled Run 成功被取消.
failed 您可以通過查看運行中的 last_error 物件來查看失敗的原因. 失敗的時間將記錄在 failed_at.

輪詢更新

為了保持 Run 狀態的更新, 您必須 定期檢索 Run 物件. 每次檢索物件時, 您都可以檢查 Run 的狀態, 以確定您的應用應該接下來做什麼. 我們計劃在不久的將來支援 streaming, 以使這個過程更簡單.

Thread 鎖定

Run 處於 in_progress 狀態且不處於終端時, Thread 將被鎖定. 這表示:

Run steps

Run steps statuses

Run steps 的狀態與 Run 狀態具有相同的含義.

Run steps 物件中, 大部分有趣的細節都存在於 step_details. 有兩種類型的步驟細節:

資料訪問指引

目前, 透過 API 創建的 Assistants, Threads, Messages 和檔案的範圍是整個組織. 因此, 任何擁有組織 API 金鑰訪問權限的人都能夠在組織中讀取或寫入 Assistants, Threads, Messages 和檔案.

我們強烈建議實施以下資料訪問控制:

限制

在這個測試版期間, 我們知道有幾個已知的限制, 我們正尋求在未來幾週和幾個月內解決. 當我們增加對額外功能的支持時, 我們將在這個頁面上發布更新日誌.