대화 한 문장이 검증된 ML 모델이 되기까지

LLM, XGENy CLI, 데이터 도구, 격리 실행과 메모리를 연결한 설계. 구현한 경계와 아직 검증하지 못한 부분까지.

왜 챗봇이 아니라 ML 엔지니어링 시스템인가

“모델을 만들어줘”에 학습 코드를 답하는 것과, 실제 데이터를 읽고 학습한 모델을 사용자에게 돌려주는 것은 다른 문제다. 후자는 데이터의 소유권, 실행 환경, 평가 조건, 비용, 실패한 작업의 복구까지 책임져야 한다. expharness는 자연어를 이 과정의 입력으로 사용하지만, 자연어 답변 자체를 실행 성공의 증거로 사용하지 않는다.

설계의 핵심은 판단하는 모델과 결과를 확인하는 시스템을 분리하는 것이다. 연결된 LLM은 문제를 해석하고 다음 시도와 코드를 제안한다. 시스템은 그 요청이 허용된 데이터·작업·예산에 속하는지 검사하고, 격리 실행에서 나온 증거로 결과를 기록한다. 공급자를 바꾸더라도 작업 원장과 평가 조건이 함께 바뀌어서는 안 된다.

이 글은 2026년 9월 21일 소스 dc7f0db를 기준으로 설명한다. 현재 중심 경로는 표 데이터 분류·회귀다. 모든 이미지·시계열 과제를 지원하거나 모든 실패에서 더 좋은 전략을 찾는 완성형 자율 연구 시스템이라고 주장하지 않는다.

1. 한 문장이 실행 가능한 작업이 되는 과정

웹의 대화창은 작업을 만드는 입구다. 목표만 먼저 받는 setup 프로젝트와, 데이터를 함께 받는 경로를 지원한다. 목표·데이터·제약을 받은 뒤 사용자 요구와 에이전트의 기술 계획을 구분해 저장한다. 예를 들어 “다음 달 이탈 고객을 알고 싶다”는 사용자 요구이고, 어떤 알고리즘과 전처리를 사용할지는 에이전트가 제안할 기술 선택이다. 둘을 섞으면 모델이 임의로 정한 선택이 사용자의 요구처럼 굳어진다.

미니대회도 별도의 축소된 챗봇이 아니다. 참가 API가 등록 과제의 목표·특징·금지 열·평가 조건을 registered_task_requirements에 기록하고 검증된 연습 데이터를 연결한 뒤, 동일한 /project/build 대화 화면으로 보낸다. 참가자가 첫 문장을 직접 쓰지 않아도 등록 조건이 남는다. 연습 데이터 공개 허용은 데이터 지문과 과제 범위에 묶이고, 참가자가 서버 파일 경로나 공개 허용 정보를 지정하지는 못한다.

여기서 막히는 조건도 명시적이다. 같은 참가 키로 생성한 작업에 다른 데이터나 다른 규칙을 덮어쓰지 않는다. 이미 해석한 작업에 새 과제 조건을 소급 삽입하지도 않는다. 재시도는 같은 작업을 찾는 것이지, 성공할 때까지 새 작업을 만드는 동작이 아니다.

2. LLM과 XGENy CLI의 역할은 다르다

LLM은 판단 엔진이고 XGENy는 그 판단을 실행·기록하는 경계다. 플랫폼의 xgeny_agent.py는 실행 파일과 호환성, 모델 endpoint, 요청 형식, 상태 디렉터리와 작업 공간을 확인한 뒤 CLI 요청을 구성한다. 공개 대화도 별도의 직접 모델 HTTP 경로로 우회하지 않는다. 공급자 설정은 교체할 수 있지만, 플랫폼이 기대하는 출력 계약과 실행 증거는 유지한다.

LLM의 문장을 곧바로 명령으로 실행하지 않는다. 구조화된 응답을 파싱하고 허용된 선택과 필드인지 검사한다. 코드 생성, 검토, 도구 사용은 각 경로의 계약과 자원 한도 아래에서 처리한다. 따라서 XGENy에 기능이 존재한다는 사실과 해당 기능이 이 제품의 특정 작업에서 허용됐다는 사실은 별개다.

이 경계는 사용량에도 중요하다. 상위 판단 요청 한 번이 실제 추론 한 번이라는 보장은 없다. CLI의 계획·완료 확인 때문에 내부 호출이 여러 번 발생할 수 있다. 재접속이나 화면 조회로 새 판단을 만들지 않고, 원래 요청과 실행 기록을 대조해야 중복 호출과 비용을 구분할 수 있다. 현재 native 경로의 공개 답변은 검증 후 전달하며, 제공되지 않는 토큰 스트림을 가짜 타이핑으로 표현하지 않는다.

