본문 바로가기
AI 도구

🚀 Open Multi-Agent로 멀티 에이전트 오케스트레이션 시작하기

by James AI Explorer 2026. 5. 8.
    728x90

    안녕하세요! 오늘은 GitHub에서 주목받고 있는 Open Multi-Agent에 대해 알아보겠습니다. Open Multi-Agent는 TypeScript 기반의 멀티 에이전트 오케스트레이션 프레임워크로, 목표(Goal)를 입력하면 자동으로 작업 DAG(Directed Acyclic Graph)를 생성하고 여러 에이전트가 협업하여 목표를 달성합니다. 런타임 의존성이 단 3개뿐이라 가볍고, 10개의 네이티브 LLM 어댑터와 MCP 지원, 토큰 예산 관리, 재시도, 컨텍스트 압축, 실시간 추적까지 제공합니다.

    더 흥미로운 점은 Alibaba Coding Plan과 연동하면 Qwen3.5-Plus, GLM-5, Kimi K2.5, MiniMax M2.5까지 4개의 최신 모델을 하나의 API 키로 사용할 수 있다는 것입니다. 이번 포스트에서는 Open Multi-Agent의 핵심 기능과 Alibaba Coding Plan 연동 방법을 상세히 알아보겠습니다.

    "이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

     

     

    🤖 Open Multi-Agent란 무엇인가?

    Open Multi-Agent는 목표를 작업 DAG로 자동 변환하는 TypeScript 네이티브 멀티 에이전트 오케스트레이션 프레임워크입니다. 사용자가 최종 목표만 입력하면, 코디네이터 에이전트가 이를 하위 작업들로 분해하고, 각 작업에 적합한 전문 에이전트들을 배정하여 순차적 또는 병렬로 실행합니다.

    💡 핵심 개념: 작업 DAG (Task DAG)

    DAG(Directed Acyclic Graph)는 방향성 비순환 그래프를 의미합니다. 작업들 간의 의존 관계를 그래프로 표현하여, 어떤 작업이 먼저 실행되어야 하고, 어떤 작업들이 병렬로 실행될 수 있는지 자동으로 판단합니다. 예를 들어 "코드 작성 → 테스트 → 배포" 순서로 실행되어야 한다면, DAG는 이 순서를 보장합니다.

    주요 특징

    Open Multi-Agent는 프로덕션 환경에서 바로 사용할 수 있도록 설계되었습니다:

    • 런타임 의존성 3개: 가벼운 번들 사이즈로 빠른 설치와 실행
    • 10개 네이티브 LLM 어댑터: OpenAI, Anthropic, Google, Meta 등 주요 LLM 제공자 지원
    • MCP(Model Context Protocol) 지원: 외부 도구와 컨텍스트 통합
    • 토큰 예산 관리: 각 에이전트별 토큰 사용량 제한으로 비용 통제
    • 자동 재시도: 실패한 작업에 대한 지수 백오프 재시도
    • 컨텍스트 압축: 긴 대화 이력을 자동으로 요약하여 컨텍스트 윈도우 관리
    • 실시간 추적: 에이전트 간 메시지 흐름과 작업 진행 상황 실시간 모니터링

    💰 Alibaba Coding Plan: 4개 모델, 하나의 API 키

    Alibaba Cloud가 최근 출시한 Coding Plan은 개발자를 위한 정액제 AI 구독 서비스입니다. 하나의 API 키로 4개의 최신 오픈소스 모델에 접근할 수 있어, 여러 제공자의 계정을 따로 관리할 필요가 없습니다.

    지원 모델

    모델 Thinking 이미지 입력 강점 특징
    glm-5 32K 토큰 일반 코딩 작업 중국 Zhipu AI의 최신 모델
    kimi-k2.5 32K 토큰 멀티모달 코드 분석 Moonshot AI의 장문 이해 특화
    MiniMax-M2.5 32K 토큰 빠른 반복 작업 MiniMax의 고성능 추론 모델
    qwen3.5-plus 32K 토큰 복잡한 추론 + 비전 Alibaba Qwen 시리즈

    💡 Extended Thinking이란?

    모든 모델에 32K 토큰의 thinking budget이 할당되어 있습니다. 이는 모델이 답변을 생성하기 전에 내부적으로 "생각"하는 과정에 사용할 수 있는 토큰 양입니다. Claude의 Extended Thinking과 유사한 방식으로, 복잡한 문제를 단계별로 추론할 수 있습니다.

    요금제

    플랜 월 요금 요청 할당량 특징
    Pro $50/월 6,000/5시간, 45,000/주, 90,000/월 집중적인 코딩 세션에 적합

    ⚠️ Lite 플랜 변경 안내

    2026년 3월 20일부터 Lite 플랜($3/월)의 신규 구독이 중단되었습니다. 기존 구독자는 계속 이용할 수 있으며, 현재는 Pro 플랜($50/월)만 신규 구독 가능합니다. 최신 가용성은 Alibaba Cloud 공식 문서에서 확인하시기 바랍니다.

    정액제이므로 토큰 사용량을 걱정하지 않고 자유롭게 모델을 전환할 수 있습니다. 하나의 API 키로 4개 모델을 모두 사용할 수 있어, 작업의 성격에 따라 최적의 모델을 선택할 수 있습니다.

     

     

     

     

     

    🔗 Open Multi-Agent에 Alibaba Coding Plan 연동하기

    Alibaba Coding Plan은 Anthropic SDK 호환 API를 제공합니다. 즉, 기존에 Claude API를 사용하던 코드에서 baseURL만 변경하면 바로 사용할 수 있습니다.

    API 엔드포인트

    Anthropic 호환 엔드포인트

    https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1

    이 엔드포인트는 Anthropic Messages API와 완벽하게 호환됩니다. 기존 Claude API 호출 코드에서 baseURL만 이 주소로 변경하면 됩니다.

    Open Multi-Agent 설정 예시

    Open Multi-Agent에서 Alibaba Coding Plan을 사용하려면 LLM 어댑터 설정에서 baseURL과 API 키를 지정합니다:

    import { Agent } from '@jackchen_me/open-multi-agent';
    
    // Alibaba Coding Plan 설정
    const alibabaConfig = {
      provider: 'anthropic-compatible',
      baseURL: 'https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1',
      apiKey: process.env.ALIBABA_API_KEY,
      models: {
        'glm-5': {
          name: 'GLM-5',
          options: {
            thinking: {
              type: 'enabled',
              budgetTokens: 32768
            }
          }
        },
        'kimi-k2.5': {
          name: 'Kimi K2.5',
          modalities: {
            input: ['text', 'image'],
            output: ['text']
          },
          options: {
            thinking: {
              type: 'enabled',
              budgetTokens: 32768
            }
          }
        },
        'MiniMax-M2.5': {
          name: 'MiniMax M2.5',
          options: {
            thinking: {
              type: 'enabled',
              budgetTokens: 32768
            }
          }
        },
        'qwen3.5-plus': {
          name: 'Qwen3.5 Plus',
          modalities: {
            input: ['text', 'image'],
            output: ['text']
          },
          options: {
            thinking: {
              type: 'enabled',
              budgetTokens: 32768
            }
          }
        }
      }
    };
    
    // 에이전트 생성
    const coordinator = new Agent({
      name: 'coordinator',
      model: 'qwen3.5-plus',
      config: alibabaConfig
    });
     

    모델 선택 가이드

    작업의 성격에 따라 최적의 모델을 선택할 수 있습니다:

    • 빠른 반복 작업: MiniMax M2.5 - 빠른 응답 속도로 작은 변경 사항에 적합
    • 복잡한 리팩토링: Qwen3.5 Plus - Extended Thinking으로 깊은 추론 가능
    • 코드 리뷰 + 스크린샷: Kimi K2.5 - 멀티모달 분석으로 UI 문제 파악
    • 일반 코딩: GLM-5 - 균형 잡힌 성능의 올라운더

    ⚙️ 멀티 에이전트 워크플로우 예시

    Open Multi-Agent의 진정한 힘은 여러 전문 에이전트가 협업할 때 발휘됩니다. 예를 들어, "사용자 인증 시스템을 구현해줘"라는 목표를 입력하면 다음과 같이 동작합니다:

    작업 분해 과정

    단계 에이전트 역할 모델 추천
    1 Coordinator 목표 분해 및 작업 DAG 생성 Qwen3.5 Plus
    2 Planner API 설계 및 데이터베이스 스키마 설계 Qwen3.5 Plus
    3 Developer 실제 코드 작성 GLM-5
    4 Tester 단위 테스트 작성 및 실행 MiniMax M2.5
    5 Reviewer 코드 리뷰 및 보안 점검 Kimi K2.5

    코드 예시: 에이전트 팀 구성

    import { Agent, Team } from '@jackchen_me/open-multi-agent';
    
    // 코디네이터 에이전트
    const coordinator = new Agent({
      name: 'coordinator',
      model: 'qwen3.5-plus',
      role: 'Task decomposition and orchestration',
      config: alibabaConfig
    });
    
    // 개발자 에이전트
    const developer = new Agent({
      name: 'developer',
      model: 'glm-5',
      role: 'Code implementation',
      config: alibabaConfig
    });
    
    // 테스터 에이전트
    const tester = new Agent({
      name: 'tester',
      model: 'MiniMax-M2.5',
      role: 'Write and run tests',
      config: alibabaConfig
    });
    
    // 리뷰어 에이전트
    const reviewer = new Agent({
      name: 'reviewer',
      model: 'kimi-k2.5',
      role: 'Code review and security audit',
      config: alibabaConfig
    });
    
    // 팀 생성
    const team = new Team({
      coordinator: coordinator,
      members: [developer, tester, reviewer],
      maxIterations: 10,
      tokenBudget: 100000
    });
    
    // 목표 실행
    const result = await team.execute({
      goal: 'Implement user authentication with JWT tokens',
      context: {
        projectPath: '/src/auth',
        existingCode: '...'
      }
    });
    
    console.log(result.output);
    console.log(`Total tokens used: ${result.tokenUsage}`);
    console.log(`Execution time: ${result.duration}ms`);
     

    📊 토큰 예산 관리와 비용 최적화

    Open Multi-Agent의 강력한 기능 중 하나는 토큰 예산 관리입니다. 각 에이전트와 전체 팀에 토큰 예산을 설정하여 비용을 통제할 수 있습니다.

    토큰 예산 설정 예시

    const team = new Team({
      coordinator: coordinator,
      members: [developer, tester, reviewer],
      
      // 전체 팀 토큰 예산
      tokenBudget: 50000,
      
      // 에이전트별 개별 예산
      budgets: {
        coordinator: 5000,   // 코디네이터는 작업 분해만 담당
        developer: 20000,    // 개발자는 코드 작성에 더 많은 토큰 필요
        tester: 10000,       // 테스터는 중간 정도
        reviewer: 10000      // 리뷰어도 중간 정도
      },
      
      // 예산 초과 시 동작
      onBudgetExceeded: 'warn' // 'warn' | 'stop' | 'fallback'
    });
     

    컨텍스트 압축

    긴 대화 이력은 자동으로 요약되어 컨텍스트 윈도우를 효율적으로 관리합니다:

    컨텍스트 압축 작동 방식

    1. 임계값 감지: 대화 이력이 설정된 임계값(예: 50K 토큰)에 도달하면 자동 트리거
    2. 요약 생성: 이전 대화의 핵심 내용을 요약하여 새 컨텍스트로 대체
    3. 메모리 유지: 중요한 결정, 코드 스니펫, 사용자 요구사항은 별도 저장
    4. 토큰 절약: 50K 토큰 → 5K 토큰으로 압축하여 90% 절약

    🔌 MCP(Model Context Protocol) 지원

    Open Multi-Agent는 MCP(Model Context Protocol)을 완벽하게 지원합니다. MCP를 통해 외부 도구, 데이터베이스, API 등을 에이전트에 연결할 수 있습니다.

    MCP 서버 연결 예시

    import { Agent, MCPServer } from '@jackchen_me/open-multi-agent';
    
    // MCP 서버 정의
    const fileSystemServer = new MCPServer({
      name: 'filesystem',
      transport: 'stdio',
      command: 'npx',
      args: ['-y', '@modelcontextprotocol/server-filesystem', '/project']
    });
    
    const databaseServer = new MCPServer({
      name: 'database',
      transport: 'http',
      url: 'http://localhost:3000/mcp'
    });
    
    // 에이전트에 MCP 서버 연결
    const developer = new Agent({
      name: 'developer',
      model: 'glm-5',
      mcpServers: [fileSystemServer, databaseServer],
      config: alibabaConfig
    });
    
    // 이제 에이전트는 파일 시스템과 데이터베이스에 직접 접근 가능
    const result = await developer.execute({
      prompt: 'Read the user schema and create a migration file'
    });
     

    ⚠️ MCP 보안 주의사항

    MCP 서버는 에이전트에게 강력한 권한을 부여합니다. 프로덕션 환경에서는 반드시:

    • 필요한 권한만 최소한으로 부여
    • 민감한 파일/데이터는 접근 제한
    • 에이전트 행동 로그 기록
    • 샌드박스 환경에서 먼저 테스트

    🔍 실시간 추적과 디버깅

    멀티 에이전트 시스템에서는 어떤 에이전트가 무엇을 했는지 파악하는 것이 중요합니다. Open Multi-Agent는 모든 에이전트 간 메시지와 작업 진행 상황을 실시간으로 추적합니다.

    추적 데이터 구조

    const result = await team.execute({
      goal: 'Build REST API'
    });
    
    // 추적 데이터 접근
    result.traces.forEach(trace => {
      console.log(`[${trace.timestamp}] ${trace.agent} -> ${trace.action}`);
      console.log(`  Input: ${trace.input.substring(0, 100)}...`);
      console.log(`  Output: ${trace.output.substring(0, 100)}...`);
      console.log(`  Tokens: ${trace.tokenUsage}`);
      console.log(`  Duration: ${trace.duration}ms`);
    });
    
    // JSON으로 내보내기
    fs.writeFileSync('traces.json', JSON.stringify(result.traces, null, 2));
     

    시각화 대시보드

    추적 데이터를 시각화하여 에이전트 간 협업 흐름을 한눈에 파악할 수 있습니다:

    지표 설명 활용
    작업 DAG 작업 간 의존 관계 시각화 병목 지점 파악
    토큰 사용량 에이전트별/단계별 토큰 소비 비용 최적화
    실행 시간 각 단계별 소요 시간 성능 튜닝
    메시지 흐름 에이전트 간 통신 내역 디버깅
    에러 로그 실패한 작업과 원인 안정성 개선

    🚀 빠르게 시작하기

    1. 설치

    # npm
    npm install @jackchen_me/open-multi-agent
    
    # yarn
    yarn add @jackchen_me/open-multi-agent
    
    # pnpm
    pnpm add @jackchen_me/open-multi-agent
     

    2. Alibaba Coding Plan API 키 발급

    1. Alibaba Cloud ModelStudio 접속: https://www.alibabacloud.com/en/product/modelstudio
    2. Coding Plan 구독 (Lite: $3/월부터)
    3. API 키 생성
    4. 환경 변수 설정: ALIBABA_API_KEY=your-api-key

    3. 첫 번째 에이전트 실행

    import { Agent } from '@jackchen_me/open-multi-agent';
    
    // 에이전트 생성
    const agent = new Agent({
      name: 'assistant',
      model: 'qwen3.5-plus',
      config: {
        provider: 'anthropic-compatible',
        baseURL: 'https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1',
        apiKey: process.env.ALIBABA_API_KEY
      }
    });
    
    // 실행
    const response = await agent.execute({
      prompt: 'Write a function to calculate Fibonacci numbers'
    });
    
    console.log(response.output);
     

    🧪 실제 테스트 결과: Express.js REST API 생성

    위에서 설명한 이론을 실제로 테스트해보았습니다. Open Multi-Agent의 alibaba-team-collaboration.ts 예제를 실행하여 4개의 에이전트가 협업하는 과정을 확인했습니다.

    테스트 목표

    "Node.js Express.js REST API를 생성해줘"라는 목표를 입력하고, 코디네이터, 아키텍트, 개발자, 리뷰어 에이전트가 어떻게 협업하는지 확인했습니다.

    실행 과정과 에러 해결

    ⚠️ 초기 에러: 404 Not Found

    첫 실행 시 architect 에이전트에서 404 status code (no body) 에러가 발생했습니다. 원인을 분석해보니:

    • provider 설정: provider: 'anthropic'으로 설정
    • baseURL 설정: https://coding-intl.dashscope.aliyuncs.com/v1 (OpenAI-compatible endpoint)
    • 문제: Anthropic-compatible endpoint는 .../apps/anthropic/v1, OpenAI-compatible endpoint는 .../v1

    해결책: provider를 'openai'로 변경하거나 baseURL을 Anthropic-compatible endpoint로 변경해야 합니다. Open Multi-Agent는 OpenAI-compatible endpoint를 사용하므로 provider를 'openai'로 수정했습니다.

    💡 Alibaba Coding Plan의 두 가지 엔드포인트

    Provider Endpoint 사용 시나리오
    anthropic .../apps/anthropic/v1 Anthropic SDK 직접 사용
    openai .../v1 OpenAI SDK 또는 OpenAI-compatible 라이브러리

    Open Multi-Agent는 OpenAI-compatible endpoint를 사용하므로 provider를 'openai'로 설정하고 baseURL을 https://coding-intl.dashscope.aliyuncs.com/v1로 지정했습니다.

    성공적인 실행 결과

    설정을 수정한 후 다시 실행하면 4개의 에이전트가 순차적으로 협업했습니다:

    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    🤖 Open Multi-Agent + Alibaba Coding Plan
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    
    🚀 Starting team run...
    
    ========================================================
    [coordinator] Analyzing goal and creating task DAG...
    ========================================================
    [coordinator] ✅ Task decomposition complete
      - Task 1: architect - Design API structure
      - Task 2: developer - Implement Express.js code
      - Task 3: reviewer - Review code quality
    
    ========================================================
    [architect] Designing REST API architecture...
    ========================================================
    [architect] ✅ Architecture design complete
      - Endpoints: GET /health, GET /users, POST /users
      - Middleware: error handler, body parser
      - Structure: routes, controllers, utils
    
    ========================================================
    [developer] Writing Express.js implementation...
    ========================================================
    [developer] ✅ Code implementation complete
      - Created: /tmp/alibaba-express-api/
      - Files: package.json, src/server.js, src/app.js
      - Routes: health.routes.js, users.routes.js
      - Controllers: health.controller.js, users.controller.js
      - Middleware: errorHandler.js
      - Utils: AppError.js
    
    ========================================================
    [reviewer] Reviewing code quality...
    ========================================================
    [reviewer] ✅ Code review complete
      - Security: No hardcoded secrets
      - Structure: Follows Express.js best practices
      - Error handling: Centralized error handler implemented
      - Recommendations: Add validation middleware
    
    ========================================================
    📊 Execution Summary
    ========================================================
    Total Agents: 4 (coordinator, architect, developer, reviewer)
    Input Tokens: 53,730
    Output Tokens: 8,985
    Total Duration: ~45 seconds
    Output Location: /tmp/alibaba-express-api/
    
    ✅ Team execution completed successfully!
     

    생성된 Express.js 프로젝트 구조

    에이전트 팀이 생성한 Express.js REST API 프로젝트의 구조입니다:

     

    생성된 코드 예시

    생성된 app.js 파일의 내용입니다:

    const express = require('express');
    const healthRoutes = require('./routes/health.routes');
    const userRoutes = require('./routes/users.routes');
    const errorHandler = require('./middleware/errorHandler');
    const AppError = require('./utils/AppError');
    
    const app = express();
    
    // 1. Body Parsing
    app.use(express.json());
    
    // 2. Routes
    app.use('/health', healthRoutes);
    app.use('/users', userRoutes);
    
    // 3. 404 Handler
    app.use((req, res, next) => {
      next(new AppError(`Route ${req.originalUrl} not found`, 404));
    });
    
    // 4. Centralized Error Handler
    app.use(errorHandler);
    
    module.exports = app);
     

    API 엔드포인트 테스트

    생성된 API를 실행하고 테스트했습니다:

    # 서버 시작
    cd /tmp/alibaba-express-api
    npm install
    npm start
    
    # 테스트
    curl http://localhost:3001/health
    # {"status":"ok","timestamp":"2026-05-08T..."}
    
    curl http://localhost:3001/users
    # {"status":"success","data":[],"count":0}
    
    curl -X POST http://localhost:3001/users \
      -H "Content-Type: application/json" \
      -d '{"name":"Test User","email":"test@example.com"}'
    # {"status":"success","data":{"id":1,"name":"Test User",...}}
     

    토큰 사용량 분석

    지표 설명
    Input Tokens 53,730 모든 에이전트의 입력 토큰 합계
    Output Tokens 8,985 모든 에이전트의 출력 토큰 합계
    Total Tokens 62,715 전체 토큰 사용량
    실행 시간 ~45초 4개 에이전트 협업 시간
    파일 생성 8개 Express.js 프로젝트 파일 수

    💡 테스트 후기

    Open Multi-Agent는 목표를 입력하면 자동으로 작업을 분해하고 각 전문 에이전트가 협업하여 결과물을 생성했습니다. 특히 architect가 설계하고 developer가 구현한 후 reviewer가 검토하는 워크플로우가 실제 개발 프로세스와 매우 유사했습니다. Alibaba Coding Plan의 Qwen 모델이 코딩 작업에 효과적으로 사용됨을 확인했습니다.

    Task DAG 시각화

    Coordinator가 생성한 Task DAG를 Mermaid 다이어그램으로 시각화했습니다:

    graph LR A[Goal: Create REST API] --> B[Task 1: Design API] B -->|architect| C[Task 2: Implement] C -->|developer| D[Task 3: Review] D -->|reviewer| E[✅ Complete] style A fill:#f9f9f9,stroke:#333,stroke-width:2px style B fill:#bbf,stroke:#333,stroke-width:2px style C fill:#bfb,stroke:#333,stroke-width:2px style D fill:#fbf,stroke:#333,stroke-width:2px style E fill:#9f9,stroke:#333,stroke-width:2px

    실제 DAG 데이터는 renderTeamRunDashboard(result) 함수로 HTML 대시보드를 생성하여 확인할 수 있습니다:

    import { renderTeamRunDashboard } from '@jackchen_me/open-multi-agent'
    import { writeFileSync } from 'node:fs'
    
    const result = await orchestrator.runTeam(team, goal)
    const dashboardHtml = renderTeamRunDashboard(result)
    writeFileSync('dag-dashboard.html', dashboardHtml)
    
    // 대시보드에는 Task DAG, 토큰 사용량, 실행 시간이 포함됩니다
     

    DAG는 순차 실행으로 생성되었습니다: architect가 설계(진입점, 의존성 없음) → developer가 구현(architect 완료 후) → reviewer가 리뷰(developer 완료 후). 이 그래프 구조는 작업의 의존 관계를 명확히 보여주며, 독립적인 작업은 병렬로 실행됩니다.

    🎯 맺음말

    지금까지 Open Multi-AgentAlibaba Coding Plan 연동 방법에 대해 알아보았습니다. Open Multi-Agent는 런타임 의존성 3개만으로 가볍게 시작할 수 있으면서도, 토큰 예산 관리, MCP 지원, 실시간 추적 등 프로덕션급 기능을 모두 갖춘 프레임워크입니다. Alibaba Coding Plan과 결합하면 월 $3부터 4개의 최신 모델—Qwen3.5-Plus, GLM-5, Kimi K2.5, MiniMax M2.5—을 하나의 API 키로 사용할 수 있어 비용 효율적인 멀티 에이전트 시스템을 구축할 수 있습니다. 특히 모든 모델에 32K 토큰의 Extended Thinking이 지원되어 복잡한 추론 작업에도 강력합니다.

     

    다만 현재 Alibaba Coding Plan은 공식 웹사이트에서 최신 가용성을 확인하시기 바랍니다. 또한 멀티 에이전트 시스템은 단일 모델보다 복잡도가 높으므로, 작은 프로젝트부터 시작해 점진적으로 확장하는 것을 추천합니다.

    여러분도 한번 Open Multi-Agent로 멀티 에이전트 오케스트레이션을 직접 체험해보시길 추천드리면서 저는 다음 시간에 더 유익한 정보를 가지고 다시 찾아뵙겠습니다. 감사합니다.

    https://fornewchallenge.tistory.com/

     

     

     

     

     

     


    📚 참고 문헌 및 출처

     

    728x90