Skip to content

dev-jsshin/multi-agent-system

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Multi-Agent System

웹 기반 멀티 에이전트 워크플로우 플랫폼. 단일 에이전트 → 정적 워크플로우 → 동적 워크플로우 순으로 점진 확장한다.

Stack

  • Backend: Python 3.12, FastAPI, LangGraph, LangChain chat models, uv
  • Frontend: React 18 + TypeScript + Vite, Tailwind v4, lucide-react, custom components
  • LLM: 멀티 프로바이더 (Anthropic / OpenAI / Google) — backend/config/llm.yaml 카탈로그 기반

Layout

모노레포. backend/frontend/ 는 IDE에서 각자 자기 폴더만 열어 작업한다.

multi-agent-system/
  backend/                  ← PyCharm 등으로 이 폴더를 연다
    pyproject.toml
    uv.lock
    .python-version
    .env / .env.example
    app/                    Python 패키지 (`from app.X import ...`)
      main.py               FastAPI 엔트리
      api/                  HTTP / SSE 엔드포인트
      llm/                  LLM 팩토리 + 모델 카탈로그 로더
      agent_core/           에이전트 레지스트리 + 러너 (graph 모듈로 위임)
      workflow/             워크플로우 YAML 스키마 + 레지스트리
      graph/                워크플로우 상태 / 노드 / 컴파일러 (정적·동적 공용)
      api/                  /chat (SSE) + /graph/{name} (트레이스용)
    agents/                 에이전트 플러그인 (config.yaml + prompt.md)
    workflows/              워크플로우 정의 (YAML DAG, leaf 에이전트 조합)
    config/
      llm.yaml              LLM 프로바이더 / 모델 카탈로그
  frontend/                 ← VSCode 등으로 이 폴더를 연다
    package.json
    vite.config.ts          dev 서버 + /api → :8000 프록시
    src/
      App.tsx               레이아웃 (사이드바 + 메인)
      api/                  /health, /chat (POST + SSE) 클라이언트
      hooks/                useAgents, useChat
      components/           Sidebar / TopBar / MessageList / Composer 등

Quickstart

cd backend

# 의존성 설치 (.venv 자동 생성)
uv sync

# API 키 설정 — .env 파일 생성
cat > .env <<'EOF'
GOOGLE_API_KEY=...
# ANTHROPIC_API_KEY=...
# OPENAI_API_KEY=...
EOF

# 개발 서버
uv run uvicorn app.main:app --reload

백엔드 단독 검증:

  • http://localhost:8000/health — 등록된 모델 / 에이전트 목록
  • http://localhost:8000/docs — Swagger UI 에서 /chat 호출 테스트

Frontend

별도 터미널에서 (백엔드는 계속 켜진 상태):

cd frontend
npm install
npm run dev

http://localhost:5173 에서 콘솔 UI. 프록시가 /api/*http://localhost:8000/* 로 보내므로 CORS 설정 불필요.

빌드 / 타입체크:

npm run typecheck    # tsc -b --noEmit
npm run build        # 프로덕션 번들 → dist/

API

POST /chat

Server-Sent Events 로 응답 토큰을 스트리밍한다.

요청 바디:

{
  "agent": "chat_agent",
  "message": "내 이름은 X 야",
  "thread_id": "선택, 미지정시 자동 생성"
}

이벤트 타입:

  • thread — 첫 이벤트, 사용된 thread_id. 같은 값으로 다음 요청 보내면 이전 대화 컨텍스트 유지
  • token — 모델 출력 청크
  • error — 에러 발생 시 {"type": ..., "message": ...}
  • done — 스트림 종료

대화 상태는 SQLite (backend/var/state.db) 에 저장된다. LangGraph AsyncSqliteSaver 가 체크포인트(메시지 히스토리 + 그래프 상태) 를 담당하고, 별도의 threads 메타데이터 테이블이 사이드바 "최근 대화" 목록 (제목, 에이전트, 메시지 수, 갱신 시각) 을 채운다. 서버 재시작해도 스레드가 살아 있으며, 사이드바에서 클릭하면 이전 대화로 그대로 이어 쓸 수 있다.

에이전트 추가하기

backend/agents/<agent_name>/ 폴더를 만들고 두 파일만 두면 부팅 시 자동 등록된다:

# backend/agents/<agent_name>/config.yaml
name: <agent_name>
kind: agent                # 또는 "supervisor" — 라우팅용 노드
model: gemini-pro          # backend/config/llm.yaml 의 키 참조
temperature: 0.7
prompt: prompt.md
description: <한 줄 설명>

