콘텐츠로 이동

Copilot CLI를 사용하여 GPT, Claude 등 다양한 AI 모델을 통합 연결하는 방법

페이지 편집
HagiCode for Windows Microsoft Store artwork
HagiCode for Windows is now on Microsoft Store
HagiCode for Windows is officially live on Microsoft Store. Windows users can install it directly from the storefront and stay on the store-managed update path. Open the listing and take a look.
Open Microsoft Store

Copilot CLI를 사용하여 GPT, Claude 등 다양한 AI 모델을 통합 연결하는 방법

AI 애플리케이션 개발에서 GPT, Claude 등 다양한 모델을 통합된 인터페이스로 연결하는 방법은 무엇일까요? 이 글에서는 Orleans Grain 아키텍처를 기반으로 한 AI 공급자 시스템 설계와 GitHub Copilot CLI 통합 실전 경험을 공유합니다.

배경

현대 AI 애플리케이션 개발에서 최신 GPT 모델 통합은 많은 개발자의 핵심 요구사항입니다. GitHub Copilot CLI는 강력한 도구로, OpenAI의 GPT 시리즈 모델(GPT-4, GPT-5 등)뿐만 아니라 Claude 등 다른 주요 AI 모델도 지원합니다. Copilot CLI를 통해 개발자는 각 모델에 대해 복잡한 통합 로직을 개별적으로 구현할 필요 없이 통일된 명령줄 인터페이스로 다양한 AI 모델을 호출할 수 있습니다.

사실 이것도 낡은 이야기입니다. 각 모델마다 호출 로직을 한 번씩 작성해야 하니, 말하면 말할수록 눈물이 납니다. 아무리 코드를 많이 작성해도 누구든 지겨워할 것이니, 바퀴를 다시 발명하는 것보다 통합된 인터페이스로 모든 것을 해결하는 것이 낫습니다. Copilot CLI는 바로 그런 존재입니다. 당신은 호출만 신경 쓰면, 나머지는 Copilot CLI에 맡기면 됩니다.

핵심 가치:

  • 다양한 AI 모델에 대한 통일된 CLI 인터페이스
  • 세션 관리 및 컨텍스트 유지 지원
  • 내장된 도구 호출 기능(파일 작업, Git 작업 등)
  • 스트리밍 응답 및 실시간 출력 지원

HagiCode 소개

이 글에서 공유하는 솔루션은 HagiCode 프로젝트에서의 실전 경험에서 비롯되었습니다. HagiCode는 AI 코드 어시스턴트 프로젝트로, 개발 과정에서 다양한 AI 모델을 동시에 지원해야 하는 과제에 직면했습니다. 어떤 사용자는 GPT-4를 선호하고, 어떤 사용자는 Claude를 선호하며, 또 어떤 사용자는 최신 GPT-5를 시도하고 싶어 합니다. 각 모델에 대해 별도의 호출 로직을 구현하면 코드가 유지 관리하기 어려워집니다. Copilot CLI의 통합된 인터페이스를 통해 우리는 이러한 다중 모델 지원의 문제를 성공적으로 해결했습니다.

속담대로, 사용자의 취향이 다양하고 모든 사람을 만족시키는 것은 어렵습니다. GPT를 좋아하는 사람, Claude를 선호하는 사람, 그리고 최신 GPT-5를 써야만 하는 사람까지 있습니다. 우리는 각자가 좋아하는 모델을 사용할 수 있게 하려고 합니다. 결국 즐거운 것이 가장 중요하니까요.

시스템 아키텍처 설계

우리는 Orleans Grain 아키텍처를 통해 확장 가능한 AI 공급자 시스템을 구현했으며, 전체 아키텍처는 다음과 같습니다:

┌─────────────────┐
│ 프론트엔드/클라이언트 │
└────────┬────────┘
│
▼
┌─────────────────────────────────┐
│ IGitHubCopilotGrain (인터페이스 계층) │
│ - ExecuteCommandStreamAsync │
│ - RunEditAsync │
│ - CancelAsync │
└────────┬────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ GitHubCopilotGrain (구현 계층) │
│ - 상태 관리 │
│ - 세션 바인딩 │
│ - 응답 매핑 │
└────────┬────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ CopilotAIProvider (공급자 계층) │
│ - 구성 분석 │
│ - 권한 관리 │
│ - 스트리밍 처리 │
└────────┬────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ HagiCode.Libs (공유 런타임) │
│ - Copilot CLI 프로세스 관리 │
│ - 메시지 프로토콜 분석 │
│ - 세션 유지 │
└─────────────────────────────────┘

