밤새 이슈를 조사하던 AI 봇이 보고서까지 만들고 알림을 보내는 순간 멈췄다고 가정해 보겠습니다. 다시 켜서 “계속해”라고 말할 수는 있습니다. 그런데 봇은 보고서를 또 만들어야 할까요? 알림은 이미 전송됐을까요? 대화가 남아 있다는 사실만으로는 두 질문에 답하기 어렵습니다.

Pi Durable이 다루는 문제는 이 복구 경계입니다. Pi 1.0이 사람이 터미널에서 사용하는 코딩 에이전트라면, Pi Durable은 오래 실행되는 에이전트 애플리케이션을 만드는 별도의 실험적 하네스입니다. Pi를 대체하는 새 화면이 아니라 저장과 실행을 연결하는 기반에 가깝습니다. Earendil의 발표도 두 프로젝트의 역할을 구분합니다.

여기서 durable은 ‘절대로 멈추지 않는다’보다 멈춰도 저장된 진행 지점에서 일을 다시 판단할 수 있다는 뜻으로 이해하면 쉽습니다. 프로세스를 다시 띄우는 장치만 있으면 봇은 살아나지만, 무엇을 끝냈는지 모르면 같은 일을 처음부터 반복할 수 있습니다. Pi Durable은 그 빈칸을 실행 기록으로 채우려는 라이브러리입니다. API가 예고 없이 바뀔 수 있는 실험 단계라는 조건도 도입 판단에 포함해야 합니다.

대화 기록과 실행 기록의 차이

하네스는 모델에 요청을 보내고, 모델이 선택한 도구를 실행하며, 결과를 다음 요청에 전달하는 주변 소프트웨어입니다. 여기에 복구가 필요해지면 “무슨 말을 했는가”뿐 아니라 “어떤 실행을 시작했고 어디까지 확정했는가”도 남겨야 합니다.

앞의 이슈 조사 봇을 세 단계로 나누면 차이가 보입니다. 먼저 관련 이슈를 검색하고, 결과를 보고서로 저장한 뒤, 담당자에게 링크를 보냅니다. 검색 결과를 대화에 적었다고 해서 보고서 파일이 존재하는 것은 아닙니다. “알림을 보냈습니다”라는 문장만으로 외부 서비스가 전송을 수락했는지도 증명할 수 없습니다.

복구 가능한 설계에서는 각 단계의 완료를 무엇으로 확인할지 정합니다. 검색은 결과 데이터, 보고서 저장은 파일이나 문서 식별자, 알림 전송은 외부 서비스의 응답 식별자가 후보입니다. 작업의 이름보다 완료 증거를 먼저 정하면, 재시작 뒤 같은 일을 반복할지 판단할 근거가 생깁니다.

Pi Durable은 실행을 태스크로 관리하고 진행 지점을 저장합니다. 중단된 모델 요청은 다시 보내며, 끊긴 도구 호출은 재실행이 안전하다고 선언된 경우에 다시 실행합니다. 안전하다고 선언하지 않은 호출은 중단 사실을 모델에 전달합니다. 이는 “모든 명령을 처음부터 재생한다”는 방식과 구별됩니다. 공식 복구 설명

조사 작업에 issue-report-42라는 이름을 붙여 보겠습니다. 검색 결과와 보고서 식별자가 저장됐다면 두 단계는 완료로 볼 근거가 있습니다. 알림을 호출했지만 응답이 저장되지 않았다면 마지막 단계는 ‘실패’로 확정할 수 없습니다. 완료, 진행 중, 결과 불명을 나눠야 하는 이유입니다. 불명 상태를 실패로 바꾸고 무조건 재시도하면 이미 성공한 일을 한 번 더 할 수 있습니다.

Pi Durable 공식 발표의 Survives crashes 설명으로 저장된 체크포인트에서 작업을 이어 가되 모델 요청과 도구 호출의 재실행을 다르게 처리합니다.
공식 발표의 복구 설명. 모델 요청의 재전송과 도구의 안전한 재실행을 구분합니다. 원문

