Pi 1.0은 무엇을 더하고 무엇을 끝내 넣지 않았나, 코드모드와 Pi Durable
Pi 1.0 출시 글과 함께 공개된 Pi Durable, MCP 편입 글을 묶어 미니멀 에이전트 하니스가 기능을 받아들이는 기준과 장시간 에이전트의 내구성 설계를 정리한다.
TL;DR
- Earendil은 Pi 1.0을 하드닝을 마친 미니멀 에이전트 하니스로 출시했다. 코드모드, 가상 모델 확장, 지연 도구 로딩, Anthropic 캐시 워밍, 대화 중간 시스템 메시지, 새 TUI 테마와 기본 전체 화면을 더했다. 기준은 검증된 뒤에만 받아들인다는 원칙이다.
- 그동안 MCP를 거부하던 Pi가 코어에 MCP를 넣은 이유는 MCP가 달라진 것만이 아니다. 지연 로딩이나 코드모드 전용 도구 같은 변경이 어차피 범용적으로 유용했기 때문이라고 밝힌다. 코드모드는 하니스 쪽에서 도는 JavaScript 샌드박스다.
- 같은 날 실험용으로 공개한 Pi Durable은 코딩 에이전트를 대체하지 않는 별도 패키지다. 단말기 밖에서 오래 돌고, 프로세스가 죽어도 이어지고, 여러 사람이 함께 조종하는 에이전트 앱의 기반을 노린다.
- 내구성의 핵심은 모든 단계를 체크포인트가 있는 태스크로 저장하는 것이다. 죽은 뒤 새 프로세스가 같은 저장소를 열면 미완료 태스크를 마지막 체크포인트부터 이어 간다. 다시 실행해도 안전한 도구만 재실행한다.
- Pi Durable은 실험 단계라 API가 바뀔 수 있고 TypeScript로만 구현됐다. 글의 성능과 안정성 주장은 자사 설명이며 독립 검증이 아니다.
1.0이 더한 것과 받아들이는 기준
Earendil은 Pi 1.0을 하드닝되고 미니멀하며 확장 가능한, 각자 자기 것으로 만들 수 있는 에이전트 하니스로 소개한다. 매주 수십만 명이 쓰고 많은 사용자가 이슈와 풀 리퀘스트를 보냈으며 수개월에 걸친 피드백으로 Pi를 안정적으로 다듬었다고 한다. 수십만이라는 이용자 규모는 회사의 자체 설명이다.
이 글에서 가장 분명한 태도는 기능을 받아들이는 기준이다. 에이전트 도구는 매주 바뀌고 그 변화의 상당수는 오래가지 않는다. Pi는 무엇이 실제로 검증될 때까지 기다렸다가, 그 기능의 실제 쓸모를 본질적으로 따라오는 복잡도와 저울질한 뒤에야 채택한다. 1.0에 들어간 항목은 코드모드(MCP 기본 지원과 Jev 및 이미지 모델 같은 비 LLM 모델 지원), 가상 모델을 위한 확장 지원, 지연 도구 로딩, Anthropic 모델용 캐시 워밍, 대화 중간 시스템 메시지, 새 TUI 테마, 기본 전체 화면 모드다.
저자들은 이 기능들을 몇 달 동안 고민했고 벽에 던져 붙은 것만 남았다고 말한다. 떨어져 나간 목록이 훨씬 길다는 설명도 덧붙인다. 전부 쓰면 큰 진전으로 느껴지면서도 여전히 Pi답게 단순하다는 것이 그들의 평가이며 이는 개발자의 체감이라서 외부에서 확인된 사실은 아니다.
거부하던 MCP를 코어에 넣은 이유
같은 주에 올라온 글은 “MCP는 안 된다고 했잖아요”라는 반응에 답한다. pi.dev에는 Pi가 MCP를 지원하지 않는다는 선언이 있었고 Mario의 글과 팟캐스트 발언도 MCP에 회의적이었다. 저자들의 설명은 세상이 정지해 있지 않다는 것이다. 지난 1년 동안 MCP를 지켜봤고 오늘의 MCP는 과거의 MCP와 다르다.
다만 그것만으로는 코어에 넣을 이유가 되지 않는다. 확장으로도 가능했고 실제로 확장으로 존재했다. 코어로 들어온 결정적 이유는 MCP를 위해 필요한 변경이 일반적으로 유용했다는 데 있다. 예를 들어 같은 변경이 Jev를 Pi 안에서 쉽게 쓰게 해 준다. 저자들은 Pi가 필요로 하는 것과 MCP가 필요로 하는 것이 비슷하다고 본다. 둘 다 인터프리터 형태의 샌드박스다.
MCP가 여전히 풀지 못한 문제도 적는다. 가장 큰 것은 조합의 어려움이다. 많은 MCP 서버는 도구를 컨텍스트에 그대로 쏟아붓는 하니스를 전제로 만들어졌고 토큰 효율을 위해 텍스트를 돌려준다. 저자들은 MCP가 지능적인 도구 발견을 갖춘 OpenAPI에 더 가까워야 한다고 본다. 도구는 구조화된 데이터를 돌려주고 문서와 설명으로 발견할 수 있어야 한다는 것이다. CLI가 유용한 까닭은 에이전트가 효율적인 셸 조합으로 이어 붙이기 때문인데, MCP도 못 할 이유가 없다는 입장이다.
코드모드 없이 MCP만 붙이지 않은 이유는 Pi의 도구 구성 방식과 관련이 있다. 최근 몇 달 동안 지연 도구 로딩, 대화 중간 시스템 메시지, 추론 수준 변경을 지원하는 새 모델에 맞추도록 Pi를 고쳤지만 도구 구성은 아직 이 기능들에 맞게 올리지 못했다. 코드모드 세계에서는 도구를 LLM에 직접 보일지, 코드모드 쪽에만 보일지 정해야 한다. 일반 MCP 확장은 그 결정에 필요한 메타데이터를 Pi의 도구 구성에서 받지 못한다. 그래서 도구를 지연 로딩이나 코드모드 전용으로 설정할 수 있게 코어를 고쳤고 저자들은 영향을 주려면 끌어안는 편이 낫다고 판단했다.
코드모드는 하니스 쪽에서 도는 샌드박스다
하니스가 도구를 실행하는 곳은 두 군데다. bash가 도는 곳과 하니스의 에이전트 루프가 도는 곳이며 신뢰 수준이 다르다. 루프는 대체로 신뢰할 수 있는 환경에서 돌고 도구는 신뢰하기 어려운 샌드박스 안에서 돈다. 코드모드는 하니스가 도는 곳에서 실행되며 도구 호출을 조율하는 장치로 이해하면 된다. 에이전트가 호출 순서를 유연하게 정하고 JavaScript로 결과를 엮게 해 준다.
하니스 쪽에서 돌기 때문에 상태는 파일 시스템이 아니라 세션 트랜스크립트에 남는다. 원리상 어떤 언어든 가능하지만 JavaScript는 작은 구현을 WASM 바이너리로 배포할 수 있어 적절한 수준의 보호를 얻기 좋다. Pi에서는 MCP를 설정하면 코드모드가 자동으로 로드되고 기본 도구로 추가할 수도 있다.
글의 예시는 Linear MCP와 TypeSafe의 결정 모델 Jev를 엮어 이슈 트래커에서 가장 짜증 난 댓글러를 찾는 작업이다. 에이전트가 열린 이슈를 모두 가져와 Jev에게 이슈 작성자들의 감정 톤을 판정시키고 네 개씩 병렬로 돌려 결과를 코드모드에 저장한다. 이 예시 세션에서는 열린 이슈 167건 중 156건이 중립, 11건이 가벼운 불만이었고 강한 분노는 없었다. 컨텍스트를 거의 쓰지 않고 분석을 끝낸다는 점이 요지다. 이 결과는 글이 보여 준 압축 재생 화면의 시연 값이며 성능이나 정확도를 검증한 실험이 아니다.
Pi Durable이 별도 패키지인 이유
Pi 1.0을 다듬으면서 Earendil은 Pi에 맞지 않는 사용 방식이 있다는 것을 알게 됐다. 코딩 에이전트는 내 (원격) 머신의 터미널 안에서 한 사람이 조종하도록 만들어졌고 프로세스가 죽으면 사람이 상황을 보고 계속하라고 말하면 된다. 1.0은 그 사용에 집중하며 그 점은 바뀌지 않는다. 하지만 Earendil은 이 기술을 코딩 밖으로, 터미널 밖으로 가져가고 싶어 한다. 어디서나 돌고 여러 표면에서 접근되고 끝없이 긴 대화를 지원하고 치명적인 내부 및 외부 실패에서 살아남고 여러 사람이 같은 에이전트를 조종하는 하니스가 필요하다.
그래서 Pi를 억지로 그런 것으로 만들지 않고 새 실험 패키지로 분리했다. Pi Durable은 코딩 에이전트를 대체하지 않고 코딩 에이전트를 포함한 모든 에이전트 앱을 만들 프레임워크다. pi-ai 같은 코드와 미니멀리즘, 가변성이라는 원칙을 Pi와 공유한다. 여기서 쌓은 교훈이 검증되면 코딩 에이전트로 되돌려 보낸다는 계획이다. 소스는 테스트를 빼고 약 15,000줄이고 토큰으로는 GPT 기준 약 15만, Claude 기준 약 25만이라고 하는데, 이는 최악의 경우이며 저장소 백엔드만 3,000줄이라 대개 건너뛸 수 있다. 에이전트가 이해할 수 있는 크기로 만든다는 설계 의도다.
글은 하니스를 이렇게 정의한다. 하니스는 저장소와, 여러 LLM 대화를 병렬로 돌리는 데 필요한 기계장치, 그리고 모델이 부르는 도구와 그 도구가 돌 실행 환경을 합친 것이다. 대화는 트랜스크립트로 기록되는 사람과 에이전트의 상호작용이고 에이전트는 LLM에 추론 수준 같은 설정과 호출 가능한 도구를 더한 것이다. 모델 호출부터 도구 실행까지 하니스가 돌리는 모든 것이 태스크다.
체크포인트와 소유권 트리로 만든 내구성
내구성은 모든 단계를 체크포인트를 저장하는 태스크로 만드는 데서 나온다. 프로세스가 죽으면 새 프로세스가 같은 저장소를 열어 끝나지 않은 태스크를 찾고 마지막 체크포인트부터 각각 이어 간다. 끊긴 모델 요청은 다시 보내고 부분 답변은 중단 표시가 붙은 채 트랜스크립트에 남는다. 끊긴 도구 호출은 안전하다고 선언된 경우에만 재실행하고 그렇지 않으면 모델에게 호출이 중단됐다고 알린다. 글의 예로 조회만 하는 검색 도구는 재실행이 안전하지만 배포 도구는 재실행 없이 모델에게 보고된다. 요청 ID를 붙인 제출은 정확히 한 번만 처리되므로, 충돌 뒤 재시도한 클라이언트는 질문이 두 번 들어가는 대신 원래 제출을 돌려받는다.
같은 하니스에서 많은 대화를 동시에 돌릴 수 있고 대화는 새로 시작하거나 다른 대화의 트랜스크립트 중간에서 분기한다. 분기한 대화는 복사 없이 부모의 이력을 그 지점까지 본다. 글의 비유는 에이전트가 멘션에 답하는 슬랙 채널이다. 채널 전체를 하나의 대화로, 스레드를 그 메시지에서 분기한 대화로 두면 둘이 서로 막지 않고 동시에 돈다. 대화마다 모델, 추론 수준, 선택한 확장과 활성 도구, 추가 지시, 작업 디렉터리를 따로 저장하므로 옆에서 검토하는 에이전트에 더 저렴한 모델과 읽기 전용 도구를 줄 수 있다.
태스크와 대화는 하나의 소유권 트리를 이룬다. 태스크를 중단하면 그것이 소유한 것을 아래에서 위로 중단하고 각 태스크가 자신의 부작용을 먼저 정리한 뒤 끝난다. 글의 결제 예시가 이를 잘 보여 준다. 여러 카드로 나눠 결제하는 체크아웃에서 한 카드가 거절되면 나머지 결제가 중단되면서 스스로 환불한다. 서브에이전트도 같은 패턴이다. 호출한 도구가 소유하는 하나의 대화이므로 충돌에서 살아남고 비용을 따로 세며 UI가 호출 아래에 보여 줄 수 있다. 태스크는 기본이 포그라운드라서 사용자가 Esc로 대화를 중단하면 함께 중단되고 백그라운드 태스크는 대화에 속하지만 현재 작업에는 속하지 않아 일반 중단이 건드리지 않는다.
확장, 컴팩션, 문서, 다중 사용자
확장은 시스템 프롬프트 섹션과 도구, 훅, 태스크를 묶은 이름 있는 꾸러미다. 시스템 프롬프트는 요청마다 확장의 섹션으로 다시 만들어지고 바뀐 내용은 트랜스크립트의 변경 위치에 기록된다. 그래서 재시작이나 분기가 모델이 본 것과 똑같이 재현된다. 대화 중간의 시스템 및 도구 변경을 지원하는 모델에서는 바뀐 부분만 보내 프롬프트 캐시를 유지한다. 훅은 모델 응답 생성, 도구 호출, 컴팩션 같은 내장 태스크에 끼어들어 요청을 고치거나 도구 호출을 막거나 결과를 바꿀 수 있고 충돌 뒤 다시 실행될 수 있으므로 결정을 메모에 저장한다.
컴팩션도 태스크다. 컨텍스트가 모델 한계에 가까워지면 백그라운드 컴팩션이 오래된 메시지를 요약하고 요약은 다음 턴 경계에 들어간다. 다음 요청이 들어가지 않을 때만 대화가 요약을 기다린다. 오래된 메시지는 저장소에 항상 남는다. 리셋은 인계 메모로 새 컨텍스트를 시작하는 더 강한 수단이고 이전 메시지가 삭제되지 않으므로 다른 도구가 인계 이전 내용을 검색할 수 있다. 할 일 목록이나 계획, 티켓 같은 애플리케이션 상태는 트랜스크립트 옆에 저장되는 타입이 있는 JSON 문서에 두어, 같은 원자적 커밋으로 바뀌므로 트랜스크립트와 어긋나지 않는다.
레지스트리는 대화가 도는 동안에도 바뀔 수 있다. 같은 이름의 확장을 설치하면 한 번에 교체되고 이미 도는 도구 호출은 시작한 코드로 끝나며 다음 호출부터 새 코드를 쓴다. 다중 사용자 쪽은 UI에 필요한 모든 것이 커밋된 상태라는 데서 나온다. 몇 명이든 어떤 대화에나 붙어 현재 뷰를 받고 이후 바뀐 부분만 받으며 어느 클라이언트든 실행 중인 대화를 조종하거나 후속 메시지를 대기열에 넣을 수 있다.
설치, 라이선스와 한계
Pi 1.0은 설치 스크립트로 바로 쓸 수 있고 Pi Durable은 npm 패키지로 설치하는 실험 버전이다. 둘 다 MIT 라이선스이고 문서는 pi.dev, 코드는 GitHub earendil-works/pi에 있다. Pi Durable 글은 API가 아직 바뀔 수 있다고 분명히 밝히며 서른 개가 넘는 예제와 1,300줄 남짓의 휴가 계획 에이전트 데모를 제공한다.
TypeScript를 또 쓴 이유를 묻는 FAQ에 대한 답은 가장 쉬운 부트스트랩 수단이기 때문이라는 것이다. 다른 언어로 옮길 가능성은 배제하지 않지만 당분간 TypeScript에 집중한다고 한다. 앞으로 몇 주 안에 Pi Durable로 만든 슬랙 봇, GitHub 분류 봇 같은 작은 도구를 공개하겠다고 예고했다. 이 노트는 세 글만 읽었고 저장소 코드와 예제를 직접 실행하거나 내구성 주장을 검증하지는 않았다. 충돌 복구와 정확히 한 번 처리 같은 보장은 설계 설명으로 읽어야 하며 실제 장애 조건에서의 동작은 코드를 돌려 봐야 안다.
참고 자료
Earendil — Pi Durable — 내구성 설계, 소유권 트리, 컴팩션, 문서, 다중 사용자 기능을 대조했다.
Earendil — “You Said No MCP!” — MCP를 코어에 넣은 이유와 코드모드 설명을 대조했다.
