GitHub Copilot Workspace 리뷰: 브라우저 기반의 태스크 레벨 (Task-Level) AI 코딩
요약
GitHub Copilot Workspace의 실제 사용 사례를 통해 명세 우선(Spec-first) 워크플로우와 저장소 인식 능력을 분석합니다. 단순 코드 생성을 넘어 계획 단계에서 환경적 제약과 구조적 문제를 식별하는 도구의 유용성을 검증합니다.
핵심 포인트
- 명세(Specification) 기반의 계획 단계를 통해 코드 생성 전 오류 방지 가능
- 저장소 컨텍스트를 파악하여 환경에 적합한 구현 방안 제안
- 태스크 규모와 초기 명세 작성 품질에 따라 성공률이 크게 좌우됨
- 단순 프롬프트 입력보다 구조적이고 안전한 개발 워크플로우 제공
저는 2026년 5월, 버그 수정, 기능 추가, 문서 업데이트가 혼합된 3개의 리포지토리(Repository)에서 12개의 실제 태스크(Task)를 대상으로 GitHub Copilot Workspace를 테스트했습니다. 저의 목표는 명세 우선(Spec-first), 브라우저 기반 워크플로우가 실제로 유용한 코드를 생성하는지, 아니면 실제 작업을 요청했을 때 무너져 버리는 데모에 불과한지를 파악하는 것이었습니다. 그 답은 인상적임과 답답함 사이 어딘가에 있었으며, 도구의 성공률은 태스크의 규모, 리포지토리의 성숙도, 그리고 초기 명세(Specification)를 얼마나 잘 작성하느냐에 따라 극적으로 달라졌습니다.
명세 우선(Spec-First) 워크플로우는 더 나은 커뮤니케이션을 강제한다
Copilot Workspace는 제가 다른 곳에서는 보지 못한 한 가지 근본적인 방식으로 AI 코딩 상호작용을 변화시킵니다. 즉, 코드로 시작하는 것이 아니라 명세(Specification)로 시작한다는 점입니다. 제가 Next.js 프로젝트에서 Workspace를 열고 "기존의 rate-limit.ts 유틸리티를 사용하여 API 라우트에 속도 제한(Rate limiting)을 추가해줘"라고 입력했을 때, 시스템은 즉시 코드를 생성하지 않았습니다. 시스템은 약 15초 동안 제 리포지토리를 읽은 다음, 다음과 같은 3단계 구현 계획을 생성했습니다: (1) 각 라우트에 rate-limit 유틸리티를 임포트(Import)한다, (2) 라우트 핸들러를 속도 제한기(Rate limiter)로 감싼다, (3) 속도 제한 동작에 대한 테스트를 추가한다.
저는 코드가 작성되기 전에 계획을 있는 그대로 승인하거나, 개별 단계를 거부하거나, 수정 사항(Revision notes)을 추가할 수 있었습니다. 이 특정 태스크의 경우, 계획이 정확했기에 저는 이를 승인했습니다. 그 후 Workspace는 각 단계를 실행하여 5개의 라우트 파일을 수정했고, 명확한 설명과 변경 사항 요약이 포함된 초안 풀 리퀘스트(Pull Request, PR)를 생성했습니다. 명세를 입력하는 것부터 검토 가능한 PR을 얻기까지의 전체 과정은 4분 12초가 소요되었습니다.
이 계획 단계 (Planning phase)는 단순히 보여주기 위한 것이 아닙니다. 제가 Workspace에 "채팅 기능에 WebSocket 지원을 추가해줘"라고 요청한 다른 작업에서, Workspace는 저장소 (Repository)를 읽고 계획 단계에서 이 프로젝트가 지속적인 WebSocket 연결을 지원하지 않는 Vercel의 서버리스 함수 (Serverless functions)에 배포되어 있다는 사실을 찾아냈습니다. 대신 제3자 실시간 서비스와 함께 Vercel의 Edge Functions를 사용할 것을 제안했습니다. 이러한 환경 인식 (Environment-aware) 계획은 제가 즉시 코딩을 시작했다면 저질렀을 실수를 잡아냈습니다. 이 도구는 단순히 코드를 생성한 것이 아니라, 제가 막다른 길로 들어서는 것을 방지했습니다.
제가 테스트한 12개의 작업 중, Workspace의 계획 단계는 코드 생성 전에 구조적 또는 호환성 문제를 3가지 사례에서 식별했습니다. 이는 약 25%의 확률입니다. 계획이 잘못되었을 때, 저는 코드가 변경되기 전에 계획을 수정할 수 있었습니다. 그 사실 하나만으로도 Workspace는 저장소 인식 (Repository awareness) 없이 한 문장의 프롬프트만으로 즉시 코드 생성을 시작하는 도구들보다 더 안전합니다.
저장소 인식 (Repository Awareness)이 더 나은 초안을 만든다
커밋 히스토리 (Commit history), 이슈 논의 (Issue discussions), 기존 PR 리뷰 코멘트, 그리고 파일 구조 등 GitHub의 전체 저장소 컨텍스트 (Repository context)에 대한 Workspace의 접근 권한은 제가 테스트한 그 어떤 AI 도구보다 프로젝트에 더 잘 맞는 코드를 생성합니다. 생성된 코드는 사람이 작성한 코드에서 사용하는 것과 동일한 명명 규칙 (Naming conventions), 파일 구성 패턴, 그리고 에러 처리 (Error handling) 스타일을 준수합니다.
저는 이를 체계적으로 테스트했습니다. 기존의 모든 엔드포인트 (Endpoints)가 에러 처리를 위해 커스텀 handle_errors 데코레이터 (Decorator)를 사용하는 Python FastAPI 프로젝트에서, 저는 Workspace에 새로운 헬스 체크 (Health check) 엔드포인트를 추가해달라고 요청했습니다. 생성된 코드는 별도의 지시 없이도 handle_errors를 사용했는데, 이는 기존 라우트 (Routes)로부터 해당 패턴을 학습했기 때문입니다. 제가 Cursor와 Copilot Chat에 동일한 프롬프트를 입력했을 때, 두 도구 모두 올바른 코드를 생성하기는 했지만 대신 try-except 블록을 사용했습니다. 두 도구 모두 handle_errors가 이 프로젝트의 표준 패턴이라는 것을 알 수 있는 저장소 수준의 컨텍스트 (Repository-level context)를 가지고 있지 않았기 때문입니다.
실행 중 발생하는 자기 수정 루프 (Self-correction loop) 또한 널리 문서화되어 있지 않기에 설명할 가치가 있습니다. Workspace가 프로젝트의 린터 (Linter)나 타입 체커 (Type checker)를 통과하지 못하는 코드를 생성하면, 에러를 다시 읽고, 파일을 수정하여 다시 시도합니다. 저는 TypeScript 작업 중에 생성된 코드가 프로젝트에 더 이상 존재하지 않는 타입을 사용하는 것을 목격했습니다. Workspace는 TypeScript 컴파일 에러를 포착하고, 현재의 타입 정의를 확인한 뒤, 임포트 (Import)를 수정했습니다. 이 모든 과정은 저의 개입 없이 이루어졌습니다. 별도의 작업에서는 자기 수정 루프가 무한 루프에 빠지기도 했습니다. 하나의 ESLint 경고를 수정하면 다른 경고가 발생하고, 두 번째를 수정하면 첫 번째가 다시 발생하는 상황이 세 번 반복된 후에야 제가 직접 개입하여 충돌을 수동으로 해결했습니다.
제 테스트 결과, 자기 수정 성공률은 린트 에러 (Lint errors)의 경우 약 70%, 타입 에러 (Type errors)의 경우 약 60%였습니다. 이 기능이 제대로 작동할 때는 CI가 실패하는 것을 지켜보고, 에러를 읽고, 코드를 수정하고, 다시 푸시 (Push)하는 지루한 사이클을 줄여줍니다. 하지만 실패할 때는 직접 문제를 해결하는 데 쓸 수 있었던 시간을 낭비하게 만듭니다. 저는 실행 로그를 주시하며 루프의 징후를 파악하고, 두 번째 수정 시도가 실패하면 개입하는 법을 배웠습니다.
테스트 생성은 안전망이 아니라 시작점이다
여기서 저는 Workspace가 약속하는 것과 실제로 제공하는 것 사이에 명확한 선을 그어야 합니다. Workspace는 자신이 수행하는 모든 변경 사항에 대해 테스트를 생성하며, 이 테스트들은 프로젝트의 기존 테스트 컨벤션 (Testing conventions)을 따릅니다. Next.js 프로젝트의 경우 Jest, Python 프로젝트의 경우 pytest, Go 프로젝트의 경우 Go의 testing 패키지를 사용합니다. 테스트는 실행되고 통과합니다.
하지만 테스트가 제가 우려하는 방식으로 피상적(shallow)입니다. 12개의 태스크 중 Workspace는 11개에 대해 해피 패스(happy paths)와 한두 개의 명백한 에지 케이스(edge cases)를 다루는 테스트를 작성했습니다. 에러 경계(error boundary), 레이스 컨디션(race condition), 타임아웃 시나리오(timeout scenario) 또는 통합 실패(integration failure)에 대한 테스트는 단 한 번도 작성하지 않았습니다. 속도 제한(rate-limiting) 태스크에서는 속도 제한기가 제한 범위 내의 요청은 허용하고 제한을 초과하는 요청은 차단하는지는 테스트했지만, 시계 왜곡(clock skew)으로 인해 윈도우 중간에 속도 제한 카운터가 재설정되는 케이스는 놓쳤습니다. 파일 업로드 태스크에서는 크기 제한 미만의 파일은 수락되고 제한을 초과하는 파일은 거부되는지는 테스트했지만, 네트워크 오류로 인해 파일 업로드 자체가 실패했을 때 어떤 일이 발생하는지는 전혀 테스트하지 않았습니다.
저는 이것이 Workspace의 버그라고 생각하지 않습니다. 이는 만약 사람이 명세서(specification)를 전달받고 10분 안에 초안을 작성하라는 지시를 받았을 때 작성할 법한 테스트를 작성한 것입니다. 테스트는 방향성 측면에서는 올바르지만, 테스트 커버리지(test coverage)에 대한 인간의 검토를 대체할 수는 없습니다. 만약 Workspace가 생성한 코드를 오직 자체 테스트만으로 검증하여 병합(merge)한다면, 테스트되지 않은 에지 케이스(edge cases)를 배포하게 되는 것입니다. 저는 팀의 코드 리뷰 체크리스트를 기준으로 Workspace가 생성한 각 PR을 검토했으며, 12개의 PR 중 8개가 제가 수동으로 작성해야 하는 추가 테스트를 필요로 한다는 것을 발견했습니다.
도구가 잘못된 지점
Workspace의 최적의 지점(Sweet spot)은 3개에서 5개의 파일을 수정하는 변경 사항입니다. 이 범위 내에서 5개의 태스크(Task)를 실행해 보았는데, 5개 모두 첫 번째 시도에서 정확한 계획(Plan)과 작동하는 코드를 생성했습니다. 여섯 번째 태스크 — 데이터베이스 마이그레이션(Migration), 스키마(Schema) 변경, 프론트엔드(Frontend) 업데이트를 포함한 새로운 API 엔드포인트(Endpoint) 추가 — 는 14개의 파일을 수정해야 했습니다. 제안된 계획은 합리적인 단계들을 제시했지만, 실행 과정에서 세 번째 단계가 아직 적용되지 않은 두 번째 단계의 스키마 변경 사항에 의존하고 있었습니다. Workspace는 이전 스키마를 기준으로 프론트엔드 코드를 생성한 후, 마이그레이션이 실행된 뒤에 이를 수정했지만, 이 수정 과정에서 TypeScript 컴파일러가 잡아내는 타입 불일치(Type mismatch)가 발생했습니다. 자기 수정 루프(Self-correction loop)가 결국 이를 해결하기는 했지만, 이 과정에서 세 번의 수정 사이클이 소요되었고, 결과물로 나온 디프(Diff)는 리뷰어가 검증하는 데 드는 시간이 초기 코드의 가치보다 더 길어질 정도였습니다.
언어 지원은 단순히 코드 출력뿐만 아니라 계획(Planning)의 품질에 영향을 미치는 방식으로 불균형하게 나타납니다. TypeScript와 Python의 경우, 계획이 구체적이고 잘 구조화되어 있었습니다. 실제 파일 이름을 명시하고, 기존 함수를 참조하며, 구체적인 변경 사항을 제안했습니다. 반면 Go의 경우, 계획이 더 일반적이었습니다. 무엇을 변경해야 하는지는 설명했지만, 어디서 어떻게 변경해야 하는지에 대해서는 덜 정밀했습니다. 호기심에 테스트해 본 Rust 프로젝트의 경우, 계획은 파일별 가이드가 없는 본질적으로 상위 수준의 요약에 불과했습니다. Workspace가 Rust 태스크에 대한 코드를 생성하기는 했지만, 계획 단계에서 잡아냈어야 할 오류들이 포함되어 있었습니다.
브라우저 기반의 워크플로 (Workflow)는 의견이 극명하게 갈릴 만큼 논쟁적인 요소이기에 직접 언급할 필요가 있습니다. Workspace 세션 중에는 로컬에서 코드를 편집할 수 없습니다. 계획 (Planning), 실행 (Execution), 그리고 리뷰 (Review)가 전적으로 GitHub의 웹 인터페이스 내에서 이루어집니다. 실행 중에 수동 개입이 필요한 실수를 발견하면, 브라우저 기반의 디프 뷰어 (Diff viewer)를 통해 수정해야 합니다. 이 뷰어는 기능적이긴 하지만 대규모 편집을 하기에는 편하지 않습니다. 아니면 세션을 중단하고, 로컬에서 코드를 수정한 뒤 다시 시도해야 합니다. 저는 태스크당 적어도 한 번은 코드를 에디터에서 열고 싶다는 생각이 들었고, 그렇게 할 수 없다는 점 때문에 이 경험이 자유롭기보다는 제약이 많다고 느껴졌습니다.
Workspace를 사용하는 경우와 건너뛰는 경우
12개의 태스크를 수행한 후, 저의 행동 패턴은 명확하게 자리 잡았습니다. 성숙한 저장소 (Repository)에 범위를 잘 설정한 기능을 추가할 때 — 이미 유사한 옵션이 존재하는 곳에 설정 옵션을 추가하거나, 기존 엔드포인트를 모방하는 새로운 API 엔드포인트를 구현하거나, 기존 문서 구조를 따르는 문서 페이지를 추가하는 경우 — 저는 가장 먼저 Workspace를 찾습니다. 계획 단계에서 제가 놓칠 수 있는 환경 특화적인 문제들을 잡아내고, 생성된 코드는 프로젝트의 컨벤션 (Convention)을 따르며, 초안 PR (Draft PR) 형식은 팀의 리뷰 프로세스와 깔끔하게 통합됩니다.
새로운 패턴을 도입하는 그린필드 (Greenfield) 기능, 8개 이상의 파일에 영향을 미치는 아키텍처 변경, 또는 컨벤션이 일관되지 않은 저장소에서의 작업의 경우, 저는 Workspace를 건너뛰고 수동으로 코딩합니다. 약 8개 이상의 파일이 넘어가면 계획 단계의 일관성이 떨어지고, 자기 수정 루프 (Self-correction loop)는 시간을 절약해 주는 대신 시간을 잡아먹는 요소가 되며, 브라우저 기반의 편집 방식은 수동 개입을 필요 이상으로 고통스럽게 만들기 때문입니다.
제가 발견한 가장 흥미로운 유스케이스 (use case)는 온보딩 (onboarding)입니다. 새로운 팀원이 어떤 유틸리티 (utility)를 사용해야 할지, 어떤 파일을 수정해야 할지, 혹은 어떤 테스트 패턴 (testing patterns)을 따라야 할지 모르는 상태에서 엔드포인트 (endpoint)에 속도 제한 (rate limit)을 추가하는 방법을 제게 물었을 때, 저는 그들에게 Workspace를 열어 직접 사양 (specification)을 작성하고, 생성된 계획 (plan)을 검토하며, 결과물로 나온 PR (Pull Request)을 훑어보도록 했습니다. 이 계획은 제가 직접 설명해 주는 것보다 더 빠르게 프로젝트의 컨벤션 (conventions)을 익히게 해주었으며, 생성된 테스트들은 우리가 사용하는 테스트 패턴을 보여주었습니다. Workspace는 자율적인 개발자 (autonomous developer)로서보다 교육 도구로서 더 효과적으로 작동했으며, 도구의 개발 팀이 더 큰 작업에 대한 계획 단계 (planning phase)의 신뢰성을 개선함에 따라 이러한 유스케이스가 더욱 늘어날 것으로 기대합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기