Skip to content

feat(agent): Primary 그래프 확장 — tool 노드 + 컨펌 노드 + draft/confirmed lifecycle #39

@hagyutae

Description

@hagyutae

배경

현 Primary 그래프는 1-노드 (LLM 한 번 호출) — 도구 / 분기 / 상태 추적 일체 없음. M3 의 Primary 책임 (사용자 대화 → 이슈/wiki 구체화 → draft → 컨펌 → external sync) 을 수행하려면 그래프를 확장해야 함.

(주: "그래프" = LangGraph 의 compiled graph, knowledge graph 가 아님)

스코프

LangGraph 그래프 재구성 — agents/primary/src/primary_agent/graph.py

flowchart LR
    S([START]) --> LLM[LLM 노드<br/>의도 / 다음 행동 판단]
    LLM -->|tool 호출| TOOL[Tool 노드<br/>Doc Store MCP / IssueTracker / Wiki / Librarian A2A]
    TOOL --> LLM
    LLM -->|컨펌 요청| CONFIRM[사용자 컨펌 대기<br/>state=INPUT_REQUIRED]
    CONFIRM --> LLM
    LLM -->|완료| E([END])
Loading

State schema

  • 진행 중인 PRD / Epic / Story / Wiki page 의 draft (id, content, status: draft|confirmed)
  • 대화 history (LangGraph 가 자동 관리)
  • 외부 도구 sync 진행 상황

Tool 통합 (#63 / #64 분담 모델)

Primary 가 호출하는 4 채널:

채널 용도 호출 방식
Doc Store MCP (write / read) PM 영역 데이터 — wiki_pages (PRD / ADR 등) / issues (Epic / Story / Task) MCP 직접
IssueTracker MCP (sync) GitHub Issue 양방향 동기화 MCP 직접
Wiki MCP (sync) GitHub Wiki 양방향 동기화 MCP 직접
Librarian A2A (read 위임) 정보 검색 / 자연어 / 교차 쿼리 A2A SendMessage

write 는 Primary 자기 도메인 (wiki_pages / issues) 만 Doc Store MCP 로 직접 (architecture-shared-memory). Librarian 통과는 read 자연어 / 교차 쿼리 (예: chronicler_log_by_context) 한정.

LangGraph bind_tools 또는 ToolNode 활용해 위 4 채널의 도구를 LLM 에 노출.

Draft → confirmed lifecycle (사용자 답변 C1, 분담 모델 정정)

  • LLM 이 사용자 대화로 draft 정리 → Primary 가 Doc Store MCP 로 직접 wiki_pages.create (status=draft) 또는 issues.create
  • LLM 이 사용자에 컨펌 요청 → state=INPUT_REQUIRED
  • 사용자 응답 분기:
    • 컨펌: Primary → Doc Store MCP 직접 wiki_pages.update(status=confirmed) + IssueTracker/Wiki MCP 로 external sync
    • 수정: LLM 으로 돌아가 재정리 → Doc Store MCP 로 추가 update
    • 취소: Primary → Doc Store MCP 직접 update(status=cancelled) 또는 delete

Persona / prompt 보강

  • configs/primary.yaml 의 persona 에 "Epic / Story / Wiki 사용 시점 / 칸반 status 의미적 매핑" 가이드 추가
  • IssueTracker.list_statuses() 동적 조회 후 LLM 이 의미적 매칭

비-스코프

  • Architect 와의 위임 (M4)
  • Engineer / QA 호출 (M5+)
  • Tool 결과의 정교한 캐싱 / 재시도 (M5+)

검증

  • 그래프 컴파일 성공
  • tool 노드 단위 테스트 (모킹된 MCP / Librarian 응답)
  • State persistence 검증 — 도중 종료 후 재기동 시 같은 contextId 의 draft 복구
  • E2E 시나리오 (별 이슈) 와 통합

의존


완료 요약 (2026-05-08, PR #68 머지)

원 스코프 대비 실제 변경

영역 원 스코프 실제
LangGraph 그래프 LLM + Tool + Confirm 3 노드 ReAct 패턴 (llm_call + tools + conditional edge). Confirm 은 별 노드 X — messages 안 AIMessage / ToolMessage 로 lifecycle 추적 (단순 우선)
State schema draft / sync 진행 / history 별 키 messages 단일 키 + add_messages reducer — draft / sync 진행도 메시지 안에 누적
Tool 통합 Doc Store / IssueTracker / Wiki / Librarian 4 채널 그대로 — 23 도구 wired (primary tools wired: doc_store=on, issue_tracker=on, wiki=on, librarian=on, total=23)
Persona 가이드 4 채널 운용 / Wiki page_type / Draft→Confirmed / 외부 status·type 동적 매핑 그대로
Draft → Confirmed lifecycle draft → 사용자 컨펌 → confirmed → external sync 그대로
(스코프 외) 모듈 분리 추가 — SRP 정리. tools/ 패키지화 + settings.py + channels.py + lifespan_helpers.py + server.py thin orchestration
(스코프 외) Docker 인프라 추가 — M3 deliverable 부팅. 4 채널 env wiring + env 명시화 + compose 루트 이동

검증

  • uv run pytest 23 통과 — graph helper 13 + tools 4 채널 매트릭스 10
  • docker compose --profile agents up -d --build — 10 컨테이너 정상 부팅
  • 사용자 UI 통해 Primary 와 9 turn 실 대화 진행 — 그래프 / 4 채널 / persona / draft 동작 정상

검증 중 발견된 인접 결함 (모두 M3 안 후속)

위 다섯이 land 되면 #41 (e2e) 진입 준비 완료.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions