Repository navigation
Feat: 질문 중계 — 에이전트가 다른 역할에게 묻고 답을 받아 이어 간다 (상담 실행·프로젝트 스위치·내 질문 API, 마이그레이션 018, CLI 0.1.5) - #32
Merged
Merged
Conversation
실행 중인 에이전트가 다른 역할 소관 결정을 AskUserQuestion으로 물으면 브릿지의 권한 도구가 서버에 올리고, 대상 역할 담당(또는 대표)이 답할 때까지 기다렸다가 답을 돌려준다. 근거 실험(E1~E6)은 scratchpad 기록 참고. - 017 agent_questions: 질문(AskUserQuestion 형식 그대로)·대상 역할·상태(pending/answered/expired)·답 - API: POST /tasks/:id/questions·GET /tasks/:id/questions/:qid(에이전트), GET /projects/:id/questions·POST /questions/:id/answer(사람) - 대상 역할은 서버가 정한다(지금은 반대 역할 — routed_by), 답의 키는 질문 문장 그대로(아니면 422), 만료는 읽을 때 판정 - 이벤트 QUESTION_ASKED·ANSWERED·EXPIRED, 실시간 토픽 questions - 브릿지: 권한 도구 permission_prompt(AskUserQuestion만 처리, 나머지·고장은 거부), 대기 중 MCP 진행 알림 - Executor: --permission-prompt-tool, 프롬프트에 "다른 역할 결정은 AskUserQuestion으로 물어라" - QUESTION_TIMEOUT_MS(기본 10분) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…RUN_CLAUDE_E2E=1일 때만) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- domain/question/router.ts: QuestionRouter 인터페이스, 기본 규칙 라우터(반대 역할), LLM 계열 공통 프롬프트·응답 해석 (DB·설정 의존 없음 — 오프라인 평가 장치가 그대로 쓴다) - router-registry.ts: setQuestionRouter로 교체, 실패·30초 초과면 규칙 라우터로 대체하고 fallback을 기록 - SELF(묻는 쪽 자기 소관)면 넘기지 않고 self_owned — 브릿지가 "스스로 정하고 DECIDED로 남겨라"로 돌려준다 - agent_questions.routing(confidence·reason·latencyMs·fallback), QUESTION_ASKED에도 같은 값 — 라우터별 비교 지표 - 라우터는 트랜잭션 밖에서 부른다(LLM이면 수 초) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- scripts/eval-question-router.ts: 정확도·SELF 탐지·잘못 막음·지연·비용, 결과는 scripts/data/router-runs/(커밋 안 함) - scripts/lib/question-routers.ts: claudeCliRouter(이 PC 구독, 도구 없음, 빈 폴더), httpRouter(Jev 등 외부 모델 자리) - scripts/data/question-routing.json: 실험에서 나온 실제 질문 11 + 자기 소관 사례 9, 애매한 문항은 정답 둘 인정 - 첫 결과(v1 데이터셋): 규칙 70%·SELF 0%, Claude Opus·Sonnet 각 2회 100%·SELF 100%(문항당 약 6초) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… 묶음, 형식 문서·빈 틀 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 질문 상태 agent_answered(상담 실행이 코드·명세에서 찾은 답, 사람 미확인) · 초안(draft: answers·decided·basis) - 사람의 답: 대기 중이면 human, 에이전트 답과 같으면 agent_confirmed, 다르면 human_override(고치는 태스크는 미구현 — notice) - POST /tasks/:id/questions/:qid/detach: 태스크 BLOCKED(QUESTION)·담당 비움 → 답이 다 오면 READY, 기간(기본 3일) 지나면 ESCALATED - GET /agents/me/questions(상담할 질문·읽을 레포), POST /questions/:id/draft(대상 역할 에이전트만, 한 번) - 브리핑 answeredQuestions — 재개한 실행이 받은 답을 읽는다 - 이벤트 QUESTION_DRAFTED·TASK_BLOCKED_ON_QUESTION, 질문 생성·초안·답 뒤 tasksChanged(상대 Executor를 깨운다) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- executor/consult.ts: 읽기 전용 상담 실행(--tools Read,Grep,Glob, 빈 MCP), 초안 해석(decided 형식이 틀리면 미정으로) - Executor 루프: 이 역할이 답할 질문이 있으면 상담을 하나씩 띄워 초안을 올린다. 진행 중인 작업공간이 같은 레포면 그걸 읽는다. 실패한 질문은 다시 시도하지 않는다(담당자가 답한다) - 브릿지: 실행 안에서 NOMOS_QUESTION_INLINE_WAIT_MS(기본 3분)만 기다리고 detach — "멈춰라, 나중에 다시 시작된다, 커밋하지 마라". 에이전트 답(agent_answered)도 바로 쓴다 - 프롬프트: 재개한 실행에 "물어서 받은 답" 절(에이전트 답은 사람 미확인 표시) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… → 재개 (RUN_CLAUDE_E2E=1, ②는 E2E_BE_EMPTY=1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… E2E - bridge/credentials.ts nomosHome(): 기본 ~/.nomos, NOMOS_HOME으로 바꾼다. 자격 증명·작업공간·레포·repos.json이 따른다. 홈 자체를 바꾸면 Claude Code 로그인까지 바뀌어 안 된다. - tests/e2e-executors.test.ts: 빌드된 CLI start 두 개(FE·BE)로 C안 전체 — BE Executor가 스스로 상담, FE Executor가 멈춘 태스크를 답이 온 뒤 스스로 다시 집어 간다(RUN_CLAUDE_E2E=1, npm run build 먼저) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
정리 단계가 중계 대기열을 한 번만 비웠다. 테스트가 남긴 백그라운드 PM 작업은 계획 행·예산 확인 뒤에 대기열에 올라오므로, 부하가 있으면 비운 뒤에 올라와 가져갈 워커 없이 PM_TIMEOUT_MS(기본 10분)를 기다렸다 — 전체 실행 6회 중 3회 실패(60초 제한에서도). 백그라운드 작업이 다 끝날 때까지 계속 비운다. 단독 20/20, 전체 3/3 통과(616개 전부). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- dev의 룸 피드·멈춘 태스크(BLOCKED·AGENT_STOPPED)·G3·dep:add·대표 토큰 GitHub 등을 합쳤다. 충돌은 양쪽 유지로 풀었다. - 질문 중계 마이그레이션 017_agent_questions → 018(dev의 017_rooms와 번호 충돌). - 답을 기다리느라 내려놓은 실행(BLOCKED·QUESTION)의 종료는 멈춤으로 바꾸지 않는다(waitingQuestion). - 답이 와서 READY가 되면 "다시 실행해 주세요 (재개)" — task_dispatches.resumes에 TASK_BLOCKED_ON_QUESTION도 센다. - 룸에 질문 줄(QUESTION_*) — 묻는 쪽 룸과 답할 역할의 룸 둘 다. - 권한 도구(permission_prompt)의 거부 문구도 멈춤 사유의 거부 명령으로 모인다(테스트 고정). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- projects.question_relay(018, 기본 켜짐). 시작 전에만 PATCH /projects/:id/settings(대표, PROJECT_SETTINGS_UPDATED). 끄면 서버는 질문을 409 QUESTION_RELAY_OFF로 거부, 브리핑 questionRelay=false → Executor가 권한 도구를 붙이지 않고 프롬프트는 "가정하고 GOTCHA로 남겨라". 대조군 실험·답할 사람 부재·상담 비용·되돌리기용. - 다른 역할 소관 계약은 DECIDED가 아니라 GOTCHA "가정함"으로(스위치와 무관, E6) — feat/prompt-foreign-contract 규칙을 합쳤다. - GET /me/questions: 내가 답할 질문(대표는 전부, 팀원은 자기 역할 대상) — 알림 배지용. - 만료 주기 정리(startQuestionExpirySweep): 아무도 읽지 않아도 3일 지난 질문을 만료시키고 멈춘 태스크를 ESCALATED로. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
실험 브랜치(
exp/question-relay)를 운영에 올린다. **프로젝트 스위치(기본 켜짐)**로 프로젝트마다 끌 수 있다.무엇
permission_prompt— AskUserQuestion만 처리, 나머지 거부).agent_answered), 아니면 사람(대상 역할 담당·대표)이 답한다.projects.question_relay(기본 켜짐, 시작 전에만PATCH /projects/:id/settings). 끄면 질문 409, Executor는 권한 도구를 붙이지 않고 "가정하고 GOTCHA".GET /me/questions(알림 배지용), 룸 피드에 질문 줄(묻는 쪽·답할 쪽 룸 모두).scripts/eval-question-router.ts).근거
헤드리스 실험 E1~E6, 진짜 Claude E2E(중계·상담·두 Executor) — 상세는 CLAUDE.md "질문 중계".
확인
전체 678 통과(E2E 3개는 RUN_CLAUDE_E2E일 때만). 마이그레이션 018(agent_questions, projects.question_relay). CLI 0.1.5.
🤖 Generated with Claude Code