quality.batch_evaluate
Batch evaluate quality of multiple web pages by analyzing originality, craftsmanship, and contextuality. Processes up to 100 items in background jobs with configurable error handling and weight settings.
Instructions
[DEPRECATED v0.1.0] 複数ページの品質を一括評価します。最大100件まで対応。バックグラウンドで処理され、ジョブIDで進捗確認できます。Use Loop with quality.evaluate instead.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | 評価するアイテムの配列(1-100件) | |
| batch_size | No | バッチサイズ(1-50、デフォルト10) | |
| on_error | No | エラー時の動作(skip: スキップして続行、abort: 中止) | skip |
| weights | No | 評価軸の重み付け(合計1.0) | |
| strict | No | strictモード: AIクリシェに厳しい(デフォルトfalse) |
Implementation Reference
- The handler function for the `quality.batch_evaluate` MCP tool, which manages the batch evaluation process, job queueing (Redis/BullMQ), or fallback LRU processing.
export async function batchQualityEvaluateHandler( input: unknown ): Promise<BatchQualityEvaluateOutput> { // 非推奨警告を作成・ログ出力 const deprecationWarning = createLowUsageToolDeprecationWarning("quality.batch_evaluate"); logDeprecationWarning(deprecationWarning); if (isDevelopment()) { logger.info("[MCP Tool] quality.batch_evaluate called", { hasInput: input !== null && input !== undefined, }); } // 入力バリデーション let validated: BatchQualityEvaluateInput; try { validated = batchQualityEvaluateInputSchema.parse(input); } catch (error) { if (isDevelopment()) { logger.error("[MCP Tool] quality.batch_evaluate validation error", { error }); } return { success: false, error: { code: QUALITY_MCP_ERROR_CODES.VALIDATION_ERROR, message: error instanceof Error ? error.message : "Invalid input", }, }; } // サービスファクトリーチェック(オプション) // サービスが設定されていなくても、HTMLで直接指定されたアイテムは評価可能 const hasPageIdItems = validated.items.some((item) => item.pageId !== undefined); if (hasPageIdItems && !serviceFactory) { if (isDevelopment()) { logger.warn( "[MCP Tool] quality.batch_evaluate service factory not set, pageId items will be skipped" ); } } try { // ジョブIDを生成 const jobId = crypto.randomUUID(); const createdAt = new Date().toISOString(); // アイテムを変換(indexを追加) // exactOptionalPropertyTypes対応: undefinedを除外 const items: BatchQualityItem[] = validated.items.map((item, index) => { const result: BatchQualityItem = { index }; if (item.pageId !== undefined) { result.pageId = item.pageId; } if (item.html !== undefined) { result.html = item.html; } return result; }); // Redis利用可能かチェック const redisAvailable = await isRedisAvailable(); let queueUsed = false; if (redisAvailable) { // BullMQキューにジョブを追加 const queue = createBatchQualityQueue(); try { // exactOptionalPropertyTypes対応: undefinedを除外 const jobData: Omit<BatchQualityJobData, "createdAt"> = { jobId, items, batchSize: validated.batch_size, onError: validated.on_error, strict: validated.strict, }; if (validated.weights !== undefined) { jobData.weights = validated.weights; } await addBatchQualityJob(queue, jobData); queueUsed = true; if (isDevelopment()) { logger.info("[MCP Tool] quality.batch_evaluate job added to BullMQ queue", { jobId, totalItems: validated.items.length, }); } } finally { await closeBatchQualityQueue(queue); } } // ジョブステータスを初期化してLRUストアにも保存(フォールバック時やステータス確認用) const jobStatus: BatchQualityJobStatus = { job_id: jobId, status: "pending", total_items: validated.items.length, processed_items: 0, success_items: 0, failed_items: 0, progress_percent: 0, created_at: createdAt, }; batchJobStore.set(jobId, jobStatus); // Redis未接続時は同期処理を開始(バックグラウンドで実行) if (!queueUsed) { if (isDevelopment()) { logger.info( "[MCP Tool] quality.batch_evaluate falling back to LRU store (Redis unavailable)", { jobId, totalItems: validated.items.length, } ); } // 非同期で処理を開始(awaitしない) processJobSync(jobId, items, { batchSize: validated.batch_size, onError: validated.on_error, weights: validated.weights, strict: validated.strict, }).catch((error) => { logger.error("[MCP Tool] quality.batch_evaluate sync processing error", { jobId, error: error instanceof Error ? error.message : String(error), }); }); } if (isDevelopment()) { logger.info("[MCP Tool] quality.batch_evaluate job created", { jobId, totalItems: validated.items.length, batchSize: validated.batch_size, onError: validated.on_error, queueUsed, }); } // 非推奨警告をラップしてレスポンス const responseData = { job_id: jobId, status: "pending" as const, total_items: validated.items.length, batch_size: validated.batch_size, on_error: validated.on_error, created_at: createdAt, message: `バッチ評価ジョブを開始しました。${validated.items.length}件のページを${validated.batch_size}件ずつ評価します。${queueUsed ? "(Redis/BullMQ)" : "(LRUストア)"}`, }; return { success: true, data: responseData, deprecation_warning: deprecationWarning, }; } catch (error) { if (isDevelopment()) { logger.error("[MCP Tool] quality.batch_evaluate error", { error }); } return { success: false, error: { code: QUALITY_MCP_ERROR_CODES.INTERNAL_ERROR, message: error instanceof Error ? error.message : "Batch evaluation failed", }, }; } } - The tool definition for `quality.batch_evaluate`, including the input schema and tool metadata.
export const batchQualityEvaluateToolDefinition = { name: "quality.batch_evaluate", description: "[DEPRECATED v0.1.0] 複数ページの品質を一括評価します。最大100件まで対応。" + "バックグラウンドで処理され、ジョブIDで進捗確認できます。Use Loop with quality.evaluate instead.", deprecated: true, annotations: { title: "Quality Batch Evaluate", readOnlyHint: false, idempotentHint: false, openWorldHint: true, }, inputSchema: { type: "object" as const, properties: { items: { type: "array", description: "評価するアイテムの配列(1-100件)", minItems: 1, maxItems: 100, items: { type: "object", properties: { pageId: { type: "string", format: "uuid", description: "ページID(UUID形式、htmlと排他)", }, html: { type: "string", minLength: 1, maxLength: 10000000, description: "HTMLコンテンツ(直接指定、pageIdと排他)", }, }, }, }, batch_size: { type: "integer", description: "バッチサイズ(1-50、デフォルト10)", minimum: 1, maximum: 50, default: 10, }, on_error: { type: "string", enum: ["skip", "abort"], description: "エラー時の動作(skip: スキップして続行、abort: 中止)", default: "skip", }, weights: { type: "object", description: "評価軸の重み付け(合計1.0)", properties: { originality: { type: "number", minimum: 0, maximum: 1 }, craftsmanship: { type: "number", minimum: 0, maximum: 1 }, contextuality: { type: "number", minimum: 0, maximum: 1 }, }, }, strict: { type: "boolean", description: "strictモード: AIクリシェに厳しい(デフォルトfalse)", default: false, }, }, required: ["items"], }, };