-
Notifications
You must be signed in to change notification settings - Fork 1
Closed
Description
Claude Code + promptfoo統合テストシステムの実装(article_guardrail_review.md対象)
🎯 概要
Claude Codeのカスタムコマンド .claude/commands/article_guardrail_review.md に対するユニットテストシステムを、promptfooフレームワークを使用して実装する。有効性確認のためのPoCとして単一コマンドに特化。
📋 背景・課題
article_guardrail_review.mdコマンドの品質保証が手動で非効率- 記事レビュープロンプトの変更による回帰テストが困難
- 日付ベースのファイル参照システムのテストが複雑
- 本番運用時のレビュー品質の一貫性確保が課題
🎁 期待される効果
- ✅ article_guardrail_reviewコマンドの自動品質検証
- ✅ 日付ベースファイル参照のモック化テスト手法確立
- ✅ プロンプトエンジニアリングテストのPoCとして知見蓄積
- ✅ 他コマンドへの展開可能な基盤構築
テスト課題
- 日付動的生成:
date +%Y-%m-%dの結果に依存 - ファイル参照:
articles/weekly-ai-digest-{YYYYMMDD}.mdの存在前提 - 動的パス: 実行日により参照先が変動
モック化戦略
- プロンプト前処理: パス・コマンドの動的置換
- モックディレクトリ:
test/mock/articles/でファイル管理 - 日付固定化:
date +%Y-%m-%d→echo "2024-12-15" - パス置換:
articles/→test/mock/articles/
📋 実装タスク
Phase 1: 基本インフラ構築
-
プロジェクト初期設定
- promptfoo専用の設定(package.jsonにprompftooを追加)
- TypeScript環境の構築(tsconfig.json)
- ディレクトリ構造の作成
-
Claude Code ラッパー実装(TypeScript)
-
claude-code-test-wrapper.ts- TypeScriptベースの前処理ラッパー - プロンプト前処理ロジック(パス置換・日付置換)
- エラーハンドリング・ログ出力
-
-
promptfoo専用設定
-
promptfooconfig.yaml- メイン設定ファイル - カスタムプロバイダー設定(TypeScriptラッパー使用)
- article_guardrail_review専用テストケース定義
-
Phase 2: モック環境構築
-
テスト用記事ファイル作成
-
test/mock/articles/weekly-ai-digest-20241215.md- 正常記事サンプル -
test/mock/articles/weekly-ai-digest-20241216.md- 問題ある記事サンプル -
test/mock/articles/weekly-ai-digest-20241217.md- エッジケースサンプル
-
-
プロンプト前処理システム(TypeScript)
-
src/prompt-preprocessor.ts- プロンプト前処理ロジック -
src/claude-executor.ts- Claude Code実行ラッパー -
src/types.ts- 型定義 - パス置換:
articles/→test/mock/articles/ - 日付コマンド置換:
date +%Y-%m-%d→echo "固定日付"
-
-
ビルド・実行環境
- TypeScriptコンパイル設定
- 実行用スクリプト(
npm run build→ 実行) - 環境変数による前処理制御(
TEST_MODE,MOCK_DATE)
Phase 3: テストシナリオ実装
-
article_guardrail_reviewコマンド専用テスト
- 良い記事のレビューテスト(承認パターン)
- 問題のある記事のレビューテスト(指摘パターン)
- ファイル不存在時のエラーハンドリングテスト
- 日付フォーマット異常時の動作テスト
-
出力形式検証
- レビュー結果の構造化確認
- 改善提案の具体性確認
- ガードレール違反指摘の精度確認
Phase 4: 評価システム実装
-
カスタム評価関数実装
-
article-review-quality- レビュー品質評価 -
guardrail-detection- ガードレール違反検出精度 -
review-completeness- レビュー完全性評価
-
-
パフォーマンス・メトリクス
- レスポンス時間測定
- トークン使用量追跡
- 成功/失敗率計算
Phase 5: 運用・保守機能
-
promptfoo専用機能活用
-
promptfoo viewによる結果可視化 -
promptfoo shareによる結果共有 - テスト履歴の管理・比較
-
-
実行スクリプト整備
-
scripts/run-tests.sh- テスト実行の簡素化 -
scripts/view-results.sh- 結果表示の簡素化 - 環境変数設定の自動化
-
-
ドキュメント整備
- README.md - promptfoo中心のセットアップガイド
- TESTING.md - promptfoo実行ガイド
- MOCKING.md - モック化手法説明
-
エラーハンドリング強化
- promptfooのタイムアウト処理
- リトライ機能
- 詳細ログ出力
📁 作成予定ファイル構成
├── src/ # TypeScriptソースコード
│ ├── claude-code-test-wrapper.ts # メインラッパー(promptfoo用エントリーポイント)
│ ├── prompt-preprocessor.ts # プロンプト前処理ロジック
│ ├── claude-executor.ts # Claude Code実行ラッパー
│ └── types.ts # 型定義
├── dist/ # TypeScriptコンパイル結果
├── promptfooconfig.yaml # promptfoo専用設定ファイル
├── package.json # promptfoo + TypeScript依存関係
├── tsconfig.json # TypeScript設定
├── test/
│ ├── mock/ # モックデータディレクトリ
│ │ └── articles/
│ │ ├── weekly-ai-digest-20241215.md # 正常記事サンプル
│ │ ├── weekly-ai-digest-20241216.md # 問題記事サンプル
│ │ └── weekly-ai-digest-20241217.md # エッジケースサンプル
│ └── evaluators/ # promptfoo用カスタム評価関数(JavaScript)
│ ├── article-review-quality.js
│ ├── guardrail-detection.js
│ └── review-completeness.js
├── scripts/
│ ├── run-tests.sh # テスト実行スクリプト
│ └── view-results.sh # 結果表示スクリプト
└── docs/
├── README.md # セットアップガイド
├── TESTING.md # promptfoo実行ガイド
└── MOCKING.md # モック化手法説明
🔧 技術的実装詳細
ラッパースクリプト仕様
# 基本的な呼び出し方法(promptfooから実行)
TEST_MODE=true MOCK_DATE=2024-12-15 node dist/claude-code-test-wrapper.js "/article_guardrail_review"
# 前処理の例:
# 元: articles/weekly-ai-digest-{YYYYMMDD}.md
# ↓
# 後: test/mock/articles/weekly-ai-digest-20241215.mdpromptfoo設定例
providers:
- id: claude-code-article-review
config:
command: 'node dist/claude-code-test-wrapper.js'
tests:
- description: "正常記事のレビューテスト"
options:
transform: |
process.env.TEST_MODE = 'true';
process.env.MOCK_DATE = '2024-12-15';
return vars;
vars:
command: "/article_guardrail_review"
assert:
- type: contains
value: "test/mock/articles/weekly-ai-digest-20241215.md"TypeScript実装例
// src/prompt-preprocessor.ts
export class PromptPreprocessor {
constructor(private testMode: boolean, private mockDate: string) {}
preprocess(prompt: string): string {
if (!this.testMode) return prompt;
// パス置換: articles/ → test/mock/articles/
let processed = prompt.replace(/articles\//g, 'test/mock/articles/');
// 日付コマンド置換
processed = processed.replace(/date \+%Y-%m-%d/g, `echo "${this.mockDate}"`);
// 動的日付置換: {YYYYMMDD} → 20241215
const dateFormatted = this.mockDate.replace(/-/g, '');
processed = processed.replace(/\{YYYYMMDD\}/g, dateFormatted);
return processed;
}
}評価関数例
// ガードレール検出評価
function evaluateGuardrailDetection(output, expectedViolations) {
const violations = extractViolations(output);
const detected = violations.filter(v => expectedViolations.includes(v));
const score = detected.length / expectedViolations.length;
return { pass: score >= 0.8, score, reason: `検出率: ${score * 100}%` };
}🧪 テスト戦略
単体テスト
- モック環境でのラッパースクリプト動作確認
- promptfoo設定ファイルの妥当性検証
- 日付モック化機能の検証
統合テスト
- Claude Code + promptfoo + モック環境の連携確認
- article_guardrail_reviewコマンドの実際の実行テスト
- 各種記事パターンでのレビュー品質確認
シナリオテスト
シナリオ1: 正常記事のレビュー
- 入力: test/mock/articles/weekly-ai-digest-20241215.md (適切なAI記事)
- 期待: 承認的なレビュー結果
シナリオ2: ガードレール違反記事
- 入力: test/mock/articles/weekly-ai-digest-20241216.md (偏見・誤情報を含む記事)
- 期待: 明確な違反指摘
シナリオ3: ファイル不存在
- 入力: test/mock/articles/weekly-ai-digest-20241299.md (存在しないファイル)
- 期待: 適切なエラーハンドリング
📊 成功指標
- article_guardrail_reviewコマンドのテスト実行時間: 30秒以内
- 3つの記事パターン(正常/問題/エッジケース)でのテスト成功率: 90%以上
- 日付モック化による再現可能テストの実現
- ガードレール違反検出精度: 80%以上
- promptfoo統合によるレポート可視化の実現
🚨 注意事項・制約
- Claude Code APIキーの適切な管理が必要
- ヘッドレスモードでの実行制限を考慮
test/mock/articles/ディレクトリ内のサンプル記事の適切な作成- プロンプト前処理による置換精度の確保
- promptfooの学習コストを考慮したドキュメント整備
- セキュリティ: テスト内容がログに残ることへの配慮
📖 参考資料
- [promptfoo公式ドキュメント](https://www.promptfoo.dev/docs/)
- [Claude Code公式ドキュメント](https://docs.anthropic.com/en/docs/claude-code/)
- [promptfoo カスタムスクリプトプロバイダー](https://www.promptfoo.dev/docs/providers/custom-script/)
💭 今後の拡張可能性
- 他のカスタムコマンドへの展開(テスト手法の一般化)
- 記事品質評価アルゴリズムの改善
- リアルタイム記事監視システムへの発展
- 他のLLMとのレビュー品質比較機能
- CI/CD統合による継続的品質保証(フェーズ2として)
🏃♂️ 開始方法
このissueを/issue-task-run [issue番号]で実行開始してください。
TDD(テスト駆動開発)アプローチで段階的に実装を進めます。
Metadata
Metadata
Assignees
Labels
No labels