3. 전처리는 학습 전에 따로 끝나는 화면이 아니다

전처리의 결과는 학습과 추론에 계속 영향을 준다. 학습할 때 범주를 숫자로 바꿨다면 새 입력에서도 같은 변환을 적용해야 한다. 전체 데이터에서 결측값 대체 기준이나 스케일을 먼저 구한 뒤 검증 데이터를 나누면, 검증 데이터의 정보가 학습으로 새어 들어갈 수 있다. 따라서 원본 보존, 학습 구간 안에서의 fit, 변환과 모델의 연결이 핵심이다.

이 시스템의 데이터 도구는 “라이브러리가 설치돼 있으니 무엇이든 실행”하는 구조가 아니다. 요청 계약, 입력 지문, 허용된 데이터 범위, 실행 한도, 반환 요약 검사가 있다. epoch_data_tools.py의 보호된 검사 경로는 봉인된 학습 입력만 준비하고, 검사 영수증과 요약을 확인한다. 이 도구를 사용했다는 이유로 최종 평가 데이터 접근이나 임의 학습 실행 권한까지 생기지는 않는다.

LLM에 전달하는 맥락과 실행 컨테이너가 읽는 데이터도 구분한다. 모델 판단에는 구조화된 요약과 허용된 근거를 전달한다. 실제 변환·학습 코드는 승인된 입력으로 실행한다. 전처리 방식이나 ML 알고리즘을 플랫폼 개발자가 대회 사례에 맞춰 숨겨 넣는 대신, 에이전트가 제안하고 시스템이 검증할 수 있는 형태로 남긴다.

4. 코드는 어디에서 실행되는가

생성된 ML 코드는 웹 서버 프로세스에서 직접 실행하지 않는다. 작업과 실행 단계에 연결된 명세로 격리 실행기에 전달한다. 명세에는 실행 대상, 입력·출력, 런타임과 자원 제한이 들어간다. CPU·메모리·프로세스 수·실행 시간·네트워크와 파일 접근 범위를 통제하는 이유는 속도뿐 아니라 다른 사용자의 작업과 서버를 보호하기 위해서다.

실행 성공 여부는 “코드를 작성했다”는 답변으로 판단하지 않는다. 완료 영수증과 출력 산출물을 확인하고, 지문이 해당 입력·실행 명세와 맞는지 검증한다. 파일이 존재하더라도 다른 실행이 남긴 파일이거나 중간 결과라면 성공 증거가 될 수 없다. 모델 미리보기 역시 요청한 모델·입력·요청 ID와 반환된 예측이 일치하는지 확인한다.

컨테이너는 호스트 커널을 공유한다. 임의의 적대적 코드를 완벽하게 막는 가상머신과 동일하다고 설명하지 않는다. 지원되는 런타임·도구·입력 범위가 제한되어 있고, 준비되지 않은 실행 경로는 준비되지 않았다고 표시한다.

5. 기준 모델, 새 후보, 최종 평가를 섞지 않는 이유

자동 루프의 목표는 실행 횟수를 늘리는 것이 아니다. EpochResearchLoop는 개발 평가의 피드백을 저장하고, 연결된 모델이 다음 실험을 제안하도록 한다. 시스템은 검증된 결과로 현재 최선의 후보를 보존하고, 선택이 끝난 산출물을 최종 평가로 연결한다. 특정 데이터에 맞춘 ML 레시피를 루프 코드 안에 넣지 않는다.

개발 평가와 최종 평가는 용도가 다르다. 개발 평가는 실험 선택에 쓰인다. 최종 평가를 매번 열어 보고 그 결과에 맞춰 전략을 수정하면 최종 평가도 사실상 튜닝 데이터가 된다. 어떤 점수인지, 어떤 데이터 버전·평가 단위에서 나온 점수인지 함께 저장해야 비교가 성립한다. 독립 평가가 존재한다는 사실만으로 실제 서비스의 분포 변화까지 해결되는 것도 아니다.

실험 실패와 전략 실패도 구분한다. 라이브러리 오류는 코드 수정의 대상이고, 실행은 성공했지만 개선이 없으면 근거를 다시 검토해야 한다. 현재 시스템에는 제한된 비교·보존·전략 재검토 경로가 있지만, 어떤 실패에서도 좋은 전략으로 자동 탈출한다는 성능 보장은 없다. 기준 모델 보존은 안전장치이지 성능 개선의 증거가 아니다.

6. 채점이 끝났는데 서버가 멈추면

