# ベクターストアにファイルをアップロード

{% openapi src="/files/NPsg8DFwcSjopKSuZo9m" path="/vector-stores/{vector-store-id}/documents/upload" method="post" %}
[rememberizer\_openapi.yml](https://3282965451-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FK09NlRK7lXZsjqCNQsEe%2Fuploads%2Fgit-blob-77b6137eeb641262ec8e531c78123c02b825b865%2Frememberizer_openapi.yml?alt=media\&token=dd73efa7-56a8-4350-88ab-85d7586fb7b8)
{% endopenapi %}

## 例リクエスト

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST \
  https://api.rememberizer.ai/api/v1/vector-stores/vs_abc123/documents/upload \
  -H "x-api-key: YOUR_API_KEY" \
  -F "files=@/path/to/document1.pdf" \
  -F "files=@/path/to/document2.docx"
```

{% hint style="info" %}
`YOUR_API_KEY` を実際のベクターストアAPIキーに、`vs_abc123` をベクターストアIDに置き換え、ローカルファイルのパスを提供してください。
{% endhint %}
{% endtab %}

{% tab title="JavaScript" %}

```javascript
const uploadFiles = async (vectorStoreId, files) => {
  const formData = new FormData();
  
  // 複数のファイルをフォームデータに追加
  for (const file of files) {
    formData.append('files', file);
  }
  
  const response = await fetch(`https://api.rememberizer.ai/api/v1/vector-stores/${vectorStoreId}/documents/upload`, {
    method: 'POST',
    headers: {
      'x-api-key': 'YOUR_API_KEY'
      // 注意: Content-Type ヘッダーは設定しないでください。正しい境界で自動的に設定されます。
    },
    body: formData
  });
  
  const data = await response.json();
  console.log(data);
};

// ファイル入力要素を使用した例
const fileInput = document.getElementById('fileInput');
uploadFiles('vs_abc123', fileInput.files);
```

{% hint style="info" %}
`YOUR_API_KEY` を実際のベクターストアAPIキーに、`vs_abc123` をベクターストアIDに置き換えてください。
{% endhint %}
{% endtab %}

{% tab title="Python" %}

```python
import requests

def upload_files(vector_store_id, file_paths):
    headers = {
        "x-api-key": "YOUR_API_KEY"
    }
    
    files = [('files', (file_path.split('/')[-1], open(file_path, 'rb'))) for file_path in file_paths]
    
    response = requests.post(
        f"https://api.rememberizer.ai/api/v1/vector-stores/{vector_store_id}/documents/upload",
        headers=headers,
        files=files
    )
    
    data = response.json()
    print(data)

upload_files('vs_abc123', ['/path/to/document1.pdf', '/path/to/document2.docx'])
```

{% hint style="info" %}
`YOUR_API_KEY` を実際のベクターストアAPIキーに、`vs_abc123` をベクターストアIDに置き換え、ローカルファイルのパスを提供してください。
{% endhint %}
{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'net/http'
require 'uri'
require 'json'

def upload_files(vector_store_id, file_paths)
  uri = URI("https://api.rememberizer.ai/api/v1/vector-stores/#{vector_store_id}/documents/upload")
  
  # 新しいHTTPオブジェクトを作成
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  
  # マルチパートフォームリクエストを作成
  request = Net::HTTP::Post.new(uri)
  request['x-api-key'] = 'YOUR_API_KEY'
  
  # マルチパート境界を作成
  boundary = "RubyFormBoundary#{rand(1000000)}"
  request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
  
  # リクエストボディを構築
  body = []
  file_paths.each do |file_path|
    file_name = File.basename(file_path)
    file_content = File.read(file_path, mode: 'rb')
    
    body << "--#{boundary}\r\n"
    body << "Content-Disposition: form-data; name=\"files\"; filename=\"#{file_name}\"\r\n"
    body << "Content-Type: #{get_content_type(file_name)}\r\n\r\n"
    body << file_content
    body << "\r\n"
  end
  body << "--#{boundary}--\r\n"
  
  request.body = body.join
  
  # リクエストを送信
  response = http.request(request)
  
  # レスポンスを解析して返す
  JSON.parse(response.body)
end
```

## コンテンツタイプを決定するためのヘルパーメソッド

def get\_content\_type(filename) ext = File.extname(filename).downcase case ext when '.pdf' then 'application/pdf' when '.doc' then 'application/msword' when '.docx' then 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' when '.txt' then 'text/plain' when '.md' then 'text/markdown' when '.json' then 'application/json' else 'application/octet-stream' end end

## 使用例

result = upload\_files('vs\_abc123', \['/path/to/document1.pdf', '/path/to/document2.docx']) puts result

````

{% hint style="info" %}
`YOUR_API_KEY` を実際の Vector Store API キーに置き換え、`vs_abc123` をあなたの Vector Store ID に置き換え、ローカルファイルへのパスを提供してください。
{% endhint %}
{% endtab %}
{% endtabs %}

## パスパラメータ

| パラメータ | タイプ | 説明 |
|-----------|------|-------------|
| vector-store-id | string | **必須。** ファイルをアップロードするベクトルストアのID。 |

## リクエストボディ

このエンドポイントは、`files`フィールドに1つ以上のファイルを含む`multipart/form-data`リクエストを受け付けます。

## レスポンス形式

```json
{
  "documents": [
    {
      "id": 1234,
      "name": "document1.pdf",
      "type": "application/pdf",
      "size": 250000,
      "status": "processing",
      "created": "2023-06-15T10:15:00Z",
      "vector_store": "vs_abc123"
    },
    {
      "id": 1235,
      "name": "document2.docx",
      "type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "size": 180000,
      "status": "processing",
      "created": "2023-06-15T10:15:00Z",
      "vector_store": "vs_abc123"
    }
  ],
  "errors": []
}
````

ファイルのアップロードに失敗した場合、それらは `errors` 配列にリストされます:

```json
{
  "documents": [
    {
      "id": 1234,
      "name": "document1.pdf",
      "type": "application/pdf",
      "size": 250000,
      "status": "processing",
      "created": "2023-06-15T10:15:00Z",
      "vector_store": "vs_abc123"
    }
  ],
  "errors": [
    {
      "file": "document2.docx",
      "error": "ファイル形式がサポートされていません"
    }
  ]
}
```

### 認証

このエンドポイントは、`x-api-key` ヘッダーを使用して API キーによる認証を必要とします。

### サポートされているファイル形式

* PDF (`.pdf`)
* Microsoft Word (`.doc`, `.docx`)
* Microsoft Excel (`.xls`, `.xlsx`)
* Microsoft PowerPoint (`.ppt`, `.pptx`)
* テキストファイル (`.txt`)
* Markdown (`.md`)
* JSON (`.json`)
* HTML (`.html`, `.htm`)

### ファイルサイズ制限

* 個々のファイルサイズ制限: 50MB
* 総リクエストサイズ制限: 100MB
* リクエストごとの最大ファイル数: 20

### エラー応答

| ステータスコード | 説明                                          |
| -------- | ------------------------------------------- |
| 400      | 不正なリクエスト - ファイルが提供されていないか、リクエスト形式が無効です      |
| 401      | 認証エラー - 無効または欠落しているAPIキー                    |
| 404      | 未検出 - ベクターストアが見つかりません                       |
| 413      | ペイロードが大きすぎます - ファイルがサイズ制限を超えています            |
| 415      | サポートされていないメディアタイプ - ファイル形式がサポートされていません      |
| 500      | 内部サーバーエラー                                   |
| 207      | マルチステータス - 一部のファイルは正常にアップロードされましたが、他は失敗しました |

### 処理状況

ファイルは最初に `processing` のステータスで受け入れられます。ドキュメントの処理状況は、[ベクトルストア内のドキュメントのリストを取得する](/ja/rissu/api-docs/vector-store/get-a-list-of-documents-in-a-vector-store.md) エンドポイントを使用して確認できます。最終的なステータスは次のいずれかになります：

* `done`: ドキュメントが正常に処理されました
* `error`: 処理中にエラーが発生しました
* `processing`: ドキュメントはまだ処理中です

処理時間はファイルのサイズと複雑さに依存します。典型的な処理時間は、ドキュメントごとに30秒から5分の間です。

### バッチ操作

複数のファイルを効率的にベクターストアにアップロードするために、Rememberizerはバッチ操作をサポートしています。このアプローチは、大量のドキュメントを扱う際のパフォーマンスを最適化するのに役立ちます。

#### バッチアップロードの実装

{% tabs %} {% tab title="Python" %}

```python
import os
import requests
import time
import concurrent.futures
from pathlib import Path

def batch_upload_to_vector_store(vector_store_id, folder_path, batch_size=5, file_types=None):
    """
    ディレクトリ内のすべてのファイルをバッチでベクターストアにアップロードします
    
    Args:
        vector_store_id: ベクターストアのID
        folder_path: アップロードするファイルを含むフォルダーへのパス
        batch_size: 各バッチでアップロードするファイルの数
        file_types: フィルタリングするファイル拡張子のオプションリスト（例：['.pdf', '.docx']）
        
    Returns:
        アップロード結果のリスト
    """
    api_key = "YOUR_API_KEY"
    headers = {"x-api-key": api_key}
    
    # ディレクトリ内のファイルのリストを取得
    files = []
    for entry in os.scandir(folder_path):
        if entry.is_file():
            file_path = Path(entry.path)
            # 指定されている場合はファイル拡張子でフィルタリング
            if file_types is None or file_path.suffix.lower() in file_types:
                files.append(file_path)
    
    print(f"アップロードするファイルが {len(files)} 件見つかりました")
    results = []
    
    # バッチでファイルを処理
    for i in range(0, len(files), batch_size):
        batch = files[i:i+batch_size]
        print(f"バッチ {i//batch_size + 1}/{(len(files) + batch_size - 1)//batch_size} を処理中: {len(batch)} 件のファイル")
        
        # バッチをアップロード
        upload_files = []
        for file_path in batch:
            upload_files.append(('files', (file_path.name, open(file_path, 'rb'))))
        
        try:
            response = requests.post(
                f"https://api.rememberizer.ai/api/v1/vector-stores/{vector_store_id}/documents/upload",
                headers=headers,
                files=upload_files
            )
            
            # すべてのファイルハンドルを閉じる
            for _, (_, file_obj) in upload_files:
                file_obj.close()
            
            if response.status_code in (200, 201, 207):
                batch_result = response.json()
                results.append(batch_result)
                print(f"バッチを正常にアップロードしました - {len(batch_result.get('documents', []))} 件のドキュメントが処理されました")
                
                # エラーを確認
                if batch_result.get('errors') and len(batch_result['errors']) > 0:
                    print(f"エラーが発生しました: {len(batch_result['errors'])} 件")
                    for error in batch_result['errors']:
                        print(f"- {error['file']}: {error['error']}")
            else:
                print(f"バッチアップロードが失敗しました。ステータスコード {response.status_code}: {response.text}")
                results.append({"error": f"バッチが失敗しました: {response.text}"})
                
        except Exception as e:
            print(f"バッチアップロード中に例外が発生しました: {str(e)}")
            results.append({"error": str(e)})
            
            # 例外が発生した場合に残りのファイルハンドルを閉じる
            for _, (_, file_obj) in upload_files:
                try:
                    file_obj.close()
                except:
                    pass
        
        # レート制限 - バッチ間に一時停止
        if i + batch_size < len(files):
            print("次のバッチの前に一時停止しています...")
            time.sleep(2)
    
    return results

# 使用例
results = batch_upload_to_vector_store(
    'vs_abc123',
    '/path/to/documents/folder',
    batch_size=5,
    file_types=['.pdf', '.docx', '.txt']
)
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
/**
 * ファイルをバッチでベクターストアにアップロードする
 * 
 * @param {string} vectorStoreId - ベクターストアのID
 * @param {FileList|File[]} files - アップロードするファイル
 * @param {Object} options - 設定オプション
 * @returns {Promise<Array>} - アップロード結果のリスト
 */
async function batchUploadToVectorStore(vectorStoreId, files, options = {}) {
  const {
    batchSize = 5,
    delayBetweenBatches = 2000,
    onProgress = null
  } = options;
  
  const apiKey = 'YOUR_API_KEY';
  const results = [];
  const fileList = Array.from(files);
  const totalBatches = Math.ceil(fileList.length / batchSize);
  
  console.log(`合計 ${fileList.length} ファイルを ${totalBatches} バッチでアップロードする準備中`);
  
  // ファイルをバッチで処理する
  for (let i = 0; i < fileList.length; i += batchSize) {
    const batch = fileList.slice(i, i + batchSize);
    const batchNumber = Math.floor(i / batchSize) + 1;
    
    console.log(`バッチ ${batchNumber}/${totalBatches} を処理中: ${batch.length} ファイル`);
    
    if (onProgress) {
      onProgress({
        currentBatch: batchNumber,
        totalBatches: totalBatches,
        filesInBatch: batch.length,
        totalFiles: fileList.length,
        completedFiles: i
      });
    }
    
    // このバッチのための FormData を作成
    const formData = new FormData();
    batch.forEach(file => {
      formData.append('files', file);
    });
    
    try {
      const response = await fetch(
        `https://api.rememberizer.ai/api/v1/vector-stores/${vectorStoreId}/documents/upload`,
        {
          method: 'POST',
          headers: {
            'x-api-key': apiKey
          },
          body: formData
        }
      );
      
      if (response.ok) {
        const batchResult = await response.json();
        results.push(batchResult);
        
        console.log(`バッチを正常にアップロードしました - ${batchResult.documents?.length || 0} ドキュメントが処理されました`);
        
        // エラーをチェック
        if (batchResult.errors && batchResult.errors.length > 0) {
          console.warn(`エラーが発生しました: ${batchResult.errors.length}`);
          batchResult.errors.forEach(error => {
            console.warn(`- ${error.file}: ${error.error}`);
          });
        }
      } else {
        console.error(`バッチアップロードが失敗しました。ステータス ${response.status}: ${await response.text()}`);
        results.push({ error: `バッチが失敗しました。ステータス: ${response.status}` });
      }
    } catch (error) {
      console.error(`バッチアップロード中に例外が発生しました: ${error.message}`);
      results.push({ error: error.message });
    }
    
    // レート制限を避けるためにバッチ間に遅延を追加
    if (i + batchSize < fileList.length) {
      console.log(`次のバッチの前に ${delayBetweenBatches}ms 一時停止します...`);
      await new Promise(resolve => setTimeout(resolve, delayBetweenBatches));
    }
  }
  
  console.log(`アップロード完了。${fileList.length} ファイルを処理しました。`);
  return results;
}

// ファイル入力要素を使用した例
document.getElementById('upload-button').addEventListener('click', async () => {
  const fileInput = document.getElementById('file-input');
  const vectorStoreId = 'vs_abc123';
  
  const progressBar = document.getElementById('progress-bar');
  
  try {
    const results = await batchUploadToVectorStore(vectorStoreId, fileInput.files, {
      batchSize: 5,
      onProgress: (progress) => {
        // プログレスUIを更新
        const percentage = Math.round((progress.completedFiles / progress.totalFiles) * 100);
        progressBar.style.width = `${percentage}%`;
        progressBar.textContent = `${percentage}% (バッチ ${progress.currentBatch}/${progress.totalBatches})`;
      }
    });
    
    console.log('アップロード結果:', results);
  } catch (error) {
    console.error('アップロードに失敗しました:', error);
  }
});
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'net/http'
require 'uri'
require 'json'
require 'mime/types'

# ベクターストアにファイルをバッチでアップロードする
#
# @param vector_store_id [String] ベクターストアのID
# @param folder_path [String] アップロードするファイルを含むフォルダーへのパス
# @param batch_size [Integer] 各バッチでアップロードするファイルの数
# @param file_types [Array<String>] オプションのファイル拡張子をフィルタリングするための配列
# @param delay_between_batches [Float] バッチ間の待機時間（秒）
# @return [Array] アップロード結果のリスト
def batch_upload_to_vector_store(vector_store_id, folder_path, batch_size: 5, file_types: nil, delay_between_batches: 2.0)
  api_key = 'YOUR_API_KEY'
  results = []
  
  # ディレクトリ内のファイルリストを取得
  files = Dir.entries(folder_path)
    .select { |f| File.file?(File.join(folder_path, f)) }
    .select { |f| file_types.nil? || file_types.include?(File.extname(f).downcase) }
    .map { |f| File.join(folder_path, f) }
  
  puts "アップロードするファイルが #{files.count} 件見つかりました"
  total_batches = (files.count.to_f / batch_size).ceil
  
  # バッチでファイルを処理
  files.each_slice(batch_size).with_index do |batch, batch_index|
    puts "バッチ #{batch_index + 1}/#{total_batches} を処理中: #{batch.count} 件のファイル"
    
    # HTTPリクエストを準備
    uri = URI("https://api.rememberizer.ai/api/v1/vector-stores/#{vector_store_id}/documents/upload")
    request = Net::HTTP::Post.new(uri)
    request['x-api-key'] = api_key
    
    # マルチパートフォームの境界を作成
    boundary = "RubyBoundary#{rand(1000000)}"
    request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
    
    # リクエストボディを構築
    body = []
    batch.each do |file_path|
      file_name = File.basename(file_path)
      mime_type = MIME::Types.type_for(file_path).first&.content_type || 'application/octet-stream'
      
      begin
        file_content = File.binread(file_path)
        
        body << "--#{boundary}\r\n"
        body << "Content-Disposition: form-data; name=\"files\"; filename=\"#{file_name}\"\r\n"
        body << "Content-Type: #{mime_type}\r\n\r\n"
        body << file_content
        body << "\r\n"
      rescue => e
        puts "ファイル #{file_path} の読み込み中にエラーが発生しました: #{e.message}"
      end
    end
    body << "--#{boundary}--\r\n"
    
    request.body = body.join
    
    # リクエストを送信
    begin
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      response = http.request(request)
      
      if response.code.to_i == 200 || response.code.to_i == 201 || response.code.to_i == 207
        batch_result = JSON.parse(response.body)
        results << batch_result
        
        puts "バッチのアップロードに成功しました - #{batch_result['documents']&.count || 0} 件のドキュメントが処理されました"
        
        # エラーをチェック
        if batch_result['errors'] && !batch_result['errors'].empty?
          puts "エラーが発生しました: #{batch_result['errors'].count} 件"
          batch_result['errors'].each do |error|
            puts "- #{error['file']}: #{error['error']}"
          end
        end
      else
        puts "バッチのアップロードがステータスコード #{response.code} で失敗しました: #{response.body}"
        results << { "error" => "バッチが失敗しました: #{response.body}" }
      end
    rescue => e
      puts "バッチアップロード中に例外が発生しました: #{e.message}"
      results << { "error" => e.message }
    end
    
    # レート制限 - バッチ間の一時停止
    if batch_index < total_batches - 1
      puts "#{delay_between_batches} 秒間次のバッチの前に一時停止します..."
      sleep(delay_between_batches)
    end
  end
  
  puts "アップロードが完了しました。#{files.count} 件のファイルが処理されました。"
  results
end

# 使用例
results = batch_upload_to_vector_store(
  'vs_abc123',
  '/path/to/documents/folder',
  batch_size: 5,
  file_types: ['.pdf', '.docx', '.txt'],
  delay_between_batches: 2.0
)
```

{% endtab %}
{% endtabs %}

### バッチアップロードのベストプラクティス

大量のファイルをアップロードする際のパフォーマンスと信頼性を最適化するために：

1. **バッチサイズの管理**: 最適なパフォーマンスのために、バッチサイズは5〜10ファイルに保ちます。1回のリクエストにファイルが多すぎると、タイムアウトのリスクが増加します。
2. **レート制限の実装**: バッチ間に遅延を追加します（2〜3秒推奨）して、APIのレート制限に達するのを避けます。
3. **エラー再試行ロジックの追加**: 本番システムでは、指数バックオフを用いた失敗したアップロードの再試行ロジックを実装します。
4. **ファイルタイプの検証**: アップロードを試みる前に、サポートされているタイプであることを確認するためにファイルを事前フィルタリングします。
5. **バッチ進行状況の監視**: ユーザー向けアプリケーションでは、バッチ操作の進行状況フィードバックを提供します。
6. **部分的成功の処理**: APIは部分的成功のために207ステータスコードを返す場合があります。常に個々のドキュメントのステータスを確認してください。
7. **リソースのクリーンアップ**: 特にエラーが発生した場合には、すべてのファイルハンドルが適切に閉じられていることを確認します。
8. **賢く並列化**: 非常に大きなアップロード（数千ファイル）では、異なるベクトルストアをターゲットにした複数の同時バッチプロセスを検討し、必要に応じて後で結果を統合します。
9. **チェックサムの実装**: 重要なデータについては、アップロード前後にチェックサムでファイルの整合性を確認します。
10. **包括的な結果のログ**: トラブルシューティングのために、すべてのアップロード操作の詳細なログを維持します。

これらのベストプラクティスに従うことで、ベクトルストアへの大規模なドキュメントの取り込みを効率的に管理できます。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rememberizer.ai/ja/rissu/api-docs/vector-store/upload-files-to-a-vector-store.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
