이 글은 누구를 위한 것인가
- 사내 코드베이스에 특화된 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을 사용한다.