중단된 검색과 중단된 알림은 다르게 취급

검색을 다시 하면 결과가 조금 달라질 수 있습니다. 그래도 외부 시스템의 상태를 바꾸지 않는 조회라면, 같은 질문을 두 번 조회하는 것이 허용되는 경우가 많습니다. 반대로 알림을 다시 보내면 같은 사람이 같은 메시지를 두 번 받습니다. 둘 다 API 호출이지만 재시도 비용과 의미는 다릅니다.

Pi Durable의 도구 정의에는 replay: "safe"라는 선언이 있습니다. 이 선언을 붙이는 일은 도구가 저절로 안전해지는 작업이 아닙니다. 작성자가 해당 도구를 다시 실행해도 되는 이유를 확인하고 하네스에 알려 주는 일입니다. 선언이 없는 중단 호출의 처리와 함께 도구 문서에 설명돼 있습니다.

이미 끝난 조사 결과는 재사용하고 중단된 검색은 안전성을 확인해 다시 실행하며 전송 여부가 불명확한 알림은 외부 기록을 확인하는 세 복구 경계
가상 이슈 조사 봇의 복구 판단. 완료 기록과 외부 효과를 각각 확인합니다.

예를 들어 보고서를 저장하는 도구도 무조건 안전한 쓰기 작업은 아닙니다. 호출할 때마다 새 문서를 생성한다면 재시도로 문서가 늘어납니다. 같은 작업 식별자로 같은 문서를 갱신하도록 만들었다면 중복 생성을 줄일 수 있지만, 동시 수정이나 버전 충돌은 별도로 다뤄야 합니다.

따라서 도구를 검토할 때는 “읽기인가, 쓰기인가”에서 한 번 더 들어가야 합니다. 같은 입력을 다시 넣었을 때 외부 결과가 어떻게 바뀌는지, 완료 여부를 조회할 수 있는지, 이미 완료된 요청을 외부 서비스가 알아볼 수 있는지가 실제 판단 기준입니다.

requestId가 해결하는 중복의 범위

요청을 보낸 클라이언트가 응답을 받기 전에 연결이 끊어지면 같은 요청을 다시 보낼 수 있습니다. Pi Durable에서는 같은 requestId로 재제출한 요청이 기존 제출을 돌려받도록 처리합니다. 아래는 공식 문서의 구조를 줄인 TypeScript 발췌입니다. root와 context는 이미 준비됐다고 가정하며, 이 코드만으로 봇이 실행되지는 않습니다. 제출과 재개 문서

TypeScript
const job = {
  type: "input",
  content: "이슈 조사 보고서를 준비해 주세요.",
  requestId: "issue-report-42",
} as const;

const submission = await root.submit(job, context);

같은 논리 요청을 다시 보낼 때는 같은 식별자를 유지해야 합니다. 반대로 내용이 다른 새 요청을 실수로 같은 식별자에 연결하지 않도록, 애플리케이션에서 요청 ID의 생성과 보존 규칙을 정해야 합니다.

중복 판별 범위는 같은 대화 안입니다. 다른 대화에 같은 문자열을 보냈다고 전체 서비스에서 하나의 작업으로 합쳐 주는 전역 ID는 아닙니다. 재시작할 때는 요청 ID뿐 아니라 어떤 대화에 제출했는지도 보존해야 합니다. 공식 제출 명세

여기서 요청 중복 방지와 외부 작업 중복 방지는 분리해서 봐야 합니다. 외부 알림 서비스가 메시지를 수락한 직후 프로세스가 죽었다면, 로컬 저장소에는 성공 응답이 기록되지 않았을 수 있습니다. 하네스 안의 제출이 하나라는 사실은 외부 전송의 결과를 알려 주지 않습니다.