이 아키텍처의 장점은 계층이 명확하고 책임이 단일하다는 것입니다. 인터페이스 계층은 통일된 AI 서비스 계약을 정의하고, 구현 계층은 Orleans의 분산 상태 관리를 처리하며, 공급자 계층은 Copilot CLI와의 상호 작용 세부 사항을 캡슐화하고, 하위 런타임은 CLI 프로세스와의 통신을 담당합니다.

속담대로, 각자의 역할을 명확히 하여 누가 무엇을 해야 할지 정하고, 엉키지 않게 하는 것입니다. 코드는 한번 엉키면 나중에 수정하기 어려워집니다.

핵심 구성 요소 분석

1. GitHubCopilotGrain: 분산 AI 서비스 인터페이스

Orleans Grain의 구현으로, GitHubCopilotGrain은 분산된 AI 서비스 기능을 제공합니다:

public interface IGitHubCopilotGrain : IGrainWithStringKey
{
/// <summary>
/// 명령을 실행하고 응답을 스트리밍으로 반환
/// </summary>
Task<IAsyncEnumerable<GitHubCopilotResponse>> ExecuteCommandStreamAsync(
string command,
string? heroId = null,
CancellationToken token = default,
string? executionMessageId = null,
string? systemMessage = null,
Dictionary<string, string>? requestSettings = null);
/// <summary>
/// 편집 작업 실행
/// </summary>
Task<IAsyncEnumerable<GitHubCopilotResponse>> RunEditAsync(
string editCommand,
string? heroId = null,
CancellationToken token = default);
/// <summary>
/// 현재 실행 취소
/// </summary>
Task CancelAsync(string heroId);
}

핵심 설계 포인트:

  • IAsyncEnumerable를 사용하여 스트리밍 응답을 지원하고 긴 대기 시간을 방지
  • heroId를 통해 세션 수준의 상태 격리 구현
  • requestSettings를 전달하여 모델 매개변수를 동적으로 구성 지원

2. CopilotAIProvider: 핵심 공급자 구현

CopilotAIProvider는 전체 솔루션의 핵심으로, Copilot CLI와의 모든 상호 작용 로직을 캡슐화합니다:

public class CopilotAIProvider : IAIProvider, IVersionedAIProvider
{
private readonly CopilotOptions _options;
private readonly ICopilotProcessExecutor _executor;
public async IAsyncEnumerable<AIStreamingChunk> SendMessageAsync(
AIRequest request,
string? embeddedCommandPrompt = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
// 실행 옵션 구성
var options = new CopilotOptions
{
Model = request.Model ?? _options.Model,
SessionId = request.Options?.Settings?.GetValueOrDefault("copilotSessionId"),
Timeout = _options.Timeout,
PermissionMode = request.OperationType == AIOperationType.Edit
? CopilotPermissionMode.BypassPermissions
: CopilotPermissionMode.Default
};
// 명령 실행 및 응답 스트리밍 처리
await foreach (var message in _executor.ExecuteAsync(
options, request.Prompt, cancellationToken))
{
yield return BuildChunk(message);
}
}
}

핵심 기능:

  • 자동 재시도 메커니즘: 일시적인 네트워크 문제 및 CLI 프로세스 예외 처리
  • 추론 콘텐츠 추적: 모델의 추론 과정(reasoning 필드) 캡처
  • 다양한 메시지 유형 처리: assistant, tool.started, tool.completed 등 메시지 지원
  • 권한 모드 전환: 편집 작업은 자동으로 bypassPermissions 사용, 일반 쿼리는 default 사용

3. CopilotOptions: 유연한 구성 시스템

구성 클래스는 다양한 옵션 설정을 지원합니다:

public class CopilotOptions
{
/// <summary>
/// 사용할 모델 지정(예: "gpt-4", "gpt-5", "claude-opus-4.5")
/// </summary>
public string Model { get; set; } = "gpt-4";
/// <summary>
/// Copilot CLI 실행 파일 경로
/// </summary>
public string ExecutablePath { get; set; } = "copilot";
/// <summary>
/// 세션 만료 시간
/// </summary>
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(1800);
/// <summary>
/// 인증 방식
/// </summary>
public CopilotAuthSource AuthSource { get; set; } = CopilotAuthSource.LoggedInUser;
/// <summary>
/// 권한 모드
/// </summary>
public CopilotPermissionMode PermissionMode { get; set; } = CopilotPermissionMode.Default;
/// <summary>
/// 세션 ID, 컨텍스트 유지용
/// </summary>
public string? SessionId { get; set; }
/// <summary>
/// 도구 권한 구성
/// </summary>
public CopilotToolPermissions? Permissions { get; set; }
}

