
콘텐츠 생성과 공개 작업을 분리하는 trusted runner 설계 - 구현 절차
요약
콘텐츠 생성과 외부 공개 작업을 분리하여 안정성을 높이는 'trusted runner' 설계 방식을 소개합니다. 상태 검증과 단계별 JSON 기록을 통해 프로세스의 재개 가능성과 데이터 무결성을 확보하는 구현 절차를 다룹니다.
핵심 포인트
- 생성 공정과 공개 공정을 분리하여 시스템 안정성 확보
- 상태를 JSON 기반의 구조화된 데이터로 기록하여 재개 지점 명시
- 완료 조건을 4단계(생성, 품질, 조작, 결과)로 세분화하여 검증
- 추측이 아닌 증거(URL, 해시 등)를 바탕으로 프로세스 제어
콘텐츠 생성과 공개 작업을 분리하는 trusted runner 설계 - 구현 절차
자동 처리는 스케줄 등록만으로는 안정적이지 않습니다. 초안을 만들 수 있었다는 것과 프로바이더 (provider) 계정을 자유롭게 조작할 수 있는 것은 별개의 문제입니다.
이 기사에서는 「구현 절차」의 관점에서 입력, 처리, 성과물, 공개 결과를 분리하는 방법을 정리합니다. 메커니즘 전체의 이유까지 다룹니다.
기본 방침
대상을 고정한 trusted runner로 요구사항, 사전 상태, 첨부, 사후 상태를 검증합니다.
프로세스가 종료되었다는 것과 목적을 달성했다는 것은 별개입니다. 초안 생성, 품질 검사, 외부 공개, 공개 URL 확인을 개별적으로 기록합니다. 상태를 분리함으로써 다음 날의 처리를 추측이 아닌 증거를 바탕으로 재개할 수 있습니다.
구현 절차
생성 공정은 로컬 성과물만을 만든다
1요구를 provider·action·title로 고정한다
공개 URL을 결과 JSON으로 재확인한다
각 공정은 다음 공정이 기계적으로 판단할 수 있는 JSON을 출력합니다. 자유 문장 로그에만 의존하면 재실행 시 어디까지 완료되었는지를 인간이 추측해야 합니다.
{"provider":"medium","action":"article_publish_v1","operator_approved":true,"allow_external_send":true}
중요한 것은 코드의 양이 아니라, 입력과 결과의 계약이 고정되어 있다는 점입니다. 성공뿐만 아니라 후보 부족이나 인증 대기 상태도 구조화하여 남깁니다.
완료 조건을 4단계로 분리
생성 완료: 본문, 메타데이터, 출처 정보가 존재함 -
품질 완료: 글자 수, 태그, 코드 예시, 중복 검사를 통과함 -
조작 완료: 허가된 runner가 대상을 한정하여 실행함 -
결과 완료: 실제 URL이나 외부 ID를 결과 파일로 확인함
중간 정지 시에는 마지막으로 통과한 단계와 다음 처리를 기록합니다. 처음부터 다시 시작하지 않고 올바른 지점에서 재개할 수 있습니다.
자주 발생하는 실패
- UI 직접 조작이 정책 검사를 우회함
- 범용 runner가 다른 상품을 변경함
- 사후 증거가 없으면 공개 여부를 추측할 수밖에 없음
재시도 횟수를 늘리기 전에 어떤 상태라면 재시도가 가능한지를 결정합니다. 외부 공개 직전에는 당일 공개 완료 여부, 제목과 본문 해시(hash)가 신규인지, 대상 초안이 이번에 작성된 것인지 확인합니다.
테스트 관점
- 동일한 입력을 2회 처리해도 후보가 중복되지 않음
- 이미 공개된 제목을 후보로 선택하지 않음
- 본문 해시 충돌 시에는 다른 각도로 전환함
- 성과물이 누락된 경우에는 성공으로 처리하지 않음
- 외부 URL이 없는 경우에는 공개 완료로 기록하지 않음
- 재고가 7건 미만으로 떨어지면 게시 전에 보충함
일일 처리의 구체적인 예
게시 시각을 10시 30분이라고 가정합니다. 2시 30분의 공급 처리에서는 단순히 Markdown 파일을 세는 것이 아니라, source_packet.json과 candidate_audit.json이 갖춰져 있고 모든 품질 체크가 참(true)인 후보만을 미공개 재고로 계산합니다. 재고가 7건 미만이라면 부족한 수만큼 다른 소재나 각도를 선택하여 로컬 생성을 수행합니다. 이 단계에서는 외부 화면을 조작하지 않습니다.
10시 30분의 공개 처리에서는 재고의 맨 앞 항목을 1건 선택합니다. 선택 후 공개된 제목과 정규화된 본문 해시를 다시 한번 읽어 들입니다. 문제가 없다면 해당 후보로부터 하나의 초안 요구를 작성하고, 저장 결과에 포함된 제목과 초안 상태를 확인합니다. 공개 요구는 방금 작성한 동일한 초안만을 대상으로 합니다. 마지막으로 실제 URL에 도달했음을 결과 JSON에 저장하여 완료합니다.
이미지 생성에 실패한 경우 본문 후보는 삭제하지 않습니다. cover_generation_failed로서 후보를 재고에 남겨둡니다. 인증이 만료된 경우에도 동일한 후보를 다시 만들지 않고 authentication_required로서 중단합니다. 공개 버튼 실행 후 확인 단계만 타임아웃된 경우에는 다음 처리에서 외부 상태를 먼저 읽고, 미공개 상태임을 증명할 수 있을 때까지 재클릭하지 않습니다.
모니터링하는 수치
일일 모니터링에서는 다음을 별도로 기록합니다.
- 보충 전과 보충 후의 미공개 후보 수
- 새로 생성한 후보 수
- 제목 중복과 본문 중복으로 제외한 건수
- 외부 조작을 시작한 건수
- 실제 URL을 확인한 건수
- 마지막으로 통과한 공정과 정지 이유
「태스크가 기동된 횟수」만을 성공 지표로 삼으면, 후보가 0건인 상태로 매일 정상 종료되는 문제를 놓치게 됩니다. 공개 URL이 필요한 레인(lane)에서는 실제 URL 확인 건수가 1이 되어야 비로소 일일 목표 달성으로 판단합니다.
재기동 후의 복구
재기동 후에는 메모리 상의 상태가 아니라 파일 결과물로부터 재개합니다. 후보 감사 (candidate audit)가 완료되어 있다면 생성을 생략하고, 초안 저장 (draft save) 결과가 있다면 새로운 초안을 만들지 않습니다. 공개 결과에 실제 URL (real URL)이 있다면 당일 처리를 종료합니다. 이 순서에 따라 PC 재부팅이나 runner 정지가 발생하더라도, 외부 조작을 중복시키지 않고 계속 진행할 수 있습니다.
테스트에는 후보 0건, 손상된 JSON, 잔류 락 (residual lock), 공개 결과 없음 등을 포함합니다. 일일 운영에서 발생하기 쉬운 상황은 예외 상황보다는 "처리는 끝났지만 목적물이 없는" 상태이기 때문입니다.
운영 체크리스트
- 입력원과 SHA-256이 기록되어 있음
- 제목과 본문의 중복 검사를 통과함
- provider와 action이 고정되어 있음
- 하루당 공개 상한을 초과하지 않음
- 결과 JSON에 실제 URL 또는 정확한 정지 사유가 있음
이러한 형태라면, 후보 생산과 공개를 독립시키면서 재고 수를 계약 (contract)으로서 연결할 수 있습니다. 게시 시점에 후보가 없다면, 공급 공정을 실행한 후 재평가합니다.
관련된 실천 사례는 AI Compass Journal의 목록에서 확인할 수 있습니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기