본문으로 건너뛰기

AI 실행 구조 기술 검토 보고서

갱신: 2026-08-18

요약 및 결론

HeyMoa의 AI 실행은 사용자와 대화를 이어 가는 채팅회의 종료 뒤 결과물을 만드는 분석으로 분리돼 있다. 채팅에는 한 오케스트레이터와 두 담당 Agent가 참여한다. 회의 분석은 세 모델 작업을 병렬로 실행하지만 작업 사이의 위임이나 협의가 없어 multi-agent로 분류하지 않는다.

검토 항목결론판단 근거
채팅 구조계층형 multi-agent오케스트레이터가 대화를 소유하고 Linear·GitHub Agent에 작업을 위임한 뒤 결과를 회수한다.
Agent 범위Linear와 GitHub만 독립 Agent각각 별도 상태, 제한된 도구, 반복 실행과 종료 조건을 가진다.
실행 선택한 모델 출력마다 한 갈래내부 조회, Linear, GitHub를 한 호출 묶음에서 섞지 않는다.
외부 쓰기사용자 승인 뒤 실행PostgreSQL checkpoint에 상태를 보존하고 승인 이후 같은 thread에서 재개한다.
회의 분석채팅과 분리된 병렬 workflow세 section이 입력만 공유하고 독립적으로 실행된 뒤 reducer에서 합쳐진다.

책임 경계는 분명하다. 오케스트레이터가 최종 응답을 전담하고, 담당 Agent에는 이번 작업만 전달하며, 외부 쓰기는 승인 노드와 실행 노드를 분리했다. 반면 운영 배포 commit과 조사 대상 checkout의 일치 여부, 분석 callback의 연속 실패 정책, 일부 실행 상한의 운영값은 확인되지 않았다.

조사 범위와 판정 기준

구분내용
조사 기준일2026-08-17
조사 대상당시 로컬 heymoa-ai checkout의 채팅·위임·분석 실행 코드
포함 범위프로필 선택, 오케스트레이터 routing, Linear·GitHub 위임, 쓰기 승인, 상태 저장, 회의 분석, 멱등 처리
제외 범위모델 답변 품질, 비용, 부하 시험, 운영 장애 기록
미확인조사 checkout과 운영 배포 commit의 일치 여부

모델 호출 여부만으로 Agent를 판정하지 않았다. 아래 네 조건을 함께 만족하는 실행 단위를 Agent로 보았다.

  1. 부모 대화와 구분되는 작업 상태를 가진다.
  2. 맡은 업무에 맞게 제한된 도구를 사용한다.
  3. 도구 결과를 보고 다음 행동을 스스로 선택한다.
  4. 완료·반복·실패·단계 상한에 따른 종료 조건을 가진다.

이 기준에 따르면 프로필은 prompt·context·tool 구성을 고르는 규칙이고, 회의 분석의 section은 정해진 결과물을 만드는 병렬 작업이다.

현행 구조

상태 변화AI 실행 전체 구조36개 노드 · 52개 연결
구성요소 경계상태 전이
휠로 확대 · 드래그로 이동 · 노드를 선택해 경로를 좁힙니다

채팅은 중앙 오케스트레이터가 요청을 판단하고 직접 조회 또는 담당 Agent 위임을 선택한다. Linear와 GitHub Agent는 부모 대화 전체가 아니라 정리된 작업 한 건을 받아 실행한다. 회의 분석은 별도 진입점에서 시작하며 채팅의 checkpoint와 상태를 공유하지 않는다.

실행 단위입력소유 상태도구와 처리종료 결과
채팅 오케스트레이터사용자 대화와 선택된 프로필부모 messages, 전송 상태HeyMoa 읽기 또는 담당 Agent 위임사용자 답변
Linear AgentLinear 작업 한 건provider_messages, 승인, 단계 수허용된 Linear 도구완료·중단 요약
GitHub AgentGitHub 작업 한 건provider_messages, 승인, 단계 수허용된 GitHub 도구완료·중단 요약
회의 분석 workflow확정된 회의 전사section 결과개요·할 일·결정 사항 분석병합 결과와 callback