# kind: supervisor 일 때만 사용
delegates_to:
  - researcher
  - writer
  - coder
# backend/agents/<agent_name>/prompt.md
You are ...

레지스트리 / 러너 코드는 건드리지 않는다. kind: supervisor 인 에이전트는 첫 LLM 호출에서 delegates_to 중 하나로 라우팅하고, 선택된 sub-agent 가 사용자에게 답한다. 프런트는 supervisor 만 사이드바에 노출하고, 실제 답변자는 메시지 라벨로 표시한다.

MCP 도구 연결

backend/config/mcp.yaml 에 서버 등록 → 에이전트가 mcp_servers: [<name>] 로 화이트리스트.

# backend/config/mcp.yaml
servers:
  filesystem:
    transport: stdio
    command: npx
    args: ["-y", "@modelcontextprotocol/server-filesystem", "~/agent-workspace"]
    description: 파일 읽기·쓰기·탐색
# backend/agents/coder/config.yaml
name: coder
kind: agent
mcp_servers:
  - filesystem        # ← 이 에이전트가 사용할 서버

앱 부팅 시 모든 MCP 서버에 연결해서 도구 목록 한 번 가져오고 캐시. 에이전트 컴파일 시점에 화이트리스트로 필터링해서 ReAct 에이전트 tools 에 주입. 도구 호출/응답은 tool_call / tool_result SSE 이벤트로 프런트에 흘려보내고, 메시지 안에 인라인 카드로 펼쳐볼 수 있게 렌더.

지원 transport: stdio (서브프로세스), sse, streamable_http. 환경변수 + ~ 확장 지원.

워크플로우 추가하기

backend/workflows/<name>.yaml 파일 하나로 정적 DAG 정의 가능:

name: research_brief
description: <한 줄 설명>

nodes:
  - id: research          # 노드 식별자 (그래프 안에서만 유효)
    agent: researcher     # 등록된 leaf 에이전트 이름
  - id: refine
    agent: writer

edges:
  - from: __start__
    to: research
  - from: research
    to: refine
  - from: refine
    to: __end__

부팅 시 자동 등록되어 /chatagent 파라미터로 호출 가능 (워크플로우와 에이전트는 같은 네임스페이스, 워크플로우가 우선). 트레이스 인스펙터 (오른쪽 사이드 패널) 에서 실행 중 활성 노드가 실시간으로 강조됨.

LLM 프로바이더 추가하기

  1. backend/config/llm.yamlproviders: / models: 에 항목 추가
  2. backend/app/llm/factory.pybuild_chat_model() match 문에 새 case 한 개 추가

이 두 곳 외에 LLM 프로바이더를 알아야 하는 코드는 없다.

Roadmap

  • Step 0 — 디렉토리 / 컨벤션 / LLM 팩토리 / 에이전트 레지스트리 골격
  • Step 1 — /chat SSE + LangGraph ReAct 단일 에이전트 + 인메모리 체크포인터
  • Step 2 — React + Vite 콘솔 UI (에이전트 선택, 토큰 스트리밍, thread 유지, 에러 인라인 표시)
  • Step 3 — 에이전트 실행을 그래프 노드 추상으로 리팩터 (정적/동적 공용 인프라)
  • Step 4 — 동적 워크플로우 (슈퍼바이저 + 서브에이전트 라우팅, LLM이 다음 단계 결정)
  • Step 5 — 정적 워크플로우 (YAML DAG → LangGraph 컴파일러, backend/workflows/*.yaml)
  • Step 6 (lite) — 트레이스 인스펙터 (그래프 토폴로지 + 활성 노드 실시간 강조)
  • Step 6 (full) — 드래그&드롭 워크플로우 편집기 (필요해지면)

After Foundation

트랙 상태 설명
MCP 통합 ✅ v1 filesystem MCP 서버 연동, 에이전트별 화이트리스트, 도구 호출/응답 SSE 이벤트, 프런트 inline 카드 렌더
영속 저장 ✅ v1 AsyncSqliteSaver 체크포인터 + threads 메타데이터 테이블, 사이드바 "최근 대화" 클릭 시 리플레이, 삭제 지원 (검색은 후속)
관측성 토큰/비용/지연 per-turn, OpenTelemetry → Langfuse/Phoenix
인증/멀티유저 SSO, 워크스페이스, RBAC (이때 Spring Boot BFF 도입 검토)
UX 폴리시 다크모드, syntax highlighting, 메시지 편집/재실행, 모바일
워크플로우 라이브러리 워크플로우 저장/공유/복제, 템플릿, 버전관리

About

MAS

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors