콘텐츠 오토파일럿
릴스 요청부터 9:16 MP4 렌더와 승인까지 실무자 화면에서 끝냅니다. 새로 만든 영상의 SNS 실게시는 아직 시험 중입니다
실무자가 업무툴 콘텐츠 화면에서 릴스를 요청하고, 미리보기를 본 뒤 승인하고, 배포 일정을 잡습니다. 생성에는 돈이, 게시에는 외부 노출이 걸립니다. 그래서 기본값을 모두 '하지 않는 쪽'에 뒀습니다. 게시는 수동, 반복 자동화는 dry-run(실행하는 흉내만 냄), 유료 생성은 꺼짐입니다. 단계 진행은 코드가 맡습니다.
- 다음 행동은 순수 함수가 정합니다. plan(state)가 행동 목록만 돌려주고, 실행기가 반영합니다. 단계마다 마감이 있고, 부모 이슈는 가장 이른 마감 + 1분에 깨어 감시합니다. 실패하면 재시도 없이 하위 이슈를 취소하고 닫습니다. 부모가 다른 하위 이슈는 건드리지 않습니다. 그래서 재실행해도 파이프라인이 새로 생기지 않습니다.
- 형식 오류는 한 번만 고치게 합니다. JSON 형식 오류만 수리 대상입니다. 이전 출력은 다시 보내지 않고 오류 목록(최대 8개, 각 120자)만 보냅니다. 호출은 최대 2회입니다. 수리 뒤에도 틀리면 세 번째 호출 없이 실패로 끝나는 것을 테스트로 고정했습니다.
- 출처는 실제 검색 결과만 인정합니다. 인용 URL은 웹 도구 결과나 입력에 있어야 통과합니다. 모델이 직접 쓴 근거 필드는 버립니다. 검색했다고 주장만 하면 web_research_unverified로 실패시킵니다. 상품 가격 같은 사실은 아직 프롬프트 규칙으로만 막고 있습니다.
- 결과를 모르는 게시는 다시 보내지 않습니다. POST 직전에 시작 표식을 씁니다. 보낸 뒤 오류가 나면 실패 대신 publish_pending으로 둡니다. 재시작 때 이미 게시됐으면 already_published로 닫습니다. Blotato는 제출 ID를 바로 저장해, 다시 깨어나도 상태만 조회합니다.
- 게시 슬롯은 DB가 나눠 줍니다. claim 함수가 행을 FOR UPDATE로 잠그고, 계정 advisory lock을 잡고, 하루 상한을 본 뒤 30~900초짜리 lease 토큰(잠시 빌려 쓰는 잠금 표식)을 줍니다. 앱 메모리 락은 택하지 않았습니다. 프로세스가 몇 개든 판정은 DB 한 곳에서 합니다.
- 장부 하나로 정책 두 가지를 지킵니다. LiteLLM과 Vertex 직접 경로가 같은 Redis 키에 비용을 더합니다. 직접 경로가 프록시 상한을 비켜 가던 구멍을 이렇게 막았습니다. 장부를 못 읽으면 개별 호출은 통과, 반복 자동화 시작은 보류입니다. 읽기는 쓰기 권한 없는 Redis 사용자로 합니다.
- 렌더 재시도는 마감 하나를 나눠 씁니다. LLM이 짠 모션 계획이 HyperFrames 검사에서 떨어지면 기본 템플릿으로 다시 렌더합니다. 두 시도가 마감 하나를 같이 써서, 재시도가 대기 시간을 두 배로 늘리지 않습니다. 렌더는 한 번에 하나씩 실행합니다.
- 게시할 파일은 체크섬으로 고정합니다. 게시 직전에 Drive 파일의 mime, 크기, md5, 위치를 다시 봅니다. QA 관문은 ffprobe로 60초, 1080×1920, 100MB, h264를 확인하고 AI 영상은 프레임마다 AI 표시를 찾습니다. 업로드는 8MiB씩 읽고 308 응답(이어 올리기 신호)에서 이어 올립니다.