Repository navigation
[AI Run] 비동기 실행 상태·재시도·멱등성 구현 #24
Copy link
Copy link
Labels
area:ai-integrationServer ↔ AI Runtime 내부 계약·Client·검증·trace 연동 영역; Prompt·모델·Provider 구현은 ai 저장소 소유Server ↔ AI Runtime 내부 계약·Client·검증·trace 연동 영역; Prompt·모델·Provider 구현은 ai 저장소 소유area:serverSpring Boot API·도메인·DB·tenant·Task Workflow 영역; Prompt·모델·Provider 구현 제외Spring Boot API·도메인·DB·tenant·Task Workflow 영역; Prompt·모델·Provider 구현 제외priority:P0MVP 진행을 막는 최우선 핵심 작업MVP 진행을 막는 최우선 핵심 작업security:privacy개인정보·접근권한·토큰·보안 영향이 있는 작업개인정보·접근권한·토큰·보안 영향이 있는 작업status:in-progress담당자가 현재 구현 중인 작업담당자가 현재 구현 중인 작업type:feature사용자 또는 Agent가 사용하는 기능 개발사용자 또는 Agent가 사용하는 기능 개발
Description
한 줄 목표
AI 분석을 Server DB에 남는 AiRun으로 관리하고, HR이 채택한 Candidate만 Case와 Task로 만드는 기능입니다.
쉽게 말하면: AI가 제안서를 만들고, 담당자가 선택한 제안만 실제 업무카드가 됩니다.
사용자 흐름
POST /api/v1/ai-runs가 발화문을 저장하고202 + aiRunId반환- Server가 [AI Integration] AiRuntimeClient·계약 검증·장애 격리 구현 #8
AiRuntimeClient로 PLAN 요청 - 필요한 DB Slot은 [AI Run][P0] Agent 요청 Slot 조회·재호출 오케스트레이션 구현 #74 Resolver가 조회하고 ANALYZE 재호출
- 누락정보가 있으면 HR이
answersAPI로 답변 - 검토할 Candidate가 준비되면 HR이 채택 또는 폐기
- 채택된 Candidate만 [Case][P0] Case·Workflow Snapshot·업무함 Projection 구현 #83 Case와 기존 연장 Task가 됨
- 승인·근로자 발송·외부 제출은 별도 기능으로 처리
현재 main에 구현됨
-
POST /api/v1/ai-runs -
GET /api/v1/ai-runs/{aiRunId} -
POST /api/v1/ai-runs/{aiRunId}/answers - AiRun·AiAttempt·Question·Candidate 저장
- 생성 요청
Idempotency-Key와 payload 충돌 검사 - PLAN → Slot 해결 → ANALYZE 재호출
- tenant 권한·낙관적 버전·감사로그
- Case 조회와 Workflow Snapshot 기반 — [Case][P0] Case·Workflow Snapshot·업무함 Projection 구현 #83
지금 먼저 구현할 MVP 범위
Candidate 결정 API
POST /api/v1/ai-runs/{aiRunId}/candidate-decisions
- Header:
Idempotency-Key - Body:
expectedRunVersion,decisions[] - action:
ACCEPT또는DISCARD ACCEPT: Server가 업무 규칙을 다시 검증한 뒤 Case와 Task 생성DISCARD: Candidate를 삭제하지 않고 결정 이력 보존- 같은 요청을 다시 보내도 Case·Task 중복 생성 금지
고정 데모 Task
EXPIRY_RENEWAL Candidate를 채택하면 새 Task 유형을 늘리지 않고 이미 정의된 다음 3개를 사용합니다.
- 재계약
- 취업활동기간 연장
- 체류기간 연장
전체 Intent 업무 유형 확장은 #85 M4/P1에서 처리합니다.
고정 데모의 Workflow 확장 규칙
현재 AI Runtime은 Candidate 하나에 workflowId 하나를 반환합니다. 반면 Server Catalog의 EXPIRY_RENEWAL은 두 Workflow와 세 Task 유형으로 구성됩니다.
detectedIntent = EXPIRY_RENEWAL
├─ WF-CON-001 → RECONTRACT, EMPLOYMENT_PERIOD_EXTENSION
└─ WF-STY-001 → STAY_PERIOD_EXTENSION
MVP에서는 HR이 EXPIRY_RENEWAL Candidate를 채택하면 Server가 WorkflowCatalog.findByIntent로 활성 Workflow를 조회하고 위 세 Task를 만듭니다.
- AI의
workflowId는 대표·검증 정보로 보존 detectedIntent와 Candidate Workflow가 Catalog에서 연결되지 않으면422- Workflow ID와 TaskType을 Controller나 if문에 하드코딩하지 않음
- Catalog가 허용한 Workflow와 TaskType만 생성
- 수동 Task 생성 경로를 세 번 단순 호출하지 않음
- 복합 Case 전용 생성 서비스가 세 Task와 전체 Snapshot을 한 Transaction에서 저장
현재 JdbcTaskCaseRegistrar는 수동 Task 하나의 Snapshot만 만들기 때문에, Candidate 연결에서는 전체 단계 Snapshot을 받는 별도 Port 또는 복합 등록 메서드가 필요합니다.
MVP 완료 조건
- CandidateDecision 저장 구조와 Repository
- ACCEPT 또는 DISCARD 권한·상태·
expectedRunVersion검증 - Candidate 채택 시 [Case][P0] Case·Workflow Snapshot·업무함 Projection 구현 #83 Case와 3개 연장 Task를 한 Transaction에서 생성
- 같은 Idempotency-Key 재전송 시 동일 결과 반환
- 다른 payload에 같은 key 사용 시
409 - 일부 Candidate만 선택 가능하고 선택되지 않은 후보는 자동 승인하지 않음
- 감사로그에 결정자·시각·결과·생성된 caseId/taskIds 기록
- 정상·중복·버전 충돌·타 사업장 접근 통합 테스트
- OpenAPI 요청·응답·409/422 예시
후속 안정화 범위
MVP Candidate 연결 후 이어서 처리합니다.
-
POST /api/v1/ai-runs/{aiRunId}/retry - 실패한 Run의 새 AiAttempt 생성
- [Reliability] 이벤트 유실 방지·재처리 기반 구현 #25 durable event 기반 재시작 복구
- 멈춘
RUNNINGlease·timeout 복구 - retry budget과 terminal error 구분
상태 구분
| 종류 | 예시 | 의미 |
|---|---|---|
| AiRun status | RUNNING, SUCCEEDED, FAILED |
Server 실행 상태 |
| analysisOutcome | NEEDS_INFO, REVIEW_REQUIRED |
HR의 다음 행동 |
| Task status | DRAFT, READY_FOR_REVIEW |
생성된 업무 상태 |
누락정보나 모호성은 기술 실패가 아닙니다. Candidate 채택도 승인이나 발송이 아닙니다.
작업 경계
- [Document][P0] 문서 상세 조회·상태 표현·HWP/HWPX 업로드 보완 #80·PR #91의 Document Entity·Repository·Flyway는 수정하지 않음
- [Worker][P0] E-9 업무용 4개 날짜·비자정보 확장 #84 Worker 날짜·비자 필드는 수정하지 않음
- Prompt·Provider·Agent Pipeline은
fowoco/ai소유 - 전체 Intent Task 확장은 [Task][P1] 전체 Intent 업무 유형·사업장 공통 대상 확장 #85
- 실제 Runtime smoke는 [AI Integration] AiRuntimeClient·계약 검증·장애 격리 구현 #8
- Parent: [EPIC] FOWOCO Server Roadmap · Controlled AI Workflow MVP #2
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:ai-integrationServer ↔ AI Runtime 내부 계약·Client·검증·trace 연동 영역; Prompt·모델·Provider 구현은 ai 저장소 소유Server ↔ AI Runtime 내부 계약·Client·검증·trace 연동 영역; Prompt·모델·Provider 구현은 ai 저장소 소유area:serverSpring Boot API·도메인·DB·tenant·Task Workflow 영역; Prompt·모델·Provider 구현 제외Spring Boot API·도메인·DB·tenant·Task Workflow 영역; Prompt·모델·Provider 구현 제외priority:P0MVP 진행을 막는 최우선 핵심 작업MVP 진행을 막는 최우선 핵심 작업security:privacy개인정보·접근권한·토큰·보안 영향이 있는 작업개인정보·접근권한·토큰·보안 영향이 있는 작업status:in-progress담당자가 현재 구현 중인 작업담당자가 현재 구현 중인 작업type:feature사용자 또는 Agent가 사용하는 기능 개발사용자 또는 Agent가 사용하는 기능 개발
Activity
[-][AI Runtime] 비동기 AI Run 상태·재시도·멱등성 구현[/-][+][AI Run] 비동기 실행 상태·재시도·멱등성 구현[/+]hywznn commentedon Aug 6, 2026
2026-08-06 상태 갱신
PR #82로 AiRun 생성·조회·질문 답변과 실행 이력이 main에 반영됐고, PR #88로 Case·Workflow Snapshot 기반도 준비됐습니다.
이제 바로 진행할 핵심 범위는 다음입니다.
POST /api/v1/ai-runs/{aiRunId}/candidate-decisions외부 계약을 기다리지 않고 Fake Runtime으로 candidate decision을 구현할 수 있어
status:in-progress로 변경합니다.