Azure OpenAIのAssistants APIでFile searchを実装

## はじめに
前回の記事（[Azure OpenAIのAssistants APIを解説&実装](https://qiita.com/MMatsumotoMM/items/601a722a856e2569a9b7)）で、Azure OpenAIの[Assistants API](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/concepts/assistants)の概要を紹介し、Code Interpreterを活用したAIアシスタント実装を行いました。
今回は、Code Interpreterに加えて、[File search](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/how-to/file-search?tabs=python#upload-files-for-file-search)も活用し、企業の生成AI戦略立案担当者をサポートするAIエージェントを実装します。またその中で、AI検索の基礎に関しても補足していきます。
今回も、[OpenAI公式ドキュメント](https://platform.openai.com/docs/assistants/tools/file-search)を参照し、Pythonで実装していきます。

【Assistants APIの概要（前回の振り返り）】
Assistants APIはその名の通り、特定の役割を負うAIエージェントを実装可能なAPIで、「あなたは〜を行うAIアシスタントです」というロール設定のもとに実装されます。単一のチャットUIから、Code Interpreter、File search、Function callingなどの複数のツールに並列でアクセスすることができ、ユーザの要求をもとにAssistants API自身が必要なツールを判断し、アクセスします。自動化したいプロセスごとにエージェントを作成し、AutoGenと呼ばれるフレームワークによって複数エージェントを制御することでマルチエージェントを実装することができます。

### File searchとは
File searchは、**任意の外部ドキュメントを活用してユーザの質問への回答を生成する、RAG(Retrieval-Augmented Generation)を実装**することができる機能です。
Assistantは、ユーザの質問をもとに、拡張されたナレッジベースから関連情報を検索し、回答を生成します。
ナレッジベースの拡張方法は簡単で、Vector Storeと呼ばれるオブジェクトにファイルをアップロードすると、自動的にチャンク分割やエンベディングが行われ、ベクトル検索およびキーワード検索の両方が実装されます。
チャンク分割やエンベディングといったAI検索の基本的な概念については、以下の補足セクションで補足します。
なお、Assistants API v2では、アシスタントあたり**最大 10,000 個**のファイルを取り込むことができます。これはv1の500倍以上の量です。 これは高速で、マルチスレッド検索を通して、並列クエリをサポートしており、強化された再ランク付けとクエリの書き換えを特徴としています。


### (補足)AI検索の基礎
検索技術の歴史はキーワード検索から始まり、ベクター検索、全文検索、ハイブリッド検索、あいまい検索、セマンティックランク付けなど様々な技術が発展してきました。これらはAzure AI Searchで実装可能です。
かつてこれらの検索を実装するためには、コードを記述し、NLP（自然言語処理）やインデックス化、チャンク分割、エンべディングなどを行う必要がありました。今では、Azure AI Searchにより、これらの検索を比較的簡単に実装することができます。
AssistantsAPIのFile searchもまた、ベクター検索、キーワード検索の両方を活用したRAGを簡単に実装できる機能です。
コードを記述しなくとも、Vector Storeに格納されたデータは、自動的にチャンク分割、エンべディングが行われ、検索可能なナレッジベースとして準備されます。
Assistants APIのFile searchだけでなく、Azure OpenAIから提供されている様々なAI検索/RAGの機能を活用することで、任意のデータソースから、AI検索やRAGを実装し、更に、検索精度を高めるための様々なアプローチを試行することができます。
Assistans APIのFile searchで、AIエージェントのRAG実装のイメージを掴み、その他のAI検索やRAGの実装にも是非取り組んでみてください。

### 記事の構成
①[Azure OpenAIのAssistants APIを解説&実装](https://qiita.com/MMatsumotoMM/items/601a722a856e2569a9b7)
②Azure OpenAIのAssistants APIでFile searchを実装（本記事）

### 事前準備
`openai`パッケージをインストール
（今回`dotenv`も活用しているため、こちらもインストールしております）

## 実装
**オブジェクト**
Vector Store
・AssistantがFIle searchで参照するナレッジベース
・参照させたいファイルをVector Storeにアップロードすると、自動的にチャンク分割、エンべディングが行われ、検索可能なナレッジベースとして準備される
・Assistantに紐づけるほか、threadのmessageに紐づけることも可能で、双方に紐づけた場合には並列で参照される。

その他、Assistants APIの基本的なオブジェクトは、前回の記事（[Azure OpenAIのAssistants APIを解説&実装](https://qiita.com/MMatsumotoMM/items/601a722a856e2569a9b7)）を参照ください。

**実装の流れ**
①モジュールのインポート及びクライアントの作成
②Assistantを作成
③Vector Storeを作成
④Vector StoreをAssistantに紐付け
⑤thread、messageを作成し、messageに新たなVector Storeを紐付け
⑥実行

### 実装-1 モジュールのインポート及びクライアントの作成
```python:モジュールのインポート及びクライアントの作成
from openai import AzureOpenAI
from dotenv import load_dotenv

load_dotenv(verbose=True)

client = AzureOpenAI(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
    api_version="2024-05-01-preview",
    azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
    )
```

### 実装-2 Assistantを作成
前回同様、instructionsパラメータで、「あなたは〜を行うAIアシスタントです」というAssistantのロールを設定していきます。
toolsパラメータで、Code Interpreter及びFile searchを有効化します。

```python:Assistantを作成
# instructionsパラメータでAssistantのロール（役割）を記述
# toolsパラメータでCode Interpreter及びFile searchを有効化
 
assistant = client.beta.assistants.create(
    name="企業戦略アナリスト",
    instructions="あなたは、企業の戦略立案をサポートするアナリストです。与えられたドキュメントをもとに、自社や競合他社、市場の動向を分析し、企業の戦略立案のための示唆を提供してください。",
    model="gpt-4o",
    tools=[
        {"type": "file_search"},
        {"type": "code_interpreter"}
    ]
)

print(assistant.model_dump_json(indent=4))
```
### 実装-3 Vector Storeを作成
Vector Storeを作成し、参照ドキュメントとするファイルをアップロードし、ポーリングします。

```python:Vector Storeを作成
##ファイルをVector Storeにアップロード、ポーリング

vector_store = client.beta.vector_stores.create(name="Market Analysis Report")
data_dir = './data1'
all_files = os.listdir(data_dir)

file_paths = [f"{data_dir}/{filename}" for filename in all_files]

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
)

print(file_batch.status)
print(file_batch.file_counts)
```
アウトプットとして、
`completed`、
`FileCounts(cancelled=0, completed=2, failed=0, in_progress=0, total=2)`
と返されました。
Vector Store上のファイルがチャンク分割、エンべディングされ、検索のために検索可能なナレッジベースとして準備されました。

### 実装-4 Vector StoreをAssistantに紐付け
Vector StoreをAssistantに紐付け、Assistantをアップデートします。
```python:Vector Storeを活用するようにAssistantをアップデート
assistant = client.beta.assistants.update(
  assistant_id=assistant.id,
  tool_resources={"file_search": {"vector_store_ids": [vector_store.id]}},
)
```

### 実装-5 messageに新たなVector Storeを紐付け
先述した通り、Vector Storeは、Assistantに紐づけるほか、threadのmessageに紐づけることも可能で、双方に紐づけた場合には並列で参照されます。
今回は、messageにも別のファイルを紐づけ、Vector Storeとして参照させていきます。

まずはmessageに参照させたいファイルをアタッチします。
```python:thread、messageを作成
message_file = client.files.create(
  file=open( "./data2/IBV - The CEOs Guide to Generative AI - Japanese.pdf", "rb"), purpose="assistants"
)
```
次に、thread、messageを作成します。
ここで、messageにアタッチしたファイルをFile searchで参照するよう、toolsで指定します。
Vector Storeが作成され、このmessageに限ったナレッジベースとして参照されます。
なお、コスト対策として、messageに紐づけられたVector Storeは、最後にアクティブであった日から７日後に期限切れとなる規定のポリシーが有効化されています。

```python:thread、messageを作成
message_file = client.files.create(
  file=open( "/Users/mai/Documents/user/Market Analysis Report/IBV - The CEOs Guide to Generative AI - Japanese.pdf", "rb"), purpose="assistants"
)
 
thread = client.beta.threads.create(
  messages=[
    {
      "role": "user",
      "content": "まず、生成AIが企業の競争力及び従業員満足度にどのように影響するのかを分析してください。次に、その分析をもとに、企業の成長戦略を立案してください。",
      "attachments": [
        { "file_id": message_file.id, "tools": [{"type": "file_search"}] }
      ],
    }
  ]
)
 
print(thread.tool_resources.file_search)
```
アウトプットとして、
`ToolResourcesFileSearch(vector_store_ids=['vs_C13P5Dshabo3XTJfOh3CnzVH'])`
が返され、messageにアタッチしたファイルがVector Storeとしてthreadに紐づけられたことが分かりました。

### 実装-6 実行
threadを実行していきます。
今回、ユーザの質問に回答するだけでなく、それぞれの文章のレファレンスを参照できるようにします。
文末に脚注番号を添えた上で、対応した脚注番号に対応し、レファレンスドキュメントの中から詳細な参照箇所も出力することができます。

```python:実行
run = client.beta.threads.runs.create_and_poll(
    thread_id=thread.id, assistant_id=assistant.id
)

messages = list(client.beta.threads.messages.list(thread_id=thread.id, run_id=run.id))

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))
```

## 結果
messageとして、以下の出力が返されました。
また、ユーザの質問に回答するだけでなく、それぞれの文章には、脚注番号が添えられています。
これにより、引用や参照箇所を示す脚注番号に対応し、レファレンスドキュメントの中から詳細な参照箇所も出力することができます。



#### 企業の競争力への影響
1. **生産性と業績の向上**: 生成AIを活用することで、従業員は単調なタスクを自動化し、より価値の高い作業に集中できるようになります。これにより生産性と仕事の面白みが向上し、企業全体の競争力が高まります[0][1][2]。
   
2. **業務プロセスの改善**: 生成AIはバックオフィスのシステム改善から顧客対応まで、様々な業務プロセスの効率化を実現します。これにより、企業はより迅速で効果的なオペレーションが可能となり、競争力を維持・向上させることができます[3]。

3. **戦略的なAI利用の欠如**: 一方で、多くの企業が生成AIの導入に関して明確な戦略やビジョンを欠いているため、その活用が効果的に進んでいない現状もあります[4][5]。

#### 従業員満足度への影響
1. **仕事の満足度とモチベーションの向上**: AIを使用することで、従業員はより創造的かつ重要な仕事に集中でき、仕事の満足度が向上します。また、AIを活用している従業員は、AIが導入されていない場合に比べて、仕事を楽しんでいると感じる割合が高いです[6][7]。

2. **職場でのストレス軽減**: AI導入によって従業員の業務負荷が軽減され、労働環境が改善されることで、燃え尽き症候群のリスクも軽減されます[8][9]。

3. **技能向上とキャリア構築**: 生成AIのスキルを持つ従業員は、より多くのキャリアチャンスを得られ、役職に関する責任も増加するため、従業員の成長意欲を高めます[10][11]。

### 企業の成長戦略の立案

#### 1. 生成AIの積極的な導入と活用
- **明確なビジョンと戦略の設定**: 生成AIを会社の成長戦略の核心に据え、全社的な導入計画を策定します。具体的なビジネス課題を特定し、その解決にAIを適用する方法を探ります[12]。
   
- **部門横断的なAI導入**: 顧客対応、製品開発、バックオフィスなど、各部門ごとに生成AIの使用ケースを特定し、部門リーダーと協力してAIを導入します[12][11]。

#### 2. 従業員教育と訓練
- **従業員に対するAIスキルの向上**: 全従業員に対して生成AIに関するトレーニングプログラムを提供し、その使用方法と応用について深く学ばせます。特に、AIパワーユーザーとなるための習慣付けと頻繁な実験を奨励します[10][7]。
   
- **キャリア成長のサポート**: 生成AIのスキルを持つ従業員がキャリアを進め、より大きな責任を持てるよう支援することで、従業員のエンゲージメントとモチベーションを高めます[10][18]。

#### 3. 組織文化の変革
- **創造性とイノベーションの奨励**: 生成AIを活用した創造性豊かな文化を育むため、チームビルディング活動やフィードバックループを構築し、従業員が企業の成長に貢献する意欲を高めます[2]。

- **公正性と透明性の強化**: AIの導入が従業員に不公平と感じられないように、透明かつ公正な方法での利用を推進し、従業員が安心してAIを使える環境を整えます[3][2]。

これらの戦略を総合的に実行することで、企業は生成AIを活用して競争力を高め、従業員の満足度を向上させつつ、持続可能な成長を実現できるでしょう。
[0] IBV - The CEOs Guide to Generative AI - Japanese.pdf
[1] IBV - The CEOs Guide to Generative AI - Japanese.pdf
[2] IBV - The CEOs Guide to Generative AI - Japanese.pdf
[3] IBV - The CEOs Guide to Generative AI - Japanese.pdf
[4] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[5] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[6] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[7] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[8] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[9] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[10] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[11] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[12] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[13] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[14] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[15] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[16] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[17] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[18] 2024_Work_Trend_Index_Annual_Report_6_7_24_666b2e2fafceb.pdf
[19] IBV - The CEOs Guide to Generative AI - Japanese.pdf
[20] IBV - The CEOs Guide to Generative AI - Japanese.pdf
[21] IBV - The CEOs Guide to Generative AI - Japanese.pdf'


## まとめ
今回は、Assistants APIのtoolsのひとつ、File searchを活用し、市場分析をもとに企業の戦略立案をサポートするAIエージェントを実装していきました。
Assistants APIには、前回の記事で紹介したCode Interpreter、今回実装したFile searchのほかにも、Function Callingをサポートしており、追ってアップデートしていきたいと思います。

また今回の記事では、AI検索やRAGの基礎についても触れていますが、Assistants APIのFile search以外にも、Azure OpenAIには、AI検索RAGを簡単に実装するための様々な機能があります。
これらは、企業の膨大なデータを活用したAIエージェント実装に役立てられています。
Assistans APIのFile Searchで、AIエージェントのRAG実装のイメージを掴み、その他のAI検索やRAGの実装にも是非取り組んでみてください。