# by nitta@tsuda.ac.jp
import os
is_colab = 'google.colab' in str(get_ipython()) # for Google Colab
if is_colab:
from google.colab import drive
drive.mount('/content/drive')
SAVE_PATH='/content/drive/MyDrive/DeepLearning'
else:
SAVE_PATH='.'
# # variable definition in 'account.py' to access HuggingFace Hub
# MyAccount = {
# 'HuggingFace': {
# 'user': 'YourUserName',
# 'token': 'YourTokenWithWritePermission'
# },
# 'OpenAI': {
# 'api-key': 'YourOpenAI_API_Key'
# },
# }
ACCOUNT_FILE = os.path.join(SAVE_PATH, 'account.py')
%run {ACCOUNT_FILE} # set 'MyAccount' variable
os.environ["OPENAI_API_KEY"] = MyAccount['OpenAI']['api-key'] # by nitta
"File Search" とは、いろいろな形式のテキストを使って、アシスタントに外部からの知識を拡張できる機能である。
公式ドキュメント:
OpenAI Assistant API: File Search
「投資信託説明書(交付目論見書)」 (使用開始日 2024.06.21) 「<購入・換金手数料なし>ニッセイNASDAQ100インデックスファンド」https://search.sbisec.co.jp/v2/popwin/info/connect/fund/2931323300000005.pdf
「投資信託説明書(交付目論見書)」 (使用開始日 2024.1.25) 「eMAXIS Slim 米国株式(S&P500)」https://search.sbisec.co.jp/v2/popwin/info/connect/fund/0331118700000029.pdf
# pdf file へのパス
pdf_path1 = f'{SAVE_PATH}/openai_assistant/data/nissei_nasdaq100_prospectus.pdf'
pdf_path2 = f'{SAVE_PATH}/openai_assistant/data/emaxis_slim_sp500_prospectus.pdf'
# パッケージのインストール
!pip install openai
from openai import OpenAI
# クライアントの準備
client = OpenAI()
import json
# JSON出力ヘルパーの準備
def show_json(obj):
display(json.loads(obj.model_dump_json()))
tools
パラメータとして
file_search
を渡して、アシスタントを作成する。
assistant = client.beta.assistants.create(
name = "Finanicial Analyst Assistant",
instructions = "あなたは株式投資の専門家です。知識ベースを利用して、投資信託の目論見書に関する質問に回答してください。",
model="gpt-4o",
tools=[{'type': 'file_search'}],
)
追加したファイルにアクセスするために、file_search
ツールは VectorStore を使う。
vector_stores.file.batches.upload_and_poll()
は、
ファイルをアップロードした後、
すべてのコンテンツの処理が終了するのを待ってから値を返す。
! ls -l {pdf_path1}
# pdf file を upload する。
vector_store = client.beta.vector_stores.create(name="Investment Trust Prospectus")
file_paths = [pdf_path1, pdf_path2]
file_streams = [ open(path, "rb") for path in file_paths ]
file_batch = client.beta.vector_stores.file_batches.upload_and_poll(
vector_store_id=vector_store.id,
files=file_streams
)
show_json(vector_store)
show_json(file_batch)
print(file_batch.status)
print(file_batch.file_counts)
アシスタントが追加したファイルにアクセスできるように、
アシスタントの tool_resources
を
新しい VectorStore の ID で更新する。
assistant = client.beta.assistants.update(
assistant_id = assistant.id,
tool_resources={ 'file_search': { 'vector_store_ids': [vector_store.id]}}
)
スレッドに Message Attatchment としてファイルを添付することもできる。 これを行うと、新しい VectorStore が作成されて、スレッドに添付される。 既にスレッドに VectorStore が添付されている場合は、新しいファイルを既存の スレッド VectorStore に添付する。
このスレッドで Run を作成すると、 file search ツールはアシスタントのVectorStoreとスレッドのVectorStore の両方を探索する。
message_file = client.files.create(
file=open(pdf_path1, "rb"),
purpose='assistants',
)
thread = client.beta.threads.create(
messages = [
{
'role': 'user',
'content': 'nasdaq100 の特色を教えてください。',
'attachments': [
{
'file_id': message_file.id,
'tools': [ { 'type': 'file_search' }]
}
],
}
]
)
print(thread.tool_resources.file_search)
"With Streaming" と "Without Streaming" の2通りがある。
ここでは、簡単のため "Without Streaming" の場合を述べる。
# Run を作成する。
run = client.beta.threads.runs.create_and_poll(
thread_id = thread.id,
assistant_id = assistant.id,
)
print(run)
show_json(run)
messages = list(client.beta.threads.messages.list(thread_id=thread.id, run_id=run.id))
print(messages)
print(len(messages))
print(messages[0])
show_json(messages[0])
message_content = messages[0].content[0].text
annotations = message_content.annotations
citations = []
for index, annotation in enumerate(annotations):
message_content.value = message_content.value.replace(annotation.text, f"[{index}]")
if file_citation := getattr(annotation, "file_citation", None):
cited_file = client.files.retrieve(file_citation.file_id)
citations.append(f'[{index}] {cited_file.filename}')
print(message_content.value)
print('\n'.join(citations))