GitHub·자동화

Windows Runner에서 Linux 명령이 나왔을 때 알게 된 것

AI coding agent에게 저장소를 맡기면 코드는 잘 읽으면서도 의외로 실행 환경은 쉽게 추측한다.

내 자동화는 Windows PC에서 GitHub Actions self-hosted runner를 돌리는 구조였다. 그런데 한 작업에서 agent가 Linux 환경을 전제로 한 명령을 사용했다. 코드 수정 자체보다 먼저 실행 명령에서 작업이 꼬였다.

저장소만 보면 운영체제를 확신하기 어렵다

대부분의 JavaScript나 TypeScript 프로젝트는 Windows, macOS, Linux에서 비슷한 파일 구조를 가진다. package.json만 읽어서는 runner가 어떤 운영체제인지 확신하기 어렵다.

사람은 화면에 PowerShell이 떠 있거나 경로가 C:\... 형태인 걸 보고 바로 Windows라고 알 수 있다. 하지만 agent에게는 그 정보가 작업 입력에 포함되지 않았을 수 있다.

결국 agent는 자신에게 익숙한 셸 명령을 선택한다.

“코드를 수정해”와 “이 환경에서 작업해”는 다른 지시다

처음에는 OS 정보가 너무 기본적이라 굳이 매번 전달할 필요가 없다고 생각했다. 하지만 자동화에서는 기본값을 agent의 추측에 맡기는 순간 불확실성이 생긴다.

그래서 task packet에 최소한 다음 정보는 명시하는 편이 안정적이었다.

  • runner OS
  • 사용할 셸
  • 프로젝트 루트 경로
  • 테스트 및 빌드 명령
  • 금지된 명령이나 작업
  • 수정 가능한 파일 범위

이렇게 하면 agent가 코드를 읽는 데 시간을 쓰면서 동시에 환경을 다시 추론할 필요가 없다.

명령 실패를 바로 다른 수정으로 보상하게 두지 않는다

환경을 잘못 이해해 명령이 실패하면 agent는 종종 다른 방법을 찾는다. 문제는 이때 원래 작업과 상관없는 변경이 시작될 수 있다는 것이다.

예를 들어 테스트 명령이 동작하지 않았다는 이유로 새 테스트 파일을 만들거나, 설정 파일을 바꾸거나, 다른 스크립트를 추가해버릴 수 있다.

그래서 명령 실행 실패는 “다른 방식으로 어떻게든 통과시켜라”가 아니라 환경 불일치 가능성을 먼저 확인해야 하는 신호로 취급하는 게 낫다.

자동화 입력은 프롬프트가 아니라 실행 계약에 가깝다

AI에게 자연어로 친절하게 설명하는 것도 중요하지만, 반복 자동화에서는 변하지 않는 환경 정보를 구조화해서 전달하는 것이 더 효과적이었다.

예를 들어 매 작업마다 “이 PC는 Windows야”라고 대화식으로 설명하는 대신, runner metadata나 task packet에 고정 필드로 넣어두는 방식이다.

이렇게 해두면 어떤 모델로 fallback되더라도 같은 환경 정보를 받는다.

실행 환경도 테스트 대상이다

CI가 통과하는지만 확인하면 코드 품질은 어느 정도 볼 수 있다. 하지만 agent 자동화에서는 CI에 들어가기 전 단계도 테스트해야 한다.

  • 올바른 셸을 사용하는가
  • 저장소 루트에서 명령을 실행하는가
  • 경로 구분자를 잘못 가정하지 않는가
  • 필요한 도구가 설치된 환경인지 확인하는가

자동화가 커질수록 “모델이 알아서 알겠지”라고 맡길 수 있는 영역은 줄어든다. 반복적으로 발생하는 정보는 대화가 아니라 시스템 입력으로 고정하는 편이 훨씬 안전했다.

How this note was made

이 글은 실제 개발 기록을 바탕으로 작성했습니다

일반적인 개발 팁을 재구성한 글이 아니라 Yeomflow의 실제 제품 개발, 배포, 장애 대응, 자동화 과정에서 나온 문제와 결정을 정리합니다. 이후 구현이나 운영 기준이 바뀌면 기존 글도 보강합니다.

작성 원칙과 프로젝트 소개 보기 →