概要

Azure OpenAI Assistants APIを用いたアプリをGradioとNext.jsで作成したので、備忘録です。

対象データ

Zennで公開している記事を対象にしました。まず以下により、一括ダウンロードしました。

import requests
from bs4 import BeautifulSoup
import os
from tqdm import tqdm

page = 1
urls = []

while 1:
    url = f"https://zenn.dev/api/articles?username=nakamura196&page={page}"
    response = requests.get(url)
    data = response.json()
    articles = data['articles']
    if len(articles) == 0:
        break
    for article in articles:
        urls.append("https://zenn.dev" + article['path'])
    page += 1

for url in tqdm(urls):
    text_opath = f"data/text/{url.split('/')[-1]}.txt"
    if os.path.exists(text_opath):
        continue
    response = requests.get(url)
    soup = BeautifulSoup(response.text, "html.parser")
    html = soup.find(class_="znc")
    txt = html.get_text()
    os.makedirs(os.path.dirname(text_opath), exist_ok=True)
    with open(text_opath, "w") as f:
        f.write(txt)

ベクトルストアへの登録

以下のようなコードにより、データファイルをアップロードします。

import os
from dotenv import load_dotenv
from openai import AzureOpenAI
from glob import glob
from tqdm import tqdm

load_dotenv(override=True)
client = AzureOpenAI(
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT_ZENN"),
  api_key=os.getenv("AZURE_OPENAI_API_KEY_ZENN"),
  api_version="2024-05-01-preview"
)

# ベクトルストアの作成または取得
is_create_vector_store = True
vector_store_name = "Vector Store"
if is_create_vector_store:
    vector_store = client.beta.vector_stores.create(name=vector_store_name) # Create a vector store caled "Financial Statements"
vector_stores = client.beta.vector_stores.list()
for vector_store in vector_stores:
    if vector_store.name == vector_store_name:
        vector_store_id = vector_store.id
        break

# 登録済みデータファイルの取得
response = client.files.list(purpose="assistants")
items = response.data
filenames = []
for item in items:
    filename = item.filename
    filenames.append(filename)
filenames.sort()

# アップロード
## 定数設定
BATCH_SIZE = 100
vector_store_id = "vs_UELnIBkcROD3o4XKX2CcpVjo"

## ファイル一覧取得とソート
files = glob("./data/text/*.txt")
files.sort()

## アップロード済みファイルを確認済みと仮定
file_streams = []

for file in tqdm(files):
    filename = os.path.basename(file)
    if filename in filenames:  # アップロード済みのファイルをスキップ
        continue

    ## ファイルをストリームとして開く
    file_streams.append(open(file, "rb"))

    ## バッチサイズに達したらアップロード処理
    if len(file_streams) == BATCH_SIZE:
        try:
            client.beta.vector_stores.file_batches.upload_and_poll(
                vector_store_id=vector_store_id, files=file_streams
            )
        except Exception as e:
            print(f"Error processing batch: {e}")
        finally:
            file_streams = []  # ストリームリセット

## 残りのファイルを処理
if file_streams:
    try:
        client.beta.vector_stores.file_batches.upload_and_poll(
            vector_store_id=vector_store_id, files=file_streams
        )
    except Exception as e:
        print(f"Error processing remaining files: {e}")

アシスタント プレイグラウンド

「アシスタント プレイグラウンド」を用いて、挙動を確認します。

少し気になった挙動として、同じファイルが複数回Citationされた場合、2つ目以降はコンテンツが空の形で表示されるようでした。

Gradio

Azure OpenAI Assistants APIとGradioを使ったアプリを試作しました。以下のSpacesからお試しいただけます。

https://huggingface.co/spaces/nakamura196/zenn

実装方法は以下をご確認ください。

https://huggingface.co/spaces/nakamura196/zenn/tree/main

GradioのChatbotとAzure OpenAI Assistants APIを組み合わせるにあたり、一部変則的な実装を行なっている点がありますが、参考になりましたら幸いです。

Next.js

同様に、openai-assistants-quickstartを使ったアプリも試作しました。以下でお試しいただけます。

https://openai-assistants-quickstart-zenn.vercel.app/examples/basic-chat

リポジトリは以下です。

https://github.com/nakamura196/openai-assistants-quickstart_zenn

openai-assistants-quickstartで、Azure OpenAI Serviceを使用するにあたり、openai.tsファイルを以下のように変更しました。

import { AzureOpenAI } from "openai";
export const openai = new AzureOpenAI({
  endpoint: process.env.OPENAI_ENDPOINT,
  apiKey: process.env.OPENAI_API_KEY,
  deployment: "gpt-4o",
  apiVersion: "2024-05-01-preview",
});

課題

GradioとNext.jsのどちらにおいても、以下のエラーが発生して、Citationのファイルの内容を取得することができませんでした。

https://community.openai.com/t/can-not-download-assistant-generated-file-download-link-assistants-api-v2/1002926/1

この点については、引き続き調査したいと思います。

まとめ

Azure OpenAI Assistants APIの利用にあたり、参考になりましたら幸いです。