pcommittee (두 에이전트 근본 원인 위원회)
개요
두 에이전트, 두 모델 계열, 동일한 문제, 각각 새로운 컨텍스트. 두 에이전트는 병렬로 분석하고, 사용자는 의견이 갈리는 지점을 찾아 논쟁을 유도한 뒤, 살아남은 내용을 종합합니다. 그리고 사용자가 구현합니다 — 위원회는 절대 파일을 건드리지 않습니다.
이것이 진가를 발휘할 때: 동일한 루프를 두 번 반복했거나, 버그의 명확한 근본 원인이 없거나, 구축하기 전에 두 번 세 번 검토할 가치가 있는 계획일 때. 두 개의 xhigh 에이전트는 저렴하지 않습니다. 한 가지 의견만 필요하면 padvisor를 사용하고, 작업을 위임하려면 pspawn 또는 phandoff를 사용하세요.
생성된 에이전트가 할 수 있는 일. 두 에이전트 모두 팀 기본값에 따라 권한 프롬프트 없이 실행되지만(bypassPermissions on Claude, full-access on Codex), 모드가 아니라 지시에 따라 읽기 전용입니다. 프롬프트의 '편집 금지' 접미사가 파일 변경을 막습니다. 더 많은 권한이 필요한 팀은 저장소의 AGENTS.md에 요청할 수 있으며, 이는 지시사항으로도 적용됩니다. 또는 Claude Code permissions.deny 규칙으로 차단할 수 있으며, bypassPermissions에서도 여전히 적용됩니다.
호출
/pcommittee <문제> — 기본 쌍은 아래와 같습니다. 사용자가 지정한 멤버가 이를 대체합니다.
구성
대조가 메커니즘이지, 단순한 편의가 아닙니다. 동일한 계열의 두 에이전트는 동일한 사각지대를 두 번 만들어내고 그 일치를 확인이라고 부릅니다.
기본 위원회는 claude와 codex를 쌍으로 합니다. 두 에이전트 모두 paseo provider ls에 available과 Enabled로 표시되어야 합니다:
- 멤버 A:
paseo provider models claude가 나열하는 최신 Opus (예:claude/claude-opus-5-5) · 사고xhigh· 모드bypassPermissions - 멤버 B: Codex의 최신 모델,
paseo provider models codex의 첫 번째 ID · 사고xhigh· 모드full-access
ID는 메모리가 아닌 해당 목록에서 읽어오세요. Claude 멤버는 일반 ID(1M 모델)를 사용합니다(pspawn에서 [1m]이 없는 이유 설명). 두 멤버 모두 권한 프롬프트 없이 실행되며(모든 스폰과 마찬가지로 팀 기본값), 파일 변경을 막는 것은 모드가 아닌 '편집 금지' 접미사입니다.
사용자가 멤버를 명명했다면 그 멤버를 사용하세요. 한 계열만 사용 가능하다면 그 사실을 알리고, 하나뿐인 멤버의 위원회를 가장하는 대신 padvisor를 실행하세요.
단계
1. 하나의 문제 프롬프트를 작성합니다. 두 멤버는 동일한 텍스트를 받습니다 — 프롬프트가 다르면 불일치가 실제 분할이 아닌 사용자 표현의 인공물이 됩니다.
파일로 작성하고 "$(cat <프롬프트 파일>)"를 두 스폰에 전달합니다. 동일한 heredoc을 두 번 입력하면 텍스트가 조용히 달라집니다. 파일은 동일성을 구조적으로 만듭니다. mktemp로 파일을 만들고 출력된 경로를 <프롬프트 파일>로 사용하세요: /tmp의 고정 이름은 다른 세션의 위원회와 충돌하고 모든 사용자가 읽을 수 있지만, mktemp 파일은 이 실행을 위해 새로 생성되고 사용자만 읽을 수 있습니다.
사용자 대화의 언어로 답변 언어를 명시하여 시작하세요(Answer in <language>.). 멤버는 프롬프트 언어로 답변하며, 한 언어로 진행되는 대화에 두 개의 다른 언어 보고서가 있으면 종합 단계에서 마찰이 발생합니다.
[사용자 대화 언어, 지시사항: "Answer in <that language>."]
## 문제
[잘못되었거나 결정되지 않은 사항. 증상, 당신의 이론이 아닙니다 — 당신의 이론은 테스트받고자 하는 것입니다.]
## 알려진 사실
[사실, 측정값, 오류 메시지, 그대로. 결론이 아닙니다.]
## 시도한 것
- [접근법] — [결과, 포기한 이유]
## 조사할 위치
- `/절대/경로/파일.ts` — [파일 설명 및 중요성]
## 원하는 결과
근본 원인 분석과 계획을 반환하세요. 신뢰도를 밝히고, 진단을 반증할 수 있는 것을 명시하세요. 제시된 문제가 잘못된 문제라면, 먼저 그렇게 말하세요.
이것은 분석 전용입니다. 파일을 편집, 생성, 삭제하지 마세요. 코드를 작성하지 마세요.
자신의 가설을 프롬프트에 넣지 마세요. 그렇지 않으면 다른 말로 두 번 돌아옵니다. 반드시 언급해야 한다면, 공격받을 가설로 표시하세요.
2. 이 세션의 자식으로 두 에이전트를 스폰합니다. 먼저 제공자 가용성을 확인합니다(pspawn의 1단계와 정확히 동일: <이 스킬의 기본 디렉토리>/../pspawn/SKILL.md). 그런 다음, 같은 응답에서 병렬로 사고할 수 있도록:
paseo run --no-wait --json --provider '<claude/newest-opus>' --thinking xhigh \
--mode bypassPermissions --title "[Committee A] <주제>" "$(cat <프롬프트 파일>)"
paseo run --no-wait --json --provider '<codex/newest>' --thinking xhigh \
--mode full-access --title "[Committee B] <주제>" "$(cat <프롬프트 파일>)"
paseo에서 두 에이전트는 자동으로 이 세션의 워크스페이스에 세션의 자식으로 배치됩니다. 분리하지 마세요. 위원회는 이 질문에 속하며, 이 세션을 보관하면 위원회도 함께 보관되는 것이 올바른 동작입니다. paseo 외부에서는 --workspace <id>를 추가하고, pspawn의 2단계처럼 한 번 조회합니다.
3. 두 에이전트를 기다립니다 — 멤버당 하나의 paseo-notify, 그런 다음 턴을 종료합니다.
paseo-notify <id-a>; paseo-notify <id-b>
각 멤버의 메시지는 별도로 도착합니다. 하나가 완료되고 다른 하나가 아직 진행 중이면, 다시 턴을 종료하세요. 두 번째 메시지가 당신을 깨웁니다. finished its turn → 응답 완료. is waiting for a permission → 당신의 응답을 기다리는 요청이 있음. stopped with an error → 그렇게 말하고 로그를 읽으세요. 조용히 다시 스폰하지 마세요. 사용량 제한은 당신을 깨우지 않습니다: paseo-limit-watch가 멤버를 재개하고 감시를 재설정합니다(cron 라인이 설치된 경우, README 참조). 그렇지 않으면 재설정 후 멤버를 직접 확인하세요. 멤버는 일반적으로 15~30분 실행됩니다. 절대 폴링, sleep, 서두르는 메시지를 보내지 마세요.
paseo 외부($PASEO_AGENT_ID 없음): paseo wait <id-a> --json; paseo wait <id-b> --json을 하나의 Bash 호출에 run_in_background: true로 사용하고, 각각의 status를 JSON에서 읽으세요. 종료 코드는 무시하세요.
permission인 경우 (bypass 및 full-access에서는 드물지만 rm -rf는 여전히 질문함) 멤버는 감시자가 없이 중단됩니다. 읽고(paseo permit ls), 부여한 권한 범위 내인지 결정한 후, paseo permit allow <agent-id> <request-id> 또는 deny(두 ID 모두 paseo permit ls에서)를 실행하고 paseo-notify를 다시 설정하세요. 범위를 벗어나거나 불명확하면 사용자에게 물어보고, 대신 승인하지 마세요.
4. 둘 다 읽습니다.
paseo logs <id> --filter text --tail 3
pagent.py <id> -t -n 3 --full (<이 스킬의 기본 디렉토리>/../pagent/)는 타임스탬프가 포함되어 더 풍부하며, Claude와 Codex 멤버를 동일하게 읽습니다.
5. 논쟁을 유도합니다. 이 단계가 위원회를 두 에이전트 가치 있게 만듭니다 — 이 단계를 건너뛰면 두 개의 보고서만 있고 해결책은 없습니다.
실제로 갈리는 지점을 찾으세요 — 다른 근본 원인, 다른 수정 방법, 다른 위험 평가. 표현과 강조의 차이는 무시하세요. 그것들은 불일치가 아닙니다.
각 실제 분할에 대해, 각 멤버에게 상대방의 주장을 보냅니다:
paseo send --behavior steer --no-wait <id-a> "멤버 B는 <X>라고 결론지었으며, 근거는 <인용 사고>입니다. 직접 다루세요: B가 어디에서 틀렸습니까, 아니면 당신이 틀렸습니까? B가 옳다면 입장을 바꾸세요 — 그렇지 않다면 명확히 말하세요."
paseo send --behavior steer --no-wait <id-b> "멤버 A는 <Y>라고 결론지었으며, 근거는 <인용 사고>입니다. 직접 다루세요: A가 어디에서 틀렸습니까, 아니면 당신이 틀렸습니까? A가 옳다면 입장을 바꾸세요 — 그렇지 않다면 명확히 말하세요."
긴 인용 사고는 파일로 전달하는 것이 더 쉽습니다: 메시지를 작성하고 paseo send --behavior steer --no-wait --prompt-file <파일> <id>를 사용하세요. 제공자가 스티어링을 수락할 수 없으면, 중단으로 대체할 수 있습니다. paseo send는 보관된 에이전트를 복원합니다 — 먼저 paseo inspect <id> --json에서 ArchivedAt을 확인하세요. 보관된 멤버는 복원하지 마세요.
여기서 --no-wait는 필수입니다. 일반 paseo send는 에이전트가 완료될 때까지 차단됩니다 — 두 개의 차단 전송은 멤버를 병렬 대신 순차적으로 실행하며, 첫 번째 전송만으로도 10분 포그라운드 Bash 제한을 초과합니다. 두 개를 비차단으로 실행한 후, 두 감시를 다시 설정하고(3단계) 다시 읽습니다(4단계). 보통 두 라운드면 충분합니다. 두 라운드 후에도 여전히 동의하지 않으면, 불일치를 결과로 보고 중단하세요 — 두 강력한 모델 간의 해결되지 않은 진정한 분할은 문제에 대한 실제 발견이며, 세 번째 라운드를 보내 합의를 강제하면 이를 파괴합니다.
6. 사용자를 위해 종합합니다:
- 두 에이전트가 동의한 내용 — 이것이 핵심입니다
- 갈린 부분과 해결 방법(또는 해결되지 않았음)
- 자신의 해석, 자신의 것으로 표시
- 이제 따를 계획
7. 두 에이전트를 보관합니다 — paseo archive <id> 각각 — 사용자가 계속 질문하기를 원하지 않는 한.
일반적인 실수
| 실수 | 수정 방법 |
|---|---|
| 동일한 제공자 계열의 두 멤버 | 대조가 메커니즘입니다 — claude + codex |
| 멤버별 다른 프롬프트 | 하나의 파일, "$(cat …)"를 두 스폰에 — 두 heredoc은 달라집니다 |
| 답변 언어 미지정 | 멤버는 프롬프트 언어로 답변합니다. 사용자 언어로 시작하세요 |
| 프롬프트에 자신의 가설을 사실로 제시 | 빼거나, 공격받을 가설로 표시하세요 |
| 논쟁 라운드 건너뛰기 | 두 보고서는 위원회가 아닙니다 — 5단계가 핵심입니다 |
| 세 번째 라운드에서 합의 강제 | 두 강력한 모델 간의 해결되지 않은 분할이 바로 발견입니다 |
paseo wait의 종료 코드 신뢰 | 0은 idle, permission, error 모두에 해당합니다 — --json에서 status를 읽으세요 |
| 포그라운드 대기 | run_in_background: true; 10분 Bash 제한은 에이전트가 아닌 대기를 종료합니다 |
Codex 멤버 기본 모드 또는 claude auto 유지 | codex → full-access, claude → bypassPermissions (팀 기본값); 기본 모드 멤버는 응답 없는 프롬프트에서 중단됩니다 |
| 폴링 / 서두르는 메시지 | 멤버당 paseo-notify로 턴 종료; 멤버는 15~30분 동안 추론합니다 |
두 번째 라운드에서 일반 paseo send | 완료될 때까지 차단됩니다 — --no-wait로 둘 다 실행한 후 3단계 |
| '편집 금지' 접미사 누락 | 두 멤버 모두 분석 대상 구현을 시작합니다 |
멤버 분리 또는 env -u PASEO_AGENT_ID | 의도적으로 이 세션의 자식입니다. 세션이 보관될 때 함께 사라집니다 |
| 작은 질문에 위원회 실행 | padvisor — 에이전트 하나, 의견 하나, 비용 일부 |