담당 Agent끼리는 직접 메시지를 교환하지 않는다. 한 모델 출력에서 Linear와 GitHub를 동시에 실행하지도 않는다. Linear 결과를 받은 오케스트레이터가 다음 판단에서 GitHub 작업을 새로 위임할 수는 있다.

핵심 아키텍처 판단

판단코드에서 확인한 근거구조에 미치는 영향
대화 소유자는 오케스트레이터 하나다.직접 도구와 담당 Agent의 결과가 모두 부모 messages로 돌아간다.최종 응답과 대화 이력을 한곳에서 관리한다.
호출 묶음은 한 갈래가 맡는다.routing 결과가 두 갈래 이상이면 refusal이 모든 tool call에 오류 결과를 붙인다.미완성 tool call로 다음 모델 호출이 깨지는 일을 막지만 한 차례에 여러 provider를 병렬 실행하지 못한다.
담당 Agent는 작업 한 건만 본다.prep이 provider 상태를 비우고 위임받은 task만 새 HumanMessage로 넣는다.이전 위임의 결과가 섞이지 않고 모델 입력이 불필요하게 커지지 않는다.
승인과 외부 쓰기를 분리한다.approvalinterrupt()만 수행하고 실제 호출은 다음 tools가 맡는다.재개 과정에서 승인 노드가 다시 실행돼도 외부 쓰기가 중복되지 않는다.
회의 분석은 Agent 협업이 아니다.세 section은 서로의 상태를 읽거나 일을 위임하지 않고 reducer에서 결과만 합친다.채팅과 다른 병렬 workflow로 운영·실패 정책을 나눠야 한다.

구조의 핵심 절충은 명확하다. 한 번에 한 실행 갈래만 허용해 대화 이력의 완결성을 우선했고, 담당 Agent의 입력을 좁혀 상태 격리를 택했다. 대신 여러 외부 서비스를 한 차례에 병렬 처리하는 구조는 아니다.

채팅 요청 처리

대화 위치가 입력 구성을 정한다

상태 변화대화 범위 선택6개 노드 · 7개 연결
상태 전이
휠로 확대 · 드래그로 이동 · 노드를 선택해 경로를 좁힙니다

ChatPolicy.select()는 요청의 scopekind를 비교해 프로필을 고른다. 프로필 선택은 실행자 선택보다 앞서 일어나며, 같은 오케스트레이터에 어떤 맥락과 내부 도구를 제공할지 정한다.

요청 위치프로필처음 제공하는 맥락HeyMoa 내부 도구
공유 회의록meeting현재 회의록 전체회의록 읽기, 전사 검색
개인 회의록note현재 회의록 전체없음
워크스페이스workspace회의록 목록회의록 읽기, 전사 검색

어느 프로필에서도 Linear와 GitHub Agent를 구성할 수 있다. 실제 모델에는 사용자가 연결한 서비스의 위임 도구만 노출한다. 회의 중 채팅도 별도 그래프를 만들지 않고 meeting 프로필로 같은 채팅 그래프를 실행한다.

호출 묶음의 소유자를 하나로 정한다

상태 변화채팅 graph 전체 흐름7개 노드 · 10개 연결
상태 전이
휠로 확대 · 드래그로 이동 · 노드를 선택해 경로를 좁힙니다
모델 출력다음 실행
도구 호출 없음답변을 사용자에게 보내고 종료
HeyMoa 읽기만 포함direct_tools에서 직접 실행
Linear 위임만 포함Linear Agent 실행
GitHub 위임만 포함GitHub Agent 실행
서로 다른 갈래가 섞이거나 호출이 잘못됨refusal에서 호출 전체를 오류로 완결

모델이 만든 각 tool call에는 대응하는 ToolMessage가 필요하다. 호출 일부만 실행하면 부모 대화 이력이 미완성 상태로 남을 수 있다. 그래서 혼합 호출을 갈래별로 나누지 않고 모두 거절한다. 실행 결과는 다시 오케스트레이터로 들어가며, 최종 사용자 문장도 오케스트레이터가 만든다.

