みなさんOpenAIのAPIは使用したことがありますか??OpenAIのAPIって、いわば「一問一答」のAIですが,新しいAssistants APIは,まるで「常駐秘書」のように,あなたの仕事を長期的にサポートしてくれるスグレモノなんです!OpenAIのAssistants APIを使用すると、独自のアプリケーション内でAIアシスタントを構築することができます.
現在、Assistants APIでは、Code Interpreter、File Search、Function callingの3種類のツールがサポートされています.
OpenAI APIのドキュメント
シリーズ OpenAI AssistantsAPI チートシート
Part 2 Thread編
Part 3 Message編
Part 4 Run編
他のチートシート
git/gh コマンド(gitコマンド以外にもgitの概念も書いてあります)
lazygit
Docker コマンド(dockerコマンド以外にもdockerの概念の記事へのリンクもあります)
ステータスコード
TypeScript
Go/Gorm
SQL
Vim
プルリクエスト・マークダウン記法チートシート
ファイル操作コマンドチートシート
VSCode Github Copilot拡張機能
他のシリーズ記事
TypeScriptで学ぶプログラミングの世界
プログラミング言語を根本的に理解するシリーズです.
情報処理技術者試験合格への道[IP・SG・FE・AP]
情報処理技術者試験の単語集です.
IAM AWS User クラウドサービスをフル活用しよう!
AWSのサービスを例にしてバックエンドとインフラ開発の手法を説明するシリーズです.
1問1答の形式(ChatCompletions API)では?
-
シンプルな一問一答型
- 1回のリクエストで1つの応答を返す
- ステートレス(状態を保持しない)
-
コンテキスト制限
- 会話履歴は手動で管理が必要
- トークン制限内で過去の会話を含める必要がある
-
機能
- テキスト生成が主な機能
- function callingのサポート
- システムプロンプトでの役割定義
使用例
const url = "https://api.openai.com/v1/chat/completions"
// 環境変数からOPENAI_API_KEYを取ってくる
apiKey := os.Getenv("OPENAI_API_KEY")
requestBody := map[string]interface{}{
"model": "gpt-3.5-turbo",
"messages": []map[string]string{
{"role": "user", "content": prompt},
},
"max_tokens": 300,
}
jsonData, err := json.Marshal(requestBody)
if err != nil {
return "", fmt.Errorf("リクエストボディのマーシャルに失敗しました: %v", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return "", fmt.Errorf("リクエストの作成に失敗しました: %v", err)
}
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("リクエストの実行に失敗しました: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("リクエストが失敗しました: %s", resp.Status)
}
var responseBody struct {
Choices []struct {
Message struct {
Content string `json:"content"`
} `json:"message"`
} `json:"choices"`
}
if err := json.NewDecoder(resp.Body).Decode(&responseBody); err != nil {
return "", fmt.Errorf("レスポンスのデコードに失敗しました: %v", err)
}
if len(responseBody.Choices) == 0 {
return "", fmt.Errorf("レスポンスにチョイスがありません")
}
return responseBody.Choices[0].Message.Content, nil
}
Assistants APIでの実装の流れ
Assistant作成(Part 1で紹介) → Thread作成(Part 2で紹介) → メッセージ追加(Part 3で紹介) → Run実行(Part 4で紹介) → 応答取得
典型的な使用パターンは以下のようである.
// 1. アシスタント作成
assistant, _ := client.CreateAssistant(ctx, openai.AssistantRequest{
Name: "Math Tutor",
Model: "gpt-4",
})
// 2. スレッド作成
thread, _ := client.CreateThread(ctx, openai.ThreadRequest{})
// 3. メッセージ追加
message, _ := client.CreateMessage(ctx, thread.ID, openai.MessageRequest{
Content: "Help with math",
})
// 4. スレッド実行
run, _ := client.CreateRun(ctx, thread.ID, openai.RunRequest{
AssistantID: assistant.ID,
})
// 5. 結果取得
messages, _ := client.ListMessages(ctx, thread.ID, nil)
本記事ではPart 1 としてアシスタント作成などのアシスタントに関する操作について説明する.
プロジェクトのセットアップ
まずは、新しいGoプロジェクトを作成し、必要なパッケージをインストールする.
# プロジェクトディレクトリの作成
mkdir openai-assistants-threads
cd openai-assistants-threads
# Goモジュールの初期化
go mod init openai-assistants-threads
# 必要なパッケージのインストール
go get github.com/sashabaranov/go-openai
go get github.com/joho/godotenv
go mod tidy
環境変数にopanaiのAPIキーを記載する.
APIキーについては以下の記事を参考にしよう
OPENAI_API_KEY="あなたのAPIキー"
Assistants APIの実装
OpenAIのAssistants APIを使って,カスタムアシスタントを作成・管理する方法を見ていく.以下の例では,Go言語とgo-openaiパッケージを活用する.
アシスタントの作成
まずは,新しいアシスタントを作成するコードを紹介する.
package main
import (
"context"
"fmt"
"github.com/joho/godotenv"
"log"
"os"
openai "github.com/sashabaranov/go-openai"
)
func main() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
apiKey := os.Getenv("OPENAI_API_KEY")
if apiKey == "" {
log.Fatal("環境変数 OPENAI_API_KEY が設定されていません")
}
client := openai.NewClient(apiKey)
ctx := context.Background()
name := "Math Tutor" // アシスタントの表示名(回答生成に影響なし)
description := "A personal math tutor" // アシスタントの簡単な説明(回答生成に影響なし)
instructions := "You are a personal math tutor. When asked a question, write and run Python code to answer the question."
req := openai.AssistantRequest{
Model: openai.GPT3Dot5Turbo, // モデル名
Name: &name,
Description: &description,
Instructions: &instructions,
Tools: []openai.AssistantTool{
{Type: openai.AssistantToolTypeCodeInterpreter}, // ツールタイプを定義,Code Interpreter、File Search、Function callingの3種類から選択
},
}
assistant, err := client.CreateAssistant(ctx, req)
if err != nil {
log.Fatalf("アシスタントの作成に失敗: %v", err)
}
fmt.Printf("アシスタントが作成されました: %+v\n", assistant)
}
ツールタイプの定義
ドキュメント内で以下のように定義してあるので使ってみよう
const (
AssistantToolTypeCodeInterpreter AssistantToolType = "code_interpreter"
AssistantToolTypeRetrieval AssistantToolType = "retrieval"
AssistantToolTypeFunction AssistantToolType = "function"
AssistantToolTypeFileSearch AssistantToolType = "file_search"
)
モデル名も以下のように定義してあるます
const (
O1Mini = "o1-mini"
O1Mini20240912 = "o1-mini-2024-09-12"
O1Preview = "o1-preview"
O1Preview20240912 = "o1-preview-2024-09-12"
GPT432K0613 = "gpt-4-32k-0613"
GPT432K0314 = "gpt-4-32k-0314"
GPT432K = "gpt-4-32k"
GPT40613 = "gpt-4-0613"
GPT40314 = "gpt-4-0314"
GPT4o = "gpt-4o"
GPT4o20240513 = "gpt-4o-2024-05-13"
GPT4o20240806 = "gpt-4o-2024-08-06"
GPT4o20241120 = "gpt-4o-2024-11-20"
GPT4oLatest = "chatgpt-4o-latest"
GPT4oMini = "gpt-4o-mini"
GPT4oMini20240718 = "gpt-4o-mini-2024-07-18"
GPT4Turbo = "gpt-4-turbo"
GPT4Turbo20240409 = "gpt-4-turbo-2024-04-09"
GPT4Turbo0125 = "gpt-4-0125-preview"
GPT4Turbo1106 = "gpt-4-1106-preview"
GPT4TurboPreview = "gpt-4-turbo-preview"
GPT4VisionPreview = "gpt-4-vision-preview"
GPT4 = "gpt-4"
GPT3Dot5Turbo0125 = "gpt-3.5-turbo-0125"
GPT3Dot5Turbo1106 = "gpt-3.5-turbo-1106"
GPT3Dot5Turbo0613 = "gpt-3.5-turbo-0613"
GPT3Dot5Turbo0301 = "gpt-3.5-turbo-0301"
GPT3Dot5Turbo16K = "gpt-3.5-turbo-16k"
GPT3Dot5Turbo16K0613 = "gpt-3.5-turbo-16k-0613"
GPT3Dot5Turbo = "gpt-3.5-turbo"
GPT3Dot5TurboInstruct = "gpt-3.5-turbo-instruct"
// Deprecated: Model is shutdown. Use gpt-3.5-turbo-instruct instead.
GPT3TextDavinci003 = "text-davinci-003"
// Deprecated: Model is shutdown. Use gpt-3.5-turbo-instruct instead.
GPT3TextDavinci002 = "text-davinci-002"
// Deprecated: Model is shutdown. Use gpt-3.5-turbo-instruct instead.
GPT3TextCurie001 = "text-curie-001"
// Deprecated: Model is shutdown. Use gpt-3.5-turbo-instruct instead.
GPT3TextBabbage001 = "text-babbage-001"
// Deprecated: Model is shutdown. Use gpt-3.5-turbo-instruct instead.
GPT3TextAda001 = "text-ada-001"
// Deprecated: Model is shutdown. Use gpt-3.5-turbo-instruct instead.
GPT3TextDavinci001 = "text-davinci-001"
// Deprecated: Model is shutdown. Use gpt-3.5-turbo-instruct instead.
GPT3DavinciInstructBeta = "davinci-instruct-beta"
// Deprecated: Model is shutdown. Use davinci-002 instead.
GPT3Davinci = "davinci"
GPT3Davinci002 = "davinci-002"
// Deprecated: Model is shutdown. Use gpt-3.5-turbo-instruct instead.
GPT3CurieInstructBeta = "curie-instruct-beta"
GPT3Curie = "curie"
GPT3Curie002 = "curie-002"
// Deprecated: Model is shutdown. Use babbage-002 instead.
GPT3Ada = "ada"
GPT3Ada002 = "ada-002"
// Deprecated: Model is shutdown. Use babbage-002 instead.
GPT3Babbage = "babbage"
GPT3Babbage002 = "babbage-002"
)
本記事ではopenai.AssistantToolTypeCodeInterpreter
を使用します
実行
go run create_assistant.go
実際に実行して,成功すると以下のようなレスポンスが表示される.
{
"ID": "asst_abc123xyz456", # アシスタントの一意の識別子
"Object": "assistant", # オブジェクトタイプを示す固定値
"CreatedAt": 1733651787, # アシスタントが作成された Unix タイムスタンプ
"Name": "Math Tutor", # アシスタントの表示名
"Description": "A personal math tutor", # アシスタントの簡単な説明
"Model": "gpt-3.5-turbo", # 使用する言語モデル
"Instructions": "You are a personal math tutor. When asked a question, write and run Python code to answer the question.", # アシスタントの振る舞いを定義する指示
"Tools": [ # アシスタントが使用できるツールのリスト
{
"Type": "code_interpreter", # ツールの種類(code_interpreter, retrieval, function のいずれか)
"Function": null # 関数呼び出し用の設定(code_interpreterの場合は null)
}
],
"ToolResources": null, # ツールに関連するリソース情報
"FileIDs": [], # アシスタントに関連付けられたファイルIDのリスト
"Metadata": {}, # カスタムメタデータを格納するキーバリューペア
"Temperature": 0, # 応答のランダム性を制御(0-2の範囲、低いほど決定的)
"TopP": 0, # 確率分布の上位を制限するパラメータ(0-1の範囲)
"ResponseFormat": "auto", # レスポンスのフォーマット指定
"httpHeader": { # API レスポンスの HTTP ヘッダー情報
"Alt-Svc": ["h3=\":443\"; ma=86400"], # HTTP/3 サポートの告知
"Cf-Cache-Status": ["DYNAMIC"], # Cloudflare のキャッシュステータス
"Cf-Ray": ["abc123xyz456-NRT"], # Cloudflare のリクエスト識別子
"Content-Type": ["application/json"], # レスポンスの内容タイプ
"Date": ["Sun, 08 Dec 2024 09:56:27 GMT"], # レスポンス生成時刻
"Openai-Organization": ["org-abc123xyz456"], # OpenAI 組織ID
"Openai-Processing-Ms": ["441"], # API リクエスト処理時間(ミリ秒)
"Openai-Version": ["2020-10-01"], # OpenAI API バージョン
"Server": ["cloudflare"], # 使用されているWebサーバー
"Set-Cookie": [ # セッション管理用クッキー
"__cf_bm=sample_cookie_value; path=/; expires=Sun, 08-Dec-24 10:26:27 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None",
"_cfuvid=sample_cfuvid_value; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None"
],
"Strict-Transport-Security": ["max-age=31536000; includeSubDomains; preload"], # HTTPS 強制設定
"X-Content-Type-Options": ["nosniff"], # MIME タイプスニッフィング防止
"X-Request-Id": ["req_abc123xyz456"] # リクエストの一意の識別子
}
}
アシスタントの一覧取得
作成したアシスタントの一覧を取得するものの実装例を以下に示す.
package main
import (
"context"
"fmt"
"github.com/joho/godotenv"
"log"
"os"
"time"
openai "github.com/sashabaranov/go-openai"
)
func main() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
apiKey := os.Getenv("OPENAI_API_KEY")
if apiKey == "" {
log.Fatal("環境変数 OPENAI_API_KEY が設定されていません")
}
client := openai.NewClient(apiKey)
ctx := context.Background()
limit := 20
order := "desc"
assistants, err := client.ListAssistants(ctx, &limit, &order, nil, nil)
if err != nil {
log.Fatalf("アシスタント一覧の取得に失敗: %v", err)
}
fmt.Println("アシスタント一覧:")
for _, assistant := range assistants.Assistants {
name := "<unnamed>"
if assistant.Name != nil {
name = *assistant.Name
}
description := "<no description>"
if assistant.Description != nil {
description = *assistant.Description
}
createTime := time.Unix(assistant.CreatedAt, 0).Format("2006-01-02 15:04:05")
fmt.Printf("ID: %s\n", assistant.ID)
fmt.Printf("名前: %s\n", name)
fmt.Printf("説明: %s\n", description)
fmt.Printf("モデル: %s\n", assistant.Model)
fmt.Printf("作成日時: %s\n", createTime)
fmt.Println("使用可能なツール:")
for _, tool := range assistant.Tools {
fmt.Printf("- %s\n", tool.Type)
}
fmt.Println("-------------------")
}
}
実行
go run list_assistants.go
先ほど作成したアシスタントの一覧が出てくる.
アシスタント一覧:
ID: asst_sample123
名前: Math Tutor
説明: 数学の問題を解決するアシスタント
モデル: gpt-3.5-turbo
作成日時: 2024-12-08 10:28:30
使用可能なツール:
- code_interpreter
-------------------
ID: asst_sample456
名前: Writing Helper
説明: 文章作成をサポートするアシスタント
モデル: gpt-3.5-turbo
作成日時: 2024-12-08 10:27:27
使用可能なツール:
- code_interpreter
-------------------
ここで出てくるidとは?
asst_abc123
は OpenAI の Assistants API が生成するアシスタントの一意の識別子(ID)
- asst_ で始まる
- その後にランダムな英数字の文字列が続く
- システムによって自動的に生成される
- 一度生成されたIDは変更できない
アシスタントの詳細取得
特定のアシスタントの詳細情報を取得するコードは以下の通りである.
package main
import (
"context"
"fmt"
"github.com/joho/godotenv"
"log"
"os"
"time"
openai "github.com/sashabaranov/go-openai"
)
func main() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
apiKey := os.Getenv("OPENAI_API_KEY")
if apiKey == "" {
log.Fatal("環境変数 OPENAI_API_KEY が設定されていません")
}
client := openai.NewClient(apiKey)
ctx := context.Background()
assistantID := "asst_sample123f" // 取得したいアシスタントのID
assistant, err := client.RetrieveAssistant(ctx, assistantID)
if err != nil {
log.Fatalf("アシスタントの取得に失敗: %v", err)
}
fmt.Println("アシスタントの詳細:")
name := "<unnamed>"
if assistant.Name != nil {
name = *assistant.Name
}
description := "<no description>"
if assistant.Description != nil {
description = *assistant.Description
}
createTime := time.Unix(assistant.CreatedAt, 0).Format("2006-01-02 15:04:05")
fmt.Printf("ID: %s\n", assistant.ID)
fmt.Printf("名前: %s\n", name)
fmt.Printf("説明: %s\n", description)
fmt.Printf("モデル: %s\n", assistant.Model)
fmt.Printf("作成日時: %s\n", createTime)
fmt.Println("使用可能なツール:")
for _, tool := range assistant.Tools {
fmt.Printf("- %s\n", tool.Type)
}
fmt.Println("-------------------")
}
実行
go run retrieve_assistant.go
成功すると以下のようなレスポンスが返ってくる.
アシスタントの詳細:
ID: asst_sample123
名前: Math Tutor
説明: 数学の問題を解決するアシスタント
モデル: gpt-3.5-turbo
作成日時: 2024-12-08 10:28:30
使用可能なツール:
- code_interpreter
-------------------
これでアシスタントを作成したり,作成したアシスタントの情報を取得することができる.次のpartではスレッドを作成して会話を始める準備をする説明をします.
Part 2 OpenAI Assistants APIチートシート [Threads編]
それではQiitaアドカレ.24企画の今日のクリスマスツリーです.
詳しくはこちらの記事から