테마 전환

Pi는 모델 요청, 도구 실행, 컨텍스트 조립, 세션 저장을 하나의 엔진으로 조율합니다. 이 구조를 이해하면 Pi가 왜 이렇게 동작하는지, 확장이나 SDK로 무엇을 건드릴 수 있는지 자연스럽게 보인다. 이 글은 공식 문서 "How Pi Works"를 바탕으로 Pi의 내부 흐름을 정리합니다.
세션은 트리다
Pi에서 세션(session)은 대화의 기록입니다. 메시지, 도구 호출과 결과, 모델 변경, 압축(compaction) 등 모든 것이 이벤트로 남습니다.
세션의 메시지와 이벤트는 트리(tree)를 이룹니다. 각 항목(entry)은 ID를 갖고 부모 항목을 가리키며, 트리를 따라 그은 하나의 경로가 브랜치(branch)입니다. 이때 현재 항목까지 이어진 브랜치가 활성 브랜치이며, 다음 모델 요청의 대화 기록이 됩니다.
이 구조 덕분에 이전 시점으로 돌아가 다른 접근을 시도해도 기존 기록이 지워지지 않습니다. 이른 시점부터 이어지는 다른 트리를 만들 뿐입니다. 이것이 /tree, /fork 같은 갈라치기 명령이 가능한 이유입니다.
에이전트 루프
메시지를 보내면 다음과 같은 흐름이 돌아갑니다.
- 보낸 메시지가 활성 브랜치에 추가된다.
- Pi는 시스템 프롬프트, 활성 브랜치, 사용 가능한 도구, 모델 설정으로 모델 요청을 만들고 선택한 제공자(provider)로 보낸다.
- 제공자가 스트리밍하는 응답(텍스트와 도구 호출)을 기록한다.
- 각 도구 호출을 실행하고 결과를 기록한다. 여기까지가 한 턴(turn)이다.
- 도구 결과나 대기 중인 메시지가 다음 요청을 필요로 하면 새 턴을 시작한다. 그렇지 않으면 실행이 끝난다.
루프 도중에 개입하는 방식도 정해져 있습니다.
| 개입 | 동작 |
|---|---|
| 조향(steering) 메시지 | 현재 어시스턴트 턴이 끝난 직후에 삽입된다 |
| 후속(follow-up) 메시지 | 에이전트가 남은 작업을 마친 뒤에 삽입된다 |
| 중단(abort) | 현재 실행을 멈추고 대기 중인 메시지를 편집기로 되돌린다 |
컨텍스트는 어떻게 조립되나
모델이 받는 대화 기록은 활성 브랜치입니다. Pi는 세션 항목을 모델이 이해하는 user·assistant·tool-result 메시지로 바꿉니다.
시스템 프롬프트는 기본 지침과 발견된 컨텍스트 파일(AGENTS.md 등)로 만들어지며, 요청에는 도구 정의와 스킬 이름·설명도 함께 실립니다. 스킬의 전체 지침은 바로 올라가지 않습니다. 필요한 순간에 모델이 직접 읽어 컨텍스트를 아낍니다.
- 프롬프트 템플릿은 사용자 입력이 user 메시지가 되기 전에 확장된다.
- 선택한 파일, 이미지, 붙여넣은 텍스트, 셸 출력이 메시지 내용이 될 수 있다.
- 확장이 지침을 추가하거나 컨텍스트를 변환할 수도 있다.
인터페이스는 달라도 엔진은 하나
| 방식 | 동작 |
|---|---|
| 대화형(interactive) | 세션·에이전트 이벤트를 터미널에 렌더링 |
| print 모드 | 프롬프트를 실행하고 최종 응답만 출력 |
| JSON 모드 | 에이전트 이벤트를 JSONL로 출력 |
| RPC 모드 | stdin으로 JSONL 명령을 받고 stdout으로 응답·이벤트를 씀 |
| TypeScript SDK | 프로세스 안에서 에이전트 세션을 생성·제어 |
모든 인터페이스가 같은 에이전트·세션 메커니즘을 공유합니다. 그래서 대화형에서 하던 작업이 스크립트나 앱 안에서도 같은 규칙으로 동작합니다.
확장 자원과 신뢰 경계
확장은 Pi 프로세스 안에 로드되는 TypeScript 모듈입니다. 팩토리 함수가 도구, 명령, 단축키, 제공자, 이벤트 핸들러, 렌더러, 터미널 UI를 등록합니다. 스킬은 필요할 때 지침을, 프롬프트 템플릿은 재사용 문구를, 테마는 색을 제공하며 Pi 패키지로 배포됩니다.
신뢰(trust)는 리소스 로드 시점에 작용합니다. Pi는 프로젝트 설정과 자원을 로드하기 전에 프로젝트 신뢰 판정을 거칩니다. 단, 한 번 로드된 도구와 확장은 Pi 프로세스의 운영체제 권한으로 동작하므로 신뢰 판정이 곧 실행 격리는 아닙니다. 이 주제의 안전하게 실행하기 글에서 자세히 다룹니다.