From c4891823ca6976e6979a3918bebdf71f5e05ba47 Mon Sep 17 00:00:00 2001 From: Wickedness Date: Tue, 9 Jun 2026 14:34:57 +0900 Subject: [PATCH] Add LLM review request candidates --- .../Domain/VerificationModels.cs | 22 ++++++++ .../Services/PocAutomationEngine.cs | 36 ++++++++++++ .../ViewModels/MainViewModel.cs | 21 +++++++ .../ViewModels/ShellModels.cs | 9 +++ TornadoAce_CJOnStyle/Views/MainPage.xaml | 56 +++++++++++++++++++ docs/poc-requirements.md | 5 +- 6 files changed, 146 insertions(+), 3 deletions(-) diff --git a/TornadoAce_CJOnStyle/Domain/VerificationModels.cs b/TornadoAce_CJOnStyle/Domain/VerificationModels.cs index b817b2a..90781a6 100644 --- a/TornadoAce_CJOnStyle/Domain/VerificationModels.cs +++ b/TornadoAce_CJOnStyle/Domain/VerificationModels.cs @@ -29,4 +29,26 @@ namespace TornadoAce_CJOnStyle.Domain { } } + + public sealed record LlmReviewField( + string CueSheetField, + string SceneObjectName, + string ExpectedText, + string ActualText, + double MatchRate, + string Severity); + + public sealed record LlmReviewRequest( + string RequestId, + string CueSheetId, + string ProgramTitle, + string SceneName, + string PromptKey, + string Policy, + string RecommendedPriority, + IReadOnlyList Fields) + { + public string AuditSummary => + $"{RequestId} / {CueSheetId} / {RecommendedPriority} / {Fields.Count} field(s)"; + } } diff --git a/TornadoAce_CJOnStyle/Services/PocAutomationEngine.cs b/TornadoAce_CJOnStyle/Services/PocAutomationEngine.cs index 54abdc1..3eb61b0 100644 --- a/TornadoAce_CJOnStyle/Services/PocAutomationEngine.cs +++ b/TornadoAce_CJOnStyle/Services/PocAutomationEngine.cs @@ -93,6 +93,42 @@ namespace TornadoAce_CJOnStyle.Services return new PocInspectionSummary(results, passedCount, reviewCount, averageMatchRate); } + public IReadOnlyList BuildLlmReviewRequests(IEnumerable inspectionResults) + { + return inspectionResults + .Select(result => + { + var failedFields = result.FieldResults + .Where(field => field.MatchRate < 99.5) + .Select(field => new LlmReviewField( + field.CueSheetField, + field.SceneObjectName, + field.ExpectedText, + field.ActualText, + field.MatchRate, + field.Severity)) + .ToArray(); + + if (failedFields.Length == 0) + { + return null; + } + + var priority = failedFields.Any(field => field.Severity == "High") ? "High" : "Medium"; + return new LlmReviewRequest( + $"LLM-{result.CueSheetId[^3..]}", + result.CueSheetId, + result.ProgramTitle, + result.SceneName, + "cj-onstyle-cg-inspection-v1", + "사내 LLM 우선, 외부 LLM은 정책 승인 후 사용", + priority, + failedFields); + }) + .OfType() + .ToArray(); + } + private InspectionResult Inspect(CueSheetRecord cueSheet, SceneDataSnapshot snapshot, SceneTemplateDefinition template) { var expectedObjects = BuildVisibleTextObjects(cueSheet, template); diff --git a/TornadoAce_CJOnStyle/ViewModels/MainViewModel.cs b/TornadoAce_CJOnStyle/ViewModels/MainViewModel.cs index 66a5681..8cae46a 100644 --- a/TornadoAce_CJOnStyle/ViewModels/MainViewModel.cs +++ b/TornadoAce_CJOnStyle/ViewModels/MainViewModel.cs @@ -50,6 +50,7 @@ namespace TornadoAce_CJOnStyle.ViewModels LoadScheduleMatches(); LoadInspectionQueue(initialInspectionSummary.Results); LoadInspectionDetails(initialInspectionSummary.Results); + LoadLlmReviewRequests(initialInspectionSummary.Results); } private string buildPhase = string.Empty; @@ -139,6 +140,8 @@ namespace TornadoAce_CJOnStyle.ViewModels public ObservableCollection InspectionDetails { get; } = []; + public ObservableCollection LlmReviewRequests { get; } = []; + public string LoginOperatorName { get => loginOperatorName; @@ -222,6 +225,7 @@ namespace TornadoAce_CJOnStyle.ViewModels StatusCards[2].Detail = $"확인 {summary.ReviewCount}건"; LoadInspectionQueue(summary.Results); LoadInspectionDetails(summary.Results); + LoadLlmReviewRequests(summary.Results); } private void LoadStatusCards() @@ -342,6 +346,23 @@ namespace TornadoAce_CJOnStyle.ViewModels } } + private void LoadLlmReviewRequests(IEnumerable results) + { + LlmReviewRequests.Clear(); + + foreach (var request in automationEngine.BuildLlmReviewRequests(results)) + { + LlmReviewRequests.Add(new LlmReviewRequestViewModel( + request.RequestId, + request.ProgramTitle, + request.SceneName, + request.RecommendedPriority, + request.AuditSummary, + request.PromptKey, + SeverityBrush(request.RecommendedPriority))); + } + } + private void ApplySceneSnapshot(SceneDataSnapshot scene) { SceneSnapshotLabel = $"{scene.SceneName} / {scene.VisibleTextObjects.Count} text objects"; diff --git a/TornadoAce_CJOnStyle/ViewModels/ShellModels.cs b/TornadoAce_CJOnStyle/ViewModels/ShellModels.cs index ad679ab..f1c15a3 100644 --- a/TornadoAce_CJOnStyle/ViewModels/ShellModels.cs +++ b/TornadoAce_CJOnStyle/ViewModels/ShellModels.cs @@ -99,4 +99,13 @@ namespace TornadoAce_CJOnStyle.ViewModels string Severity, string Decision, SolidColorBrush SeverityBrush); + + public sealed record LlmReviewRequestViewModel( + string RequestId, + string ProgramTitle, + string SceneName, + string Priority, + string PayloadSummary, + string PromptKey, + SolidColorBrush PriorityBrush); } diff --git a/TornadoAce_CJOnStyle/Views/MainPage.xaml b/TornadoAce_CJOnStyle/Views/MainPage.xaml index 9dcde4b..b2c950a 100644 --- a/TornadoAce_CJOnStyle/Views/MainPage.xaml +++ b/TornadoAce_CJOnStyle/Views/MainPage.xaml @@ -664,6 +664,62 @@ Text="{x:Bind ViewModel.LlmPolicyDetail, Mode=OneWay}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/poc-requirements.md b/docs/poc-requirements.md index 30266bb..89ee18c 100644 --- a/docs/poc-requirements.md +++ b/docs/poc-requirements.md @@ -19,7 +19,7 @@ | RFP-04 | Tornado Scene API | Scene visible Text/Image 스냅샷 샘플 구현 | `SceneDataSnapshot.ToPreviewJson` | | RFP-05 | 큐시트 데이터와 Tornado Scene 연동 관리자 기능 | JSON 매핑 프로파일과 검증 UI 구현 | `FieldMappings`, `MappingValidations`, `ValidateMappingProfile` | | RFP-06 | 자동 검수 1단계 Text Diffing | 필드별 기대값/실제값/일치율 비교 구현 | `PocAutomationEngine.InspectWorkspace`, `InspectionFieldResult` | -| RFP-07 | 자동 검수 2단계 LLM 중요도 피드백 | LLM 검토 후보 분류와 제작자 상세 UI 구현 | 검수 결과 `Severity`, `Decision`, `InspectionDetails` | +| RFP-07 | 자동 검수 2단계 LLM 중요도 피드백 | LLM 요청 후보 payload와 제작자 상세 UI 구현 | `LlmReviewRequest`, `BuildLlmReviewRequests`, `LlmReviewRequests` | | RFP-08 | 제작자가 결과를 볼 수 있는 GUI | WinUI 3 운영 콘솔 초안 구현 | `MainPage.xaml` | ## 초기 PoC 완료 기준 @@ -36,5 +36,4 @@ - 관리자용 매핑 프로파일 편집/저장 권한 정책을 정한다. - Tornado2/Tornado3 어댑터를 동일 인터페이스로 유지하고, 버전별 구현체를 분리한다. - Scene 내부 비노출 객체를 구분할 메타데이터 규칙을 정의한다. -- 1차 검수 실패 사유를 필드 단위로 누적하고 LLM 요청 후보로 전달한다. -- LLM 요청/응답 스키마와 감사 로그 보관 정책을 별도 모델로 둔다. +- LLM 응답 스키마와 감사 로그 보관 정책을 실제 사내 정책에 맞춘다.