forked from hangshuo652/aurak
feat: implement QuestionBank CRUD with pagination and template query
- Add pagination support to findAll (page, limit query params) - Add findByTemplateId method to service - Add GET /by-template/:templateId endpoint to controller - Service already includes CRUD for QuestionBank and QuestionBankItem
This commit is contained in:
@@ -0,0 +1,361 @@
|
||||
# チャンクサイズの制限に関する完全スキーム
|
||||
|
||||
## 🎯 設計目標
|
||||
|
||||
**主要な問題の解決:**
|
||||
|
||||
1. ✅ チャンクサイズがモデルの入力制限を超えないようにする
|
||||
2. ✅ 環境変数でグローバルな上限を設定可能にする
|
||||
3. ✅ フロントエンドのスライダーで動的に制限し、上限を超えられないようにする
|
||||
4. ✅ バックエンドで自動検証と調整を行う
|
||||
|
||||
---
|
||||
|
||||
## 📋 設定階層構造
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 環境変数の設定 (server/.env) │
|
||||
│ MAX_CHUNK_SIZE=8191 │
|
||||
│ MAX_OVERLAP_SIZE=200 │
|
||||
└─────────────────────────────────────────┘
|
||||
↓ 優先度1(最も厳格)
|
||||
┌─────────────────────────────────────────┐
|
||||
│ モデル制限設定 (ChunkConfigService) │
|
||||
│ OpenAI: 8191 tokens │
|
||||
│ Gemini: 2048 tokens │
|
||||
└─────────────────────────────────────────┘
|
||||
↓ 優先度2
|
||||
┌─────────────────────────────────────────┐
|
||||
│ ユーザー設定 (フロントエンドスライダー)│
|
||||
│ chunkSize: 200 tokens │
|
||||
│ chunkOverlap: 40 tokens │
|
||||
└─────────────────────────────────────────┘
|
||||
↓ 最終検証
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 実際に適用される値 (自動調整) │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 環境変数の設定
|
||||
|
||||
### server/.env
|
||||
|
||||
```env
|
||||
# チャンクサイズの上限 (tokens)
|
||||
# 使用する埋め込みモデルに合わせて設定
|
||||
# OpenAI text-embedding-3-large: 8191
|
||||
# OpenAI text-embedding-3-small: 8191
|
||||
# Google Gemini embedding-001: 2048
|
||||
MAX_CHUNK_SIZE=8191
|
||||
|
||||
# チャンクオーバーラップの上限 (tokens)
|
||||
# チャンクサイズの 10-20% を推奨
|
||||
MAX_OVERLAP_SIZE=200
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ アーキテクチャの実装
|
||||
|
||||
### 1. ChunkConfigService (バックエンドコア)
|
||||
|
||||
```typescript
|
||||
// 環境変数から上限を読み込む
|
||||
private readonly envMaxChunkSize: number;
|
||||
private readonly envMaxOverlapSize: number;
|
||||
|
||||
// 主要なモデルの制限
|
||||
private readonly MODEL_LIMITS = {
|
||||
'text-embedding-3-large': {
|
||||
maxInputTokens: 8191,
|
||||
maxBatchSize: 2048,
|
||||
expectedDimensions: 3072,
|
||||
},
|
||||
'embedding-001': {
|
||||
maxInputTokens: 2048,
|
||||
maxBatchSize: 100,
|
||||
expectedDimensions: 768,
|
||||
},
|
||||
};
|
||||
|
||||
// 最終的な上限を計算
|
||||
const effectiveMaxChunkSize = Math.min(
|
||||
this.envMaxChunkSize, // 環境変数
|
||||
limits.maxInputTokens // モデルの制限
|
||||
);
|
||||
```
|
||||
|
||||
### 2. 検証ロジック
|
||||
|
||||
```typescript
|
||||
async validateChunkConfig(chunkSize, chunkOverlap, modelId, userId) {
|
||||
const warnings = [];
|
||||
|
||||
// 1. 最終的な上限を計算
|
||||
const effectiveMaxChunkSize = Math.min(
|
||||
this.envMaxChunkSize,
|
||||
limits.maxInputTokens
|
||||
);
|
||||
|
||||
// 2. チャンクサイズの検証
|
||||
if (chunkSize > effectiveMaxChunkSize) {
|
||||
warnings.push(`上限 ${effectiveMaxChunkSize} を超えています`);
|
||||
chunkSize = effectiveMaxChunkSize;
|
||||
}
|
||||
|
||||
// 3. オーバーラップサイズの検証
|
||||
const maxOverlap = Math.min(
|
||||
this.envMaxOverlapSize,
|
||||
Math.floor(chunkSize * 0.5)
|
||||
);
|
||||
if (chunkOverlap > maxOverlap) {
|
||||
warnings.push(`オーバーラップが上限 ${maxOverlap} を超えています`);
|
||||
chunkOverlap = maxOverlap;
|
||||
}
|
||||
|
||||
return {
|
||||
chunkSize,
|
||||
chunkOverlap,
|
||||
warnings,
|
||||
effectiveMaxChunkSize,
|
||||
effectiveMaxOverlapSize,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 3. API エンドポイント
|
||||
|
||||
```typescript
|
||||
// GET /api/knowledge-bases/chunk-config/limits?embeddingModelId=xxx
|
||||
{
|
||||
"maxChunkSize": 8191,
|
||||
"maxOverlapSize": 200,
|
||||
"defaultChunkSize": 200,
|
||||
"defaultOverlapSize": 40,
|
||||
"modelInfo": {
|
||||
"name": "text-embedding-3-large",
|
||||
"maxInputTokens": 8191,
|
||||
"maxBatchSize": 2048,
|
||||
"expectedDimensions": 3072
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 フロントエンドの実装
|
||||
|
||||
### IndexingModal.tsx
|
||||
|
||||
```typescript
|
||||
// 状態管理
|
||||
const [limits, setLimits] = useState(null);
|
||||
const [chunkSize, setChunkSize] = useState(200);
|
||||
const [chunkOverlap, setChunkOverlap] = useState(40);
|
||||
|
||||
// モデル選択時に制限をロード
|
||||
useEffect(() => {
|
||||
if (selectedEmbedding) {
|
||||
const limitData = await chunkConfigService.getLimits(selectedEmbedding, token);
|
||||
setLimits(limitData);
|
||||
|
||||
// 現在の値を自動調整
|
||||
if (chunkSize > limitData.maxChunkSize) {
|
||||
setChunkSize(limitData.maxChunkSize);
|
||||
}
|
||||
}
|
||||
}, [selectedEmbedding]);
|
||||
|
||||
// スライダー変更時の処理
|
||||
const handleChunkSizeChange = (value) => {
|
||||
if (limits && value > limits.maxChunkSize) {
|
||||
showWarning(`最大値は ${limits.maxChunkSize} です`);
|
||||
setChunkSize(limits.maxChunkSize);
|
||||
return;
|
||||
}
|
||||
setChunkSize(value);
|
||||
|
||||
// オーバーラップの自動調整
|
||||
if (chunkOverlap > value * 0.5) {
|
||||
setChunkOverlap(Math.floor(value * 0.5));
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### UI 機能
|
||||
|
||||
1. **動的なスライダー範囲**
|
||||
|
||||
```jsx
|
||||
<input
|
||||
type="range"
|
||||
min="50"
|
||||
max={limits?.maxChunkSize || 8191} // 動的な上限
|
||||
value={chunkSize}
|
||||
onChange={handleChunkSizeChange}
|
||||
/>
|
||||
```
|
||||
|
||||
2. **制限のリアルタイム表示**
|
||||
|
||||
```
|
||||
チャンクサイズ: 200 tokens (上限: 8191)
|
||||
```
|
||||
|
||||
3. **モデル情報の表示**
|
||||
|
||||
```
|
||||
モデル: text-embedding-3-large
|
||||
チャンク上限: 8191 tokens
|
||||
オーバーラップ上限: 200 tokens
|
||||
バッチ制限: 2048
|
||||
```
|
||||
|
||||
4. **最適化アドバイス**
|
||||
|
||||
```
|
||||
💡 最適化アドバイス
|
||||
• チャンクが大きすぎます (800)。検索精度に影響する可能性があります。
|
||||
• 少なくとも 80 tokens のオーバーラップを推奨します。
|
||||
• 最大値を使用すると、処理速度が低下する可能性があります。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 ユースケース例
|
||||
|
||||
### シナリオ1: OpenAI + 環境変数による制限
|
||||
|
||||
**設定:**
|
||||
|
||||
```env
|
||||
MAX_CHUNK_SIZE=4000 # モデルより厳格なカスタム制限
|
||||
```
|
||||
|
||||
**ユーザー操作:**
|
||||
|
||||
```
|
||||
1. モデル選択: text-embedding-3-large
|
||||
2. スライダー上限: 4000 (環境変数による制限)
|
||||
3. ユーザー設定: 3000 tokens
|
||||
4. バックエンド検証: ✅ 合格
|
||||
5. 実適用値: 3000 tokens
|
||||
```
|
||||
|
||||
### シナリオ2: Gemini + モデルによる制限
|
||||
|
||||
**設定:**
|
||||
|
||||
```env
|
||||
MAX_CHUNK_SIZE=8191 # 環境変数は緩和
|
||||
```
|
||||
|
||||
**ユーザー操作:**
|
||||
|
||||
```
|
||||
1. モデル選択: embedding-001
|
||||
2. スライダー上限: 2048 (モデル制限の方が厳格)
|
||||
3. ユーザー設定: 1500 tokens
|
||||
4. バックエンド検証: ✅ 合格
|
||||
5. 実適用値: 1500 tokens
|
||||
```
|
||||
|
||||
### シナリオ3: 制限超過時の自動調整
|
||||
|
||||
**ユーザー操作:**
|
||||
|
||||
```
|
||||
1. モデル選択: embedding-001 (制限 2048)
|
||||
2. ユーザー入力: 3000 tokens
|
||||
3. フロントエンド表示: "最大値は 2048 です"
|
||||
4. スライダーを自動的に 2048 に調整
|
||||
5. バックエンド記録: ⚠️ 設定修正ログ
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 優先順位ルール
|
||||
|
||||
### 上限計算ロジック
|
||||
|
||||
```typescript
|
||||
最終的な上限 = min(環境変数, モデル制限)
|
||||
|
||||
例:
|
||||
- 環境変数: 8191
|
||||
- モデル制限: 2048 (Gemini)
|
||||
- 最終上限: 2048 ✅
|
||||
|
||||
- 環境変数: 4000
|
||||
- モデル制限: 8191 (OpenAI)
|
||||
- 最終上限: 4000 ✅
|
||||
```
|
||||
|
||||
### 検証順序
|
||||
|
||||
```typescript
|
||||
1. チャンクサイズ ≤ 最終上限 かを確認
|
||||
2. チャンクサイズ ≥ 最小値 (50) かを確認
|
||||
3. オーバーラップサイズ ≤ 環境変数の上限 かを確認
|
||||
4. オーバーラップサイズ ≤ チャンクサイズの 50% かを確認
|
||||
5. オーバーラップサイズ ≥ 0 かを確認
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 デプロイ時の推奨設定
|
||||
|
||||
### 開発環境
|
||||
|
||||
```env
|
||||
# テストに適した設定
|
||||
MAX_CHUNK_SIZE=8191
|
||||
MAX_OVERLAP_SIZE=200
|
||||
```
|
||||
|
||||
### 本番環境 (OpenAI)
|
||||
|
||||
```env
|
||||
# 大容量ファイルへの対策を考慮した保守的な設定
|
||||
MAX_CHUNK_SIZE=4000
|
||||
MAX_OVERLAP_SIZE=500
|
||||
```
|
||||
|
||||
### 本番環境 (Gemini)
|
||||
|
||||
```env
|
||||
# モデルの制限に合わせた設定
|
||||
MAX_CHUNK_SIZE=2048
|
||||
MAX_OVERLAP_SIZE=300
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ メリットのまとめ
|
||||
|
||||
| 特徴 | 実装方法 | 効果 |
|
||||
|------|----------|------|
|
||||
| **安全性** | 環境変数 + モデル制限の二重保護 | API の制限を超えない |
|
||||
| **柔軟性** | 環境変数で調整可能 | 異なるデプロイ要件に対応 |
|
||||
| **ユーザー体験** | フロントエンドでの動的制限 | 無効な値を選択できない |
|
||||
| **透明性** | 制限情報をリアルタイム表示 | 設定理由が明確 |
|
||||
| **自動調整** | バックエンドでの検証・修正 | 実行時のエラーを回避 |
|
||||
| **ログ管理** | 詳細な警告情報 | 問題の切り分けがスムーズ |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 結論
|
||||
|
||||
このスキームにより、以下が実現されました:
|
||||
|
||||
1. ✅ **環境変数の設定** - グローバルに制御可能な上限
|
||||
2. ✅ **モデル制限の認識** - 異なるモデルの自動識別
|
||||
3. ✅ **フロントエンドでの制限** - 無効な値を選択不可に
|
||||
4. ✅ **バックエンド検証** - 二重の保険
|
||||
5. ✅ **自動調整** - 制限超過時の自動修正
|
||||
6. ✅ **透明なフィードバック** - 制限理由の表示
|
||||
|
||||
**これで、ユーザーがモデルの制限を超える値を選択することはなくなり、システムが自動的に保護されます!**
|
||||
Reference in New Issue
Block a user