구성이란 게 충분하면 되는 것입니다. 아무도 영원히 사용하지 않을 구성을 작성하고 싶어 하지 않을 테니까요. 대부분의 시나리오를 커버하면 충분합니다.

구성 가이드

1. 기본 구성

appsettings.json에 Copilot 공급자 구성 추가:

{
"AI": {
"Providers": {
"Providers": {
"GitHubCopilot": {
"Enabled": true,
"ExecutablePath": "copilot",
"Model": "gpt-5",
"Timeout": 1800,
"IdleTimeout": 300,
"UseLoggedInUser": true,
"NoAskUser": true,
"PermissionMode": "default",
"Permissions": {
"AllowAllTools": false,
"AllowAllPaths": false,
"AllowedTools": ["Read", "Bash(git:*)", "Bash(cat:*)"],
"DeniedTools": []
}
}
}
}
}
}

2. 모델 선택

시스템은 다음 모델을 지원합니다(Copilot CLI의 --model 매개변수로 지정):

모델설명권장 시나리오
gpt-4 / gpt-4-turboOpenAI 4세대 모델일반 작업, 가성비 우수
gpt-5OpenAI 최신 5세대 모델복잡한 추론, 최상의 결과 필요
claude-sonnet-4.5Anthropic Sonnet 4.5성능과 비용의 균형
claude-opus-4.5Anthropic Opus 4.5고정밀 작업

HagiCode 실무에서는 기본적으로 GPT-4를 일상 모델로 사용하며, 복잡한 작업(대규모 리팩토링 등)의 경우 GPT-5로 전환하고, Claude 모델은 Anthropic을 선호하는 사용자를 위한 대안으로 제공합니다.

3. 서비스 등록

DI 컨테이너에 관련 서비스 등록:

// Copilot AI 공급자 등록
services.AddSingleton<IAIProvider, CopilotAIProvider>();
// Orleans Grain 등록
services.AddSingleton<IGitHubCopilotGrain, GitHubCopilotGrain>();
// 프로세스 실행기 등록
services.AddSingleton<ICopilotProcessExecutor, CopilotProcessExecutor>();

사실 이 몇 줄의 코드뿐이며, 특별한 것은 없습니다. 필요한 것들을 모두 등록하여 사용할 때 찾을 수 없게 하는 것뿐입니다.

실전 예제

1. 기본 호출

// Grain 가져오기
var grain = grainFactory.GetGrain<IGitHubCopilotGrain>("session-123");
// 명령 실행
await foreach (var response in grain.ExecuteCommandStreamAsync(
"현재 디렉터리의 코드 구조를 분석하고 문서를 생성",
heroId: null,
token: cancellationToken))
{
switch (response.Type)
{
case ExecutorResponseType.Text:
Console.Write(response.Content);
break;
case ExecutorResponseType.ToolCall:
Console.WriteLine($"[도구 호출] {response.ToolName}");
break;
case ExecutorResponseType.Completion:
Console.WriteLine($"\n[완료] 토큰 사용: {response.PromptTokens}+{response.CompletionTokens}");
break;
}
}

2. 컨텍스트가 있는 세션

var requestSettings = new Dictionary<string, string>
{
{ "model", "gpt-5" },
{ "temperature", "0.7" },
{ "maxTokens", "4096" },
{ "copilotSessionId", "existing-session-123" } // 세션 컨텍스트 유지
};
await foreach (var response in grain.ExecuteCommandStreamAsync(
"방금 분석을 기반으로 해당 단위 테스트 생성",
requestSettings: requestSettings,
token: cancellationToken))
{
// 응답 처리
}

3. 편집 모드 호출

await foreach (var response in grain.RunEditAsync(
"모든 PascalCase 명명을 camelCase로 변환",
heroId: "hero-001",
token: cancellationToken))
{
if (response.Type == ExecutorResponseType.FileEdit)
{
Console.WriteLine($"[편집] {response.FilePath}: {response.EditCount}개 수정");
}
}

모범 사례

세션 유지

copilotSessionId 매개변수를 사용하여 요청 간에 컨텍스트를 유지할 수 있으며, 이는 다중 라운드 대화가 필요한 시나리오에서 매우 유용합니다. 예를 들어:

// 첫 번째 라운드: 컨텍스트 설정
var settings1 = new Dictionary<string, string> { { "copilotSessionId", "session-001" } };
await grain.ExecuteCommandStreamAsync("이것은 .NET 8을 사용하는 C# 프로젝트입니다", requestSettings: settings1);
// 두 번째 라운드: 컨텍스트 기반 질문
var settings2 = new Dictionary<string, string> { { "copilotSessionId", "session-001" } };
await grain.ExecuteCommandStreamAsync("적합한 프로젝트 구조를 추천", requestSettings: settings2);

