chunkConfigService.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // チャンク設定サービス - チャンク設定の制限の取得と検証に使用
  2. export interface ChunkConfigLimits {
  3. maxChunkSize: number; // 最大チャンクサイズ (tokens)
  4. maxOverlapSize: number; // 最大重複サイズ (tokens)
  5. defaultChunkSize: number; // デフォルトチャンクサイズ
  6. defaultOverlapSize: number; // デフォルト重複サイズ
  7. modelInfo: EmbeddingModelLimit; // モデル情報
  8. }
  9. export interface EmbeddingModelLimit {
  10. name: string; // モデル名
  11. maxInputTokens: number; // モデル入力制限
  12. maxBatchSize: number; // モデルバッチ制限
  13. expectedDimensions: number; // 期待されるベクトル次元数
  14. }
  15. export const chunkConfigService = {
  16. /**
  17. * チャンク設定の制限を取得
  18. * @param embeddingModelId 埋め込みモデルID
  19. * @param authToken 認証トークン
  20. * @returns 設定制限情報
  21. */
  22. async getLimits(
  23. embeddingModelId: string,
  24. authToken: string
  25. ): Promise<ChunkConfigLimits> {
  26. const params = new URLSearchParams({
  27. embeddingModelId,
  28. });
  29. const response = await fetch(
  30. `/api/knowledge-bases/chunk-config/limits?${params.toString()}`,
  31. {
  32. method: 'GET',
  33. headers: {
  34. 'Authorization': `Bearer ${authToken}`,
  35. 'Content-Type': 'application/json',
  36. },
  37. }
  38. );
  39. if (!response.ok) {
  40. const errorData = await response.json();
  41. throw new Error(errorData.message || 'loadLimitsFailed');
  42. }
  43. return response.json();
  44. },
  45. /**
  46. * チャンク設定が有効かどうかを検証
  47. * @param chunkSize チャンクサイズ
  48. * @param chunkOverlap 重複サイズ
  49. * @param limits 設定制限
  50. * @returns 検証結果とエラー情報
  51. */
  52. validateConfig(
  53. chunkSize: number,
  54. chunkOverlap: number,
  55. limits: ChunkConfigLimits
  56. ): {
  57. isValid: boolean;
  58. errors: string[];
  59. adjustedChunkSize: number;
  60. adjustedOverlapSize: number;
  61. } {
  62. const errors: string[] = [];
  63. let adjustedChunkSize = chunkSize;
  64. let adjustedOverlapSize = chunkOverlap;
  65. // チャンクサイズの検証
  66. if (chunkSize > limits.maxChunkSize) {
  67. errors.push(`チャンクサイズ ${chunkSize} が上限 ${limits.maxChunkSize} を超えています`);
  68. adjustedChunkSize = limits.maxChunkSize;
  69. }
  70. if (chunkSize < 50) {
  71. errors.push(`チャンクサイズ ${chunkSize} が最小値 50 未満です`);
  72. adjustedChunkSize = 50;
  73. }
  74. // 重複サイズの検証
  75. const maxOverlapByRatio = Math.floor(adjustedChunkSize * 0.5);
  76. if (chunkOverlap > limits.maxOverlapSize) {
  77. errors.push(`重複サイズ ${chunkOverlap} が上限 ${limits.maxOverlapSize} を超えています`);
  78. adjustedOverlapSize = limits.maxOverlapSize;
  79. }
  80. if (chunkOverlap > maxOverlapByRatio) {
  81. errors.push(`重複サイズ ${chunkOverlap} がチャンクサイズの50% (${maxOverlapByRatio}) を超えています`);
  82. adjustedOverlapSize = maxOverlapByRatio;
  83. }
  84. if (chunkOverlap < 0) {
  85. adjustedOverlapSize = 0;
  86. }
  87. return {
  88. isValid: errors.length === 0,
  89. errors,
  90. adjustedChunkSize,
  91. adjustedOverlapSize,
  92. };
  93. },
  94. /**
  95. * 表示用に制限情報をフォーマット
  96. */
  97. formatLimits(limits: ChunkConfigLimits): string {
  98. return [
  99. `モデル: ${limits.modelInfo.name}`,
  100. `チャンク上限: ${limits.maxChunkSize} tokens`,
  101. `重複上限: ${limits.maxOverlapSize} tokens`,
  102. `バッチ制限: ${limits.modelInfo.maxBatchSize}`,
  103. `ベクトル次元: ${limits.modelInfo.expectedDimensions}`,
  104. ].join(' | ');
  105. },
  106. };