채팅 오케스트레이터는 gpt-5.6-luna, 추론 강도 low를 사용한다.

담당 Agent는 준비·실행·회수 경계를 가진다

상태 변화Provider handoff 확대9개 노드 · 12개 연결
상태 전이
휠로 확대 · 드래그로 이동 · 노드를 선택해 경로를 좁힙니다

위임은 세 단계로 나뉜다.

  1. prepprovider, intent, task, 원래 tool_call_id를 저장하고 이전 provider 상태를 지운다.
  2. 담당 Agent가 허용된 도구 안에서 판단과 실행을 반복한다.
  3. collect가 완료·중단 요약을 원래 tool call의 ToolMessage로 바꿔 부모 대화에 추가한다.

담당 모델은 gpt-5.6-luna, 추론 강도 medium이며 parallel_tool_calls=False로 실행한다. 도구 호출이 없으면 완료하고, 같은 도구와 인자를 되풀이하면 중단한다. 쓰기가 포함되면 승인을 기다리고, 읽기만 있으면 도구 검사와 실행으로 넘어간다. 연속 실패가 max_failures에 닿거나 모델 호출이 max_steps에 닿아도 중단 요약을 만든다.

상태 범위주요 필드책임
부모 대화messages, message_id, turn_content사용자와 이어지는 대화와 이미 전송한 문장
위임 경계handoff, tool_call_id담당 서비스, intent, task와 원래 호출 연결
담당 Agentprovider_messages, provider_approvals, provider_steps이번 작업의 이력, 승인, 실행 단계
결과 회수provider_summary완료·중단 결과를 부모 대화로 반환

상태·승인·안정성 통제

확인된 통제 장치는 외부 쓰기 중복, 위임 사이의 상태 오염, 반복 호출, 장시간 실행을 각각 다른 경계에서 막는다.

쓰기 승인은 checkpoint에서 멈추고 이어 간다

상태 변화쓰기 승인과 실행 재개8개 노드 · 8개 연결
상태 전이
휠로 확대 · 드래그로 이동 · 노드를 선택해 경로를 좁힙니다

쓰기 호출이 생기면 approvalinterrupt()로 사용자 결정을 요청한다. AsyncPostgresSaver가 중단 시점의 상태를 저장하며 chat_id를 checkpoint의 thread_id로 사용한다. 승인이나 거절 뒤에는 같은 thread에 Command를 보내 실행을 재개한다.

재개할 때 approval이 다시 실행될 수 있으므로 이 노드에서는 외부 쓰기와 감사 기록을 만들지 않는다. 승인된 외부 호출은 다음 tools에서만 실행한다. 거절한 호출도 결과 메시지를 남겨 담당 Agent의 이력을 완결한다.

재사용 장치는 수명과 목적이 다르다

상태 변화대화 상태와 재사용 장치8개 노드 · 7개 연결
상태 전이
휠로 확대 · 드래그로 이동 · 노드를 선택해 경로를 좁힙니다
통제 장치유효 범위통제하는 위험
prep위임 한 번이전 provider 상태가 새 작업에 섞임
prefill()모델 호출 한 번지침·근거·대화의 입력 순서가 흔들림
PostgreSQL checkpoint같은 chat_id승인 대기 중 상태 유실
프로필 그래프 레지스트리프로세스같은 그래프의 반복 구성
모델 레지스트리모델·추론 강도 조합같은 모델 클라이언트의 반복 생성
Langfuse 프롬프트 대체본프롬프트별원격 프롬프트 조회 실패
도구 fingerprint현재 사용자 차례성공한 HeyMoa 읽기의 즉시 반복
max_failures, max_steps담당 Agent 작업연속 실패와 무한 실행

prefill()은 그래프 노드나 실행 결과 cache가 아니다. 모델 입력을 instructions → grounding → history 순서로 조립해 변하지 않는 접두부를 유지한다. 대화가 길어지면 모델에 보내는 사본만 줄이고 PostgreSQL checkpoint의 원본 messages는 보존한다.