AI도 만능은 아니므로, 컨텍스트가 없으면 당신이 무슨 말을 하는지 어떻게 알겠습니까? 채팅과 마찬가지로 서로 주고받아야 대화가 이어집니다.

권한 제어

작업 유형에 따라 적절한 권한 모드 선택:

  • 쿼리 작업: default 모드를 사용하여 AI가 파일을 읽고 안전한 Git 명령만 실행하도록 함
  • 편집 작업: bypassPermissions 모드를 사용하여 AI가 파일을 수정하도록 허용
var permissionMode = operationType == AIOperationType.Edit
? CopilotPermissionMode.BypassPermissions
: CopilotPermissionMode.Default;

도구 화이트리스트

AllowedTools 구성을 통해 AI가 실행할 수 있는 작업 제어:

{
"Permissions": {
"AllowAllTools": false,
"AllowedTools": [
"Read",
"Bash(git:*)",
"Bash(cat:*)",
"Glob"
]
}
}

HagiCode에서는 AI의 작업 권한을 엄격하게 제한하여 파일 읽기와 Git 명령 실행만 허용하여 시스템 보안을 보장합니다.

보안이란 아무리 주의해도 지나치지 않습니다. AI가 일시적으로 프로젝트 전체를 삭제할지 누가 알겠습니까?

시간 초과 처리

기본 시간 초과는 30분으로 설정되어 있으며, 대량의 파일이 포함된 작업(전체 코드 분석 등)의 경우 조정이 필요할 수 있습니다:

var options = new CopilotOptions
{
Timeout = TimeSpan.FromMinutes(60) // 60분으로 확장
};

자주 묻는 질문

Q: 다른 AI 모델로 어떻게 전환하나요?

A: Model 구성 항목이나 requestSettings로 지정:

var settings = new Dictionary<string, string> { { "model", "claude-opus-4.5" } };

사실 매개변수를 바꾸는 것뿐이며, 복잡한 것은 없습니다.

Q: 세션 컨텍스트는 얼마나 유지되나요?

A: Copilot CLI 구현에 따라 다르며, 일반적으로 세션 유휴 시간 초과(기본값 5분) 후에 정리됩니다. IdleTimeout 구성으로 조정할 수 있습니다.

Q: CLI 프로세스 충돌은 어떻게 처리하나요?

A: CopilotAIProvider에는 자동 재시도 메커니즘이 내장되어 있어 프로세스 예외를捕获하고 CLI를 다시 시작합니다. 연속 실패 횟수가 너무 많으면 AIProviderException이 발생합니다.

프로그램 충돌은 누구도 피할 수 없습니다. 최대한 오류 처리를 잘하고, 정말 죽으면 재시작하면 됩니다.

Q: 사용자 정의 도구를 지원하나요?

A: Copilot CLI가 지원하는 도구는 미리 정의되어 있지만, AllowedTools 구성을 통해 어떤 도구를 사용할 수 있는지 제어할 수 있습니다. 사용자 정의 도구는 Copilot CLI의 향후 업데이트를 기다려야 합니다.

요약

Copilot CLI를 통한 다양한 AI 모델의 통합 연결을 통해 우리는 HagiCode 개발에서 다중 모델 지원 문제를 해결했습니다. 이 솔루션의 핵심 장점은 다음과 같습니다:

  1. 통합 인터페이스: GPT, Claude 등 다양한 모델을 지원하는 단일 코드베이스
  2. 세션 관리: 컨텍스트 유지 및 세션 격리 자동 처리
  3. 도구 통합: 파일 작업, Git 작업 등 일반적으로 사용하는 도구 내장
  4. 스트리밍 응답: AI 출력을 실시간으로 반환하여 사용자 경험 향상
  5. 안전 제어: 세분화된 권한 제어 및 도구 화이트리스트

프로젝트에서 다양한 AI 모델을 지원해야 하거나 성숙한 CLI 도구 통합 솔루션을 찾고 있다면, Copilot CLI를 사용해 보세요. 이 아키텍처는 HagiCode에서 충분히 검증되었으며 프로덕션 환경의 복잡한 요구사항을 지원할 수 있습니다.

각 모델마다 호출 코드를 작성하고 싶은 사람은 누구일까요? 통합된 솔루션이 있으면 모두가 편합니다.

참고 자료

이 글이 도움이 되었다면:

开始使用 HagiCode

一次安装,几分钟上手

HagiCode for Windows 在 Microsoft Store 免费提供。打开商店即可安装并保持更新;也可以先对比各版本与定价,再决定从哪个渠道开始。