AI 코드 생성 코파일럿 구현: 컨텍스트 인식 코드 완성

AI 기술

AI 코드 생성코파일럿LLM코드 완성개발자 도구

이 글은 누구를 위한 것인가

  • 사내 코드베이스에 특화된 AI 코파일럿을 만들려는 팀
  • LLM 기반 코드 완성/생성 도구를 개발하는 팀
  • AI로 코드 리뷰와 테스트 자동화를 구현하려는 개발자

들어가며

GitHub Copilot은 범용이다. 사내 코딩 컨벤션, 내부 라이브러리, 도메인 용어를 모른다. 사내 코드베이스를 RAG로 인덱싱하고 LLM에 컨텍스트를 제공하면 프로젝트 특화 코파일럿을 만들 수 있다.

이 글은 bluefoxdev.kr의 AI 코드 생성 코파일럿 구현 가이드 를 참고하여 작성했습니다.


1. 코파일럿 아키텍처

[컨텍스트 수집 계층]
  현재 파일 코드 (커서 위치 기준 앞뒤 50줄)
  열린 파일 목록 (관련 파일)
  현재 선택 영역
  최근 편집 이력

[코드베이스 RAG]
  인덱싱: AST 기반 함수/클래스 단위 청킹
  임베딩: 코드 특화 모델 (CodeBERT, Voyage)
  검색: 현재 컨텍스트와 유사한 코드 조각

[생성 유형]
  인라인 완성: 현재 줄/함수 완성
  함수 생성: 시그니처 기반 구현
  테스트 생성: 함수 보고 테스트 작성
  리팩터링: 선택 영역 개선
  주석 생성: 코드 설명 자동화

[VS Code 확장]
  Language Server Protocol (LSP)
  InlineCompletionProvider
  CodeActionProvider (리팩터링, 테스트)

2. 코파일럿 구현

import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic();

interface CodeContext {
  filePath: string;
  language: string;
  beforeCursor: string; // 커서 앞 코드
  afterCursor: string;  // 커서 뒤 코드
  relevantCode?: string; // RAG 검색 결과
  imports?: string;
}

// 인라인 코드 완성
async function generateInlineCompletion(ctx: CodeContext): Promise<string> {
  const systemPrompt = `당신은 ${ctx.language} 코드 완성 AI입니다.
커서 위치에 들어갈 코드만 생성하세요. 설명 없이 코드만 반환하세요.
프로젝트 컨텍스트를 따르세요.`;

  const stream = await client.messages.stream({
    model: 'claude-haiku-4-5-20251001', // 빠른 완성
    max_tokens: 256,
    system: systemPrompt,
    messages: [{
      role: 'user',
      content: `파일: ${ctx.filePath}
언어: ${ctx.language}

관련 코드:
\`\`\`${ctx.language}
${ctx.relevantCode ?? ''}
\`\`\`

현재 코드 (커서 위치: [HERE]):
\`\`\`${ctx.language}
${ctx.beforeCursor}[HERE]${ctx.afterCursor}
\`\`\`

[HERE] 위치에 들어갈 코드를 완성하세요.`,
    }],
    temperature: 0.1,
  });

  return stream.finalText();
}

// 함수 테스트 자동 생성
async function generateTests(functionCode: string, language: string): Promise<string> {
  const testFrameworks: Record<string, string> = {
    typescript: 'Vitest',
    python: 'pytest',
    java: 'JUnit 5',
    go: 'testing package',
  };

  const response = await client.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 2048,
    messages: [{
      role: 'user',
      content: `다음 ${language} 함수에 대한 완전한 단위 테스트를 ${testFrameworks[language] ?? 'testing framework'}으로 작성하세요.

\`\`\`${language}
${functionCode}
\`\`\`

다음을 포함하세요:
- 정상 케이스 (happy path)
- 경계 값 테스트
- 에러 케이스
- 목(mock) 처리 (필요 시)

테스트 코드만 반환하세요.`,
    }],
    temperature: 0.2,
  });

  return response.content[0].type === 'text' ? response.content[0].text : '';
}

// 보안 취약점 감지
async function detectVulnerabilities(code: string, language: string): Promise<{
  vulnerabilities: { type: string; line: number; description: string; fix: string }[];
}> {
  const response = await client.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 1024,
    messages: [{
      role: 'user',
      content: `다음 ${language} 코드에서 보안 취약점을 찾아 JSON으로 반환하세요.

\`\`\`${language}
${code}
\`\`\`

형식:
{"vulnerabilities": [{"type": "SQL Injection|XSS|CSRF|...", "line": 줄번호, "description": "설명", "fix": "수정 방법"}]}

취약점이 없으면 {"vulnerabilities": []}를 반환하세요.`,
    }],
    temperature: 0,
  });

  try {
    const text = response.content[0].type === 'text' ? response.content[0].text : '{"vulnerabilities":[]}';
    const match = text.match(/\{[\s\S]*\}/);
    return match ? JSON.parse(match[0]) : { vulnerabilities: [] };
  } catch { return { vulnerabilities: [] }; }
}

// VS Code InlineCompletionProvider 인터페이스
// vscode.languages.registerInlineCompletionItemProvider('typescript', {
//   provideInlineCompletionItems: async (document, position) => {
//     const completion = await generateInlineCompletion({ ... });
//     return [new vscode.InlineCompletionItem(completion)];
//   }
// });

마무리

사내 코파일럿의 핵심은 코드베이스 RAG다. 범용 LLM에 사내 코드 컨텍스트를 제공하면 내부 라이브러리, 컨벤션, 도메인 지식을 반영한 코드를 생성한다. 완성 속도를 위해 claude-haiku를 사용하고, 테스트/보안 감지 같은 무거운 작업은 claude-sonnet을 사용한다.