회의 후 분석

세 결과물을 독립적으로 만든 뒤 합친다

상태 변화회의 후 병렬 분석6개 노드 · 7개 연결
상태 전이
휠로 확대 · 드래그로 이동 · 노드를 선택해 경로를 좁힙니다

회의 분석은 채팅 오케스트레이터와 담당 Agent를 거치지 않는다. sections.ymloverview, action_items, decisions 사이에 의존관계가 없어 세 노드를 함께 시작하고 sections reducer에서 결과를 합친다.

세 작업은 gpt-5.6-luna, 추론 강도 low를 사용한다. 노드별 제한 시간은 55초이며 한 번 재시도한다. checkpointer가 없어 채팅 승인처럼 중단 지점에서 재개하지 않는다.

analysis_id로 중복 실행을 막는다

상태 변화분석 요청의 중복 실행 방지9개 노드 · 10개 연결
상태 전이
휠로 확대 · 드래그로 이동 · 노드를 선택해 경로를 좁힙니다
접수 상태처리
같은 analysis_id가 실행 중새 작업을 만들지 않고 기존 실행을 기다림
같은 ID의 결과가 보관됨모델을 다시 호출하지 않고 기존 결과를 callback으로 전송
결과 없음세 section을 새로 실행

전사 색인은 분석과 함께 시작하는 별도 작업이다. embedding에는 text-embedding-3-small을 사용한다. 분석 결과의 재사용 기준은 내용의 유사도가 아니라 정확히 같은 analysis_id다.

비교 항목채팅회의 분석
실행 시작사용자 메시지회의 분석 요청
작업 선택오케스트레이터의 조건부 routing고정된 세 section 병렬 실행
상태 보존PostgreSQL checkpoint실행 중 checkpointer 없음
사용자 승인외부 쓰기에 사용없음
재사용 기준같은 chat_id의 대화 상태같은 analysis_id의 실행·보관 결과

한계와 확인사항

상태항목확인이 필요한 이유
미확인운영 배포 commit과 조사 checkout의 일치 여부보고서의 코드 근거가 실제 운영 경로와 같은지 판정할 수 없다.
미확인운영 환경의 max_steps, max_failures 값과 산정 근거담당 Agent의 최악 실행 시간과 호출 비용을 계산할 수 없다.
미확인분석 callback 연속 실패 정책분석 결과를 만들고도 업무 서버에 전달하지 못했을 때의 복구 책임이 불분명하다.
미확인회의 분석 timeout과 retry 소진 뒤 최종 처리실패 상태 저장, 재발행, 운영자 경보의 경계가 확인되지 않았다.
미확인모델·추론 강도 변경의 품질·비용 평가 기준현재 모델 설정을 바꿀 때 회귀 여부를 판단할 기준이 없다.
확인된 범위 밖회의 중 자동 개입, 주제 이탈 경고, 결정 충돌 알림조사한 코드에는 전담 실행 그래프가 없다. 다른 저장소의 구현 여부는 확인하지 못했다.

한 번의 모델 출력에서 여러 provider를 병렬 실행하지 않는 점과 담당 Agent끼리 직접 협업하지 않는 점은 현행 설계의 제약이다. 이를 문제로 볼지는 제품이 한 사용자 차례에 복수 외부 작업을 요구하는지 확인한 뒤 판단해야 한다.

구현 근거

검토 항목heymoa-ai 경로
프로필 선택과 모델·도구 설정src/heymoa/application/policies/chat.py, src/heymoa/infrastructure/config/profiles.yml
최상위 채팅 그래프src/heymoa/infrastructure/agent/builder.py
오케스트레이터와 조건 분기src/heymoa/infrastructure/agent/orchestrator/
위임 준비와 결과 회수src/heymoa/infrastructure/agent/branches/handoff/
Linear·GitHub Agent 실행 loopsrc/heymoa/infrastructure/agent/providers/
부모·담당 Agent 상태src/heymoa/infrastructure/agent/state.py
모델 입력 조립src/heymoa/infrastructure/llm/caching.py