예를 들어 알림 서비스에 issue-report-42-notice라는 중복 방지 키를 보냈다고 가정하겠습니다. 재시작 뒤 같은 키를 다시 보냈을 때 서비스가 이전 전송 결과를 돌려준다면, 알림을 두 번 만드는 일을 피할 수 있습니다. 반대로 그런 기능도 전송 조회도 없다면 ‘전송 여부 미확인’으로 남겨 확인을 요청하는 쪽이 맞습니다. 키의 유효 기간과 적용 범위도 서비스마다 다르므로, 문자열 하나를 붙였다는 사실만으로 보장이 완성되지는 않습니다.

Pi Durable 내부에서는 대화 항목·상태 문서·다음 태스크를 하나의 commit에 저장할 수 있습니다. 이때 전부 반영되거나 전부 반영되지 않는 성질을 원자성이라고 합니다. 하지만 이 저장과 외부 알림 서버의 전송은 별개입니다. 내 기록의 일관성과 외부 세계의 결과를 맞추는 일은 남아 있습니다. 공식 Concepts 설명

이 틈을 다루는 설계로는 외부 API의 중복 방지 키, 작업 ID로 전송 결과를 조회하는 기능, 결과가 불명확할 때 사람에게 확인을 맡기는 절차가 있습니다. 어떤 방법이 가능한지는 연결한 서비스에 달려 있습니다. 결제·배포·메시지 전송을 한데 묶어 “정확히 한 번 실행”이라고 소개하면 이 차이가 가려집니다.

핵심 비교
구분역할설명예시
요청 제출같은 요청인지 식별클라이언트의 재전송을 기존 제출에 연결합니다.같은 requestId로 재제출
도구 실행다시 실행해도 되는지 판단도구의 외부 효과와 재실행 선언을 함께 검토합니다.검색 재조회와 알림 재전송 구분
외부 결과실제 완료 여부 확인외부 서비스의 기록이나 중복 방지 기능이 필요할 수 있습니다.전송 식별자로 결과 조회

저장소를 골랐다고 모든 장애가 해결되지는 않음

공식 README의 간단한 시작 예제는 메모리 저장소를 사용합니다. 하지만 프로세스 종료 뒤 복구를 검토한다면 SQLite나 JSONL처럼 데이터를 남기는 저장소가 필요합니다. 메모리에만 있던 상태는 프로세스와 함께 사라집니다. 저장소 문서

같은 문서는 SQLite의 WAL·synchronous = NORMAL 조건도 밝힙니다. 프로세스 충돌을 견디는 것과 전원·호스트 장애에서 마지막 기록까지 보존하는 것은 같은 보장이 아닙니다. 저장소는 한 번에 한 프로세스가 소유하며 교차 프로세스 잠금도 제공하지 않는다고 설명합니다.

이 조건은 컨테이너 운영에서 중요해집니다. 데이터 파일을 임시 디스크에 두면 새 컨테이너가 이전 기록을 찾지 못할 수 있습니다. 같은 파일을 두 인스턴스가 동시에 열도록 구성하면, 재시작을 구현하려다 다른 종류의 상태 충돌을 만들 수도 있습니다. 복구 기능을 검토할 때에는 저장 위치, 소유 프로세스, 백업과 장애 종류를 함께 적어야 합니다.

또 하나의 경계는 파일과 대화의 차이입니다. 실행 기록을 복구했다고 작업 디렉터리의 모든 파일이나 원격 머신까지 이전 시점으로 돌아오는 것은 아닙니다. 보고서 파일이 별도 저장소에 있다면 그 파일의 존재와 버전도 확인해야 합니다. 하네스의 저장과 도구 실행 환경의 저장을 한 덩어리로 취급하지 않는 편이 안전합니다.

이 차이를 잘 짚은 개발자 토론에는 ‘에이전트는 브라우저의 다음 페이지까지 갔다고 기억하는데, 새 실행 환경의 브라우저는 처음 화면이면 어떻게 하는가’라는 질문이 있습니다. 제작자의 답변도 실행 환경의 상태 보존은 에이전트 설계에 달려 있다고 구분합니다. 복구 기능이 브라우저·가상 머신의 현재 상태까지 자동으로 맞춰 준다고 읽어서는 안 됩니다.

조사 봇이 웹 화면으로 보고서를 올리는 경우라면, 재시작 후 먼저 로그인 상태와 현재 URL, 보고서의 존재를 확인하게 설계할 수 있습니다. 보고서가 있으면 그 식별자를 회수하고, 없다면 보존한 파일로 업로드 단계부터 다시 시작합니다. 좌표를 기억해 같은 버튼을 누르는 것보다 원하는 결과가 이미 있는지 조회하는 도구가 복구 판단에 도움이 됩니다. 이는 이 사례의 설계 제안이며 Pi Durable의 자동 기능은 아닙니다.

도구 권한도 별도 선택입니다. 공식 README의 CodingTools는 registry에 설치하는 확장이며, 대화별로 제공할 도구를 선택할 수 있습니다. 이슈 조사만 하는 봇에 파일 쓰기나 셸 실행을 모두 줄 필요는 없습니다. 다만 도구를 제한하는 설정과 운영체제 수준의 격리는 다른 문제이므로, 실행 환경은 Environment 문서와 함께 설계해야 합니다.

도입 검토는 성공 시연보다 중단 지점에서 시작

이슈 조사 봇을 평가한다면 같은 정상 요청을 여러 번 성공시키는 것보다, 중단 위치를 바꿔 보는 편이 복구 설계를 잘 드러냅니다. 다음은 구현 후 수행할 검증 시나리오이며 실행 결과가 아닙니다.

복구 설계를 확인할 세 중단 지점
  1. 검색 도중 종료다시 켠 뒤 검색이 어떻게 이어지는지, 중복 요청이 과도하게 늘지 않는지 확인합니다.
  2. 보고서 저장 직후 종료같은 작업이 새 보고서를 중복 생성하지 않는지, 저장된 문서를 다시 찾는지 확인합니다.
  3. 알림 수락 직후 종료성공 응답을 잃었을 때 전송 결과를 조회하거나 확인을 요청하는지 살펴봅니다.

비교할 증거는 최종 답변만이 아닙니다. 제출 ID, 도구 호출 기록, 보고서 식별자, 외부 전송 기록을 함께 봐야 합니다. 모델이 “복구했습니다”라고 답해도 외부 문서가 두 개 만들어졌다면 기대한 복구가 아닙니다.

이 사례의 합격 조건은 구체적으로 정할 수 있습니다. 같은 제출을 다시 보내도 작업 ID가 유지되고, 작업 42에 연결된 보고서는 하나이며, 알림은 한 번만 확인되거나 전송 여부 미확인으로 멈춰야 합니다. 실패 기록에는 중단 위치와 재시작 후 실제 도구 호출을 남깁니다. 그러면 ‘복구 성공’이라는 문구 대신 어떤 보장이 성립했는지 검토할 수 있습니다.

사람의 재개 지시를 줄이고 싶은 팀에게

Pi Durable은 밤새 작업하는 조사 봇, 여러 대화에서 요청을 받는 도구, 중간 결과를 보존해야 하는 에이전트 서비스를 검토할 때 의미가 있습니다. 반면 짧은 작업을 사람이 옆에서 실행하고 실패하면 다시 시작해도 충분한 환경이라면, 저장·복구 설계가 먼저 필요한지부터 따져볼 수 있습니다.

선택 기준은 “얼마나 오래 돌아가나”보다 “멈추면 어떤 결과를 잃고 어떤 작업이 중복되는가”에 있습니다. 처음의 이슈 봇이라면 검색을 재개하는 능력만큼 알림을 함부로 다시 보내지 않는 판단이 중요합니다. Pi Durable을 도입하는 일은 그 판단을 없애는 일이 아니라, 도구별 복구 규칙을 코드와 기록으로 옮기는 일입니다.

VIEW—

© Chacolate. 일부를 인용할 때는 글 제목과 원문 링크를 함께 표시해 주세요. 무단 전재·재배포는 허용하지 않습니다.