미니대회의 채점 규칙은 고정된 데이터·분할·지표·특징·모델 식별에 묶인다. 제출은 SQLite 원장에 기록되며, 워커가 작업을 점유한 뒤 평가한다. 참가자가 올린 숫자를 점수로 믿는 방식이 아니다. 결과가 불확실하면 임의의 0점을 넣지 않는다.

완료 직후 점수 저장 전에 중단될 수도 있다. 이 경우 무조건 재실행하면 비용을 이중 사용하거나 실행 결과를 바꿀 수 있다. 복구 경로는 원래 제출, 실행 권한 식별자, 모델·입력 지문, 비용 예약과 모든 배치의 완료 영수증을 다시 확인하고 점수 저장만 복구한다. 영수증이 없거나 변조됐으면 성공으로 바꾸지 않는다. 실행과 복구는 같은 작업별 잠금을 사용하고, 자동 확인 횟수는 SQLite에 저장해 프로세스 재시작으로 초기화되지 않게 한다.

실측에서는 비공개 검증 원장으로 실제 격리 평가 10회를 수행한 뒤 저장 직전 중단을 주입했다. 새 워커가 고정 평가 9,039개 단위의 결과를 복원했고, 복구를 위한 추가 평가 실행은 0회였다. 이는 저장 장애 복구의 증거다. 모든 모델이 채점에 성공한다거나, Google 로그인과 공개 점수 제출까지 검증했다는 뜻은 아니다.

7. 메모리는 대화를 길게 붙이는 기능이 아니다

XGENy의 run-local SQLite와 플랫폼의 프로젝트·데이터 명세·모델 메타데이터·이벤트가 원본 기록이다. project_memory.py는 프로젝트 내부의 ML 경험을 재구성 가능한 형태로 투영한다. memory_events.py는 실행 사이의 사실을 정규화한다. 요약이나 색인이 원본 증거보다 더 강한 권위를 갖지 않도록 나눈 것이다.

기록해야 할 것은 성공한 모델 이름만이 아니다. 어떤 목표와 제약에서 어떤 입력·변환·코드·런타임을 사용했는지, 무엇이 실패했고 비용과 평가 결과는 어땠는지가 있어야 반복 실패를 피할 수 있다. 점수가 좋아도 평가 조건이 다르면 그대로 순위를 매길 수 없다. 동일한 이름의 열이 있어도 의미가 다르면 과거 변환을 그대로 이식하면 안 된다.

과제 간 경험 검색과 자동 이식은 이 기록 위의 다음 단계다. 현재 기록·정규화 기반과, 새 과제에 가장 적합한 경험을 안정적으로 찾아 성능을 개선하는 완성된 기능을 구분한다. “100번 걸린 작업을 다음에는 두 번 만에 해결한다”는 것은 측정해야 할 목표이지 구현됐다고 내세울 수 있는 수치가 아니다. 경험 재사용은 LLM 가중치의 온라인 학습과도 다르다.

8. 웹 조사와 공개 화면의 신뢰 경계

공개 자료 조사는 호스트가 연결한 검색·fetch 계층이다. 명시된 검색어로 얻은 문서를 비신뢰 근거로 다루며, 검색 결과의 짧은 문구를 원문을 읽은 증거로 사용하지 않는다. 사용자 데이터 행이나 자격증명을 검색어에 실어 보내지 않는다. 웹페이지에서 발견한 명령이 실행 권한이나 사용자의 목표를 바꾸어서도 안 된다. 이 기능은 XGENy 공식 브라우저 capability와 동일하지 않다.

웹 화면은 이 과정의 투영이다. 대화, 실제 작업 이벤트, 점수, 산출물과 실패 안내를 보여주되 페이지 조회나 SSE 재연결이 새 학습을 시작하지 않는다. 공개 이력의 읽기 권한과 작업을 변경하는 소유자 권한도 별개다. 보관 모델을 다운로드하거나 미리보기할 수 있다는 것과 운영 모델로 승격됐다는 것도 구분해야 한다.

구현 근거와 남은 과제

아래 링크는 설명 기준 커밋으로 고정했다. 저장소 접근 권한이 필요한 경우 GitHub 로그인이 필요할 수 있다. 본문은 링크를 열지 않아도 읽을 수 있다.

남은 일은 인증을 포함한 공개 제출 완주, 모델 사용 가능 상태의 일관된 표시, 실제 실패 후 전략 전환의 품질 측정, 과제 간 경험 재사용의 효과 검증이다. 더 많은 도구 이름을 나열하는 것보다, 같은 사용자 작업에서 계획·실행·비교·수정·산출물이 끊기지 않는지 확인하는 것을 우선한다.