생성형 AI를 위한 구조적 설계
생성형 AI를 위한 구조적 설계
바로 앱 서비스의 목표는 사용자들에게 “오늘 나온 법안” 을 쉽게 제공하는 것에 있습니다.
추후 업데이트에 생성형 AI를 이용하여 사용자가 더욱 쉽게 법안을 읽어볼 수 있는 기능을 제공하고자 합니다.
– 원문 –
제안이유 및 주요내용
현행법은 공직후보자에 대한 인사청문 절차를 규율하고 있으며, 인사청문 과정을 통해 공직후보자의 능력과 자질을 검증하고 투명한 인사를 도모하는 데 기여해왔음.
다만 공직후보자의 선서 의무 조항에도 불구하고, 공직후보자가 인사청문 과정에서 정당한 사유 없이 자료를 제출하지 아니하거나 답변을 회피하는 사례가 발생하고 있어 인사청문회의 본래 취지가 저해된다는 지적이 제기됨.
이에 공직후보자가 자료 제출 및 질의에 성실하게 임할 법적 의무를 규정함으로써, 인사청문회를 통한 공직 임명 과정의 실효성을 제고하려는 것임(안 제16조의2 신설).
– ai 분석 –
현행법은 공직후보자에 대한 인사청문 절차를 규정하여 후보자의 능력과 자질을 검증하고 투명한 인사를 유도하는 데 목적이 있습니다. 그러나 인사청문 과정에서 후보자가 정당한 사유 없이 자료 제출을 거부하거나 답변을 회피하는 경우가 발생하여 절차의 취지가 훼손되고 있습니다.
이를 개선하기 위해 공직후보자가 인사청문회에서 자료 제출과 질의에 성실히 임할 법적 의무를 신설하는 내용을 담고 있습니다. 제16조의2 조항을 통해 후보자의 협조 의무를 명확히 하여 인사청문회의 실효성을 높이고자 합니다.
위와 같이 기존에 딱딱하고 어려운 형식의 원문 텍스트에서 보다 이해하기 쉽게 요약한 텍스트를 제공하고자 합니다.
구조
현재 앱 내의 오늘 접수 법안은 Lambda 인스턴스와 Spring batch를 통해 이루어집니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
[cron job을 통해 특정 시간에 배치 작업 트리거]
↓
[lambda 인스턴스 시작]
↓
[오늘 접수 법안 조회]
↓
[오늘 접수 법안 가공]
↓
[db write]
↓
[사용자 알림 전송]
↓
[lambda 인스턴스 종료]
이러한 구조에서
1
2
3
4
5
6
7
8
9
...
↓
[오늘 접수 법안 조회]
↓
[+] [생성형 AI로 생성] (추가되는 항목)
↓
[오늘 접수 법안 가공]
↓
...
생성형 AI를 위한 Step 을 추가하여 AI로 요약된 항목을 제공합니다.
구현 과정
생성형 AI는 다음과 같은 특징을 갖습니다
실행 시간이 예측 불가능하고, 언제든지 실패가능하며, 요청마다 비용이 발생
따라서 생성형 AI를 서비스에 사용할 때에 이를 고려하여 최적의 파이프라인을 신중하게 구축해야 합니다.
현재 방식은 이를 두 Step으로 나누어 구현합니다.
1
[생성형 AI 요청 Step] → [생성형 AI 확인 Step] → 이후 진행...
생성형 AI 요청 Step
- 생성형 AI 요청은 Spring Batch의
Step객체로 구현됩니다.AsyncItemProcessor와AsyncItemWriter를 활용하여 생성 요청을 병렬적으로 처리합니다. - 응답 자체는 실패하지 않으나, OpenAI API 서버 상태에 따라
Timeout이 발생할 수 있습니다. - 요청 실패 시에는 Spring Batch 프레임워크가 제어하며, 지정된 횟수까지 자동으로 재시도합니다.
생성형 AI 요청 생성 완료 확인 Step
- 생성형 AI에게 보낸 요청이 실제로 완료되었는지 확인하는 단계입니다.
- 이 구간에서
생성 실패 여부를 검증할 수 있습니다. - Spring Batch의
ItemWriter/ItemProcessor를 사용하지 않고, 단일Tasklet으로 구현됩니다. - Polling 방식으로 상태를 확인하며, 미완료된 요청은 다시 큐에 넣어 추후 재검증할 수 있습니다.
1 2 3 4 5 6
[response_id를 통해 현재 상태 조회] ↓ [response.status 확인] → [생성중이면 나중에 다시 확인] ↓ [생성 완료/실패 시 수집 후 처리] ↓
왜 Chunk기반이 아닌가?
구현적 관점
Chunk 기반은 정해진 아이템을 read → process → write → commit하는 직선형 파이프라인에 적합합니다.
그러나 Polling 전략은 “미완료면 다시 큐 뒤로 넣고, 일정 간격으로 계속 순환” 하는 반복·대기·재배치 제어가 핵심입니다.
이는 Tasklet을 통해 시간 기반으로 유연하게 다룰 수 있으며, 단순하고 직관적으로 구현 및 유지 보수가 가능합니다.
비즈니스 관점
Chunk 기반은 실행 흐름이 commit-interval, retry, skip 같이 Spring batch 프레임워크의 정책에 의해 결정됩니다.
반면 Tasklet을 사용하게 된다면 polling 전략의 핵심 ( _backoff,retry, 등) 을 비즈니스 룰로 정의하여 코드로 직접 표현이 가능합니다.
Polling시 작업이 완료되지 않은 항목에 대해서 Chunk의 retry/skip은 실패(예외 발생) 를 전제로 해야 하지만, 이는 예외처리 항목이 아닌 정상적인 분기(나중에 처리해야 하는 상태) 로 구분되어야 합니다.
결론
1
2
3
4
5
6
7
8
9
10
11
RecentBillJob 시작
↓
[jobExecutionListener] : 오늘 접수된 법안 조회 (외부 API)
↓
[requestBackgroundSummaryStep] : "접수" 상태 법안 → OpenAI API 비동기 요약 요청
↓
[pollSummaryRequestStep] : response_id 기반 polling → 요약 결과 수집
↓
[writeTodayBillInfoStep] : 요약 포함하여 오늘 법안 정보 저장
↓
[notifyTodayBillStep] : 알림 전송
생성형 AI는 비용·실패 가능성·예측 불가능성이라는 특성을 갖고 있기 때문에, 단순히 기존 배치 파이프라인에 붙이는 것에 제약이 있습니다.
이에 따라 위의 구조로 요청 Step과 확인 Step을 분리합니다.
요청 Step은 병렬성과 재시도 로직을 갖춘 Spring Batch의 장점을 살리고확인 Step은 Polling 기반 Tasklet으로 유연하게 제어하는 방식으로 구현합니다.
앞으로 이런 구조를 기반으로 생성형 AI를 사용하여 다양한 새로운 기능을 추가해볼 예정입니다.
바로 앱 서비스를 google play에서 만나보세요


