Recent Posts
Recent Comments
반응형
«   2026/10   »
일 월 화 수 목 금 토
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

오늘도 공부

AI 코딩 에이전트는 어떻게 ‘끝날 때까지’ 일할까(/goal) 본문

AI/추천 오픈소스

AI 코딩 에이전트는 어떻게 ‘끝날 때까지’ 일할까(/goal)

행복한 수지아빠 2026. 9. 28. 12:37
반응형

Codex와 DeepSeek Harness의 /goal 이해하기

AI에게 개발을 맡길 때 자주 생기는 문제가 하나 있다.

예를 들어 이렇게 부탁했다고 해보자.

로그인 버그를 찾아서 수정하고,
관련 테스트가 전부 통과하는 것까지 확인해줘.

AI는 코드를 살펴보고, 파일을 수정하고, 테스트를 한 번 돌린다.

그리고 이렇게 답할 수 있다.

로그인 로직을 수정했습니다.
다음으로 테스트를 확인해보면 좋겠습니다.

사람 입장에서는 답답하다.

“그걸 내가 다시 시켜야 하나?”

그래서 다시 말한다.

계속해.

테스트가 실패한다.

AI가 원인을 설명한다.

다시 사람이 말한다.

고쳐.

다시 테스트한다.

또 문제가 발견된다.

계속해.

이 과정을 반복하다 보면 한 가지 의문이 생긴다.

처음부터 ‘완료될 때까지 알아서 계속하라’고 할 수는 없을까?

이 문제를 해결하기 위해 등장한 개념 중 하나가 바로 Goal이다.

Codex에서는 /goal이라는 형태로 사용할 수 있고, DeepSeek Harness 역시 거의 같은 개념의 Goal 시스템을 구현하고 있다.


1. 먼저 ‘프롬프트’와 ‘Goal’의 차이부터

보통 우리가 AI에게 입력하는 것은 프롬프트다.

이 버그를 수정해줘.

프롬프트를 아주 단순하게 표현하면 다음 구조다.

사용자 요청
   ↓
AI 작업
   ↓
결과
   ↓
대기

한 번의 요청에 대한 작업이다.

반면 Goal은 조금 다르다.

/goal 로그인 오류를 수정하고 모든 테스트를 통과시켜라

이 경우 중요한 것은 현재 무엇을 할 것인가가 아니라

어떤 상태가 되면 일이 끝난 것으로 볼 것인가

이다.

OpenAI는 Codex Goal을 여러 턴에 걸쳐 유지되는 persistent objective, 즉 지속되는 목표라고 설명한다. Goal은 결과가 무엇이어야 하는지뿐 아니라 성공을 어떻게 확인할 것인지와 어떤 제약을 지켜야 하는지를 함께 담을 수 있다. OpenAI Developers

그래서 구조도 달라진다.

Prompt

요청
 ↓
작업
 ↓
결과
 ↓
종료

Goal은 다음과 가깝다.

Goal
 ↓
작업
 ↓
검증
 ↓
완료했는가?
 ├─ 아니오 → 다음 작업
 │           ↓
 │          검증
 │           ↓
 │          다시 판단
 │
 └─ 예 → 완료

이 차이가 생각보다 크다.


2. /goal을 이해하려면 Harness부터 알아야 한다

여기서 Harness라는 단어가 등장한다.

AI 코딩 도구에서 Harness는 모델 그 자체가 아니다.

쉽게 비유하면,

LLM = 두뇌

Harness = 두뇌가 실제 일을 하도록
          기억하고, 도구를 주고,
          실행을 반복하고,
          상태를 관리하는 시스템

이라고 볼 수 있다.

예를 들어 Codex 같은 코딩 에이전트가 단순히 LLM API 하나만 호출한다고 생각하기 쉽지만 실제로는 주변에 많은 시스템이 필요하다.

             ┌──────────────┐
             │     LLM      │
             └──────┬───────┘
                    │
      ┌─────────────┼─────────────┐
      │             │             │
    Files          Shell        Tools
      │             │             │
      └─────────────┼─────────────┘
                    │
                 Harness
                    │
        ┌───────────┼───────────┐
        │           │           │
      State       Session     Context
        │
      Goal

Harness가 있어야 AI가

코드를 읽고,

터미널 명령을 실행하고,

테스트 결과를 확인하고,

작업 상태를 기억하고,

다음 행동을 결정할 수 있다.

Goal도 모델 자체의 기능이라기보다 Harness가 제공하는 실행 관리 기능에 가깝다.


3. 그래서 /goal은 단순한 ‘긴 프롬프트’가 아니다

예를 들어 이렇게 입력한다고 생각해보자.

/goal 회원가입 기능의 오류를 모두 수정하고
npm test가 통과하도록 만들어라

단순 구현이라면 이것을 매번 모델의 시스템 프롬프트에 넣어줄 수도 있다.

하지만 Goal의 핵심은 그것보다 더 깊다.

Goal을 별도의 상태로 만든다.

개념적으로는 이런 데이터다.

{
  "objective": "회원가입 오류를 수정하고 테스트를 통과시킨다",
  "status": "active",
  "progress": "...",
  "budget": "...",
  "rounds": 3
}

즉 대화 내용과 별개로

“이 세션은 현재 무엇을 끝내려고 하고 있는가?”

라는 상태가 존재하는 것이다.

Codex도 Goal을 전역 메모리나 프로젝트 전체 설정이 아니라 현재 thread에 귀속되는 지속 상태로 설계한다. 목표, lifecycle, budget, 진행 상황 등을 thread가 관리한다. OpenAI Developers


4. Codex에서는 실제로 /goal을 사용할 수 있다

현재 Codex 관련 공식 문서에서는 /goal을 지속적인 목표를 설정하는 명령으로 설명하고 있다.

예를 들어 이런 식이다.

/goal Reduce p95 latency below 120 ms without regressing correctness tests

한국어로 바꾸면 대략 이런 형태다.

/goal API 응답시간 p95를 120ms 이하로 낮추고
기존 정확성 테스트는 모두 통과하도록 만들어라.

Codex 문서에서 제시하는 기본적인 Goal 제어는 다음과 같다.

/goal

현재 Goal 확인


/goal pause

Goal 일시정지


/goal resume

Goal 다시 진행


/goal clear

현재 Goal 제거

Codex의 공식 Goal 가이드에 따르면 Goal은 Codex 0.128.0부터 지원되며, 활성 상태에서는 코드 확인 → 실행 → 수정 → 테스트 → 검증을 진행하다가 성공, 일시정지, 사용자 개입 필요, 인터럽트, 예산 제한 등의 조건을 만나면 멈추는 구조다. OpenAI Developers

현재 ChatGPT/Codex의 slash command 문서에도 /goal이 persistent goal을 설정하는 명령으로 올라와 있다. Goal이 실행되는 동안 화면에서 진행 상태를 확인하고 pause, resume, edit, clear 등의 제어도 할 수 있다. OpenAI Developers


5. 그런데 Goal이 있다고 해서 자동으로 계속 일하는 것은 아니다

여기서 중요한 개념이 하나 더 있다.

Goal State와 Continuation은 서로 다른 문제다.

예를 들어 시스템에 다음 데이터가 저장돼 있다고 하자.

Goal:

쇼핑몰 결제 버그를 수정한다.

이것만으로 AI가 계속 움직이는 것은 아니다.

누군가 AI에게 다시 실행 신호를 줘야 한다.

그래서 Goal 시스템에는 보통 Continuation Driver 같은 것이 붙는다.

Goal
 │
 ▼
Agent 실행
 │
 ▼
작업
 │
 ▼
Agent가 Idle 상태가 됨
 │
 ▼
Goal 확인
 │
 ├─ 완료 → 종료
 │
 └─ 미완료
      │
      ▼
 다음 Agent 실행

바로 이 부분 때문에 Goal이 단순 TODO와 달라진다.


6. DeepSeek Harness를 보면 이 구조가 훨씬 명확하다

DeepSeek가 공개한 Harness에는 Goal 기능이 꽤 명확하게 분리되어 있다.

구조를 단순화하면 다음과 같다.

Goal Service

      +

Goal Tools

      +

/goal Command

      +

Goal Round Driver

각자 하는 역할이 다르다.

DeepSeek Harness 공식 저장소에서도 Goal 기능을 네 부분으로 나눈다. goal은 상태와 lifecycle을, tool-goal은 모델이 사용하는 get_goal, create_goal, update_goal을, command-goal은 사람이 사용하는 /goal을, goal-round-driver는 자동으로 다음 Round를 실행하는 역할을 맡는다. GitHub

이걸 그림으로 보면 훨씬 이해하기 쉽다.

사용자

/goal "결제 오류를 수정하고 테스트 통과"

          │
          ▼

┌──────────────────┐
│   Goal Command   │
└────────┬─────────┘
         │
         ▼

┌──────────────────┐
│   Goal Service   │
│                  │
│ objective        │
│ status           │
│ round            │
│ revision         │
│ blocker          │
└────────┬─────────┘
         │
         ▼

┌──────────────────┐
│ Goal Round Driver│
└────────┬─────────┘
         │
         ▼

┌──────────────────┐
│      Agent       │
│                  │
│ LLM + Tools      │
└────────┬─────────┘
         │
         ▼

     결과 검증

         │

     미완료?

    YES     NO
     │       │
     ▼       ▼
Next Round Complete

이것이 /goal의 본질에 상당히 가깝다.


7. 여기서 ‘Round’라는 개념이 중요하다

일반 대화에서는 Turn이라는 표현을 많이 사용한다.

사용자 질문
   ↓
AI 응답

이것을 하나의 Turn이라고 볼 수 있다.

Goal에서는 그 바깥에 Round라는 개념을 둘 수 있다.

예를 들어 목표가 다음과 같다고 하자.

/goal 프로젝트의 TypeScript 오류를 전부 제거한다.

첫 번째 Round.

tsc 실행

→ 오류 37개 발견

두 번째 Round.

타입 정의 수정

→ 오류 12개

세 번째 Round.

API 타입 수정

→ 오류 3개

네 번째 Round.

나머지 타입 수정

→ 오류 0개

다섯 번째 Round.

npm test

→ PASS

그리고 Goal을 완료한다.

즉 사용자가 중간마다

계속해.

라고 말하지 않아도 된다.

DeepSeek Harness의 goal-round-driver는 Goal이 활성 상태이고, 자동 continuation이 허용되어 있고, Agent가 idle 상태이며, 남은 Round가 있을 때 다음 Goal Round를 만들어 실행한다. GitHub


8. 이것이 긴 작업에서 특히 중요한 이유가 있다

AI 코딩 작업이 길어지면 Context Window 문제가 생긴다.

처음에는 이런 요청을 줬다고 해보자.

이 프로젝트를 Next.js 16으로 마이그레이션하고
모든 테스트를 통과시키고
기존 API 호환성을 유지해줘.

작업이 길어지면서 수많은 정보가 쌓인다.

사용자 요청

파일 읽기

코드 분석

터미널 출력

에러 로그

수정

테스트

재수정

테스트

...

결국 Context가 커진다.

그러면 시스템은 과거 내용을 압축하거나 일부 세부 정보를 줄일 수 있다.

100K Context

     ↓

Compaction

     ↓

20K Summary

여기서 중요한 초기 요구사항이 약해질 수 있다.

하지만 Goal을 별도의 persistent state로 관리하면 상황이 달라진다.

Conversation Context
       │
       ├─ 압축 가능
       ├─ 오래된 로그 제거 가능
       └─ 요약 가능


Goal State

"Next.js 16으로 마이그레이션하고
 테스트 통과,
 API 호환성 유지"

       │
       └─ 계속 유지

그래서 장시간 Agent를 운영할수록 Goal 같은 구조의 가치가 커진다.


9. DeepSeek Harness는 Goal 변경 자체도 기록한다

DeepSeek Harness에서는 Goal이 단순 메모리 변수 하나가 아니다.

Goal 변경 사항을 session log에 기록한다.

예를 들어 개념적으로 이런 식이다.

goal/change

user/message

assistant/message

tool/result

goal/change

user/message

tool/result

goal/change

Goal을 수정하거나 pause하거나 complete하면 새로운 상태가 기록된다.

공식 문서에 따르면 모든 Goal mutation은 goal/change 이벤트로 session log에 남고, 이 session log가 Goal 상태에 대한 durable authority가 된다. GitHub

그래서 프로그램이 다시 시작되거나 세션이 복원되어도

objective
phase
revision
round count

같은 정보를 복구할 수 있다. GitHub

이걸 개발 용어로 표현하면 Event Sourcing에 가까운 방식이다.


10. 그런데 왜 revision까지 필요할까?

여기서 조금 더 재미있는 설계가 나온다.

Goal에 revision이 존재한다.

예를 들어 현재 Goal이

revision = 7

이라고 하자.

Agent가 이 상태를 읽었다.

그런데 그 사이 사용자가 Goal을 수정했다.

revision = 8

예전 Agent가 뒤늦게 이렇게 요청한다.

revision 7의 Goal을 완료 처리

그대로 받아버리면 문제가 생긴다.

사용자가 방금 수정한 최신 Goal을 옛날 Agent가 완료해 버릴 수 있기 때문이다.

그래서 DeepSeek Harness에서는 Goal을 변경할 때 정확한

goal id
+
revision

을 요구한다.

옛 revision을 가지고 수정하려 하면 거절한다. GitHub

데이터베이스에서 흔히 사용하는 Compare-And-Set과 비슷한 아이디어다.


11. AI도 Goal을 읽고 수정할 수 있다

DeepSeek Harness에는 모델이 사용할 수 있는 Goal Tool도 있다.

대표적으로 다음 세 가지다.

get_goal()

create_goal()

update_goal()

예를 들어 Agent가 현재 상태를 알고 싶다면

get_goal()

을 실행한다.

결과는 개념적으로 이런 형태다.

{
  "objective": "모든 테스트 오류를 수정한다",
  "phase": "active",
  "roundsStarted": 12,
  "maxGoalRounds": 256
}

그리고 작업이 끝났다고 판단하면

update_goal(... complete ...)

같은 동작을 할 수 있다.

DeepSeek Harness의 모델용 Goal Tool 역시 get_goal, create_goal, update_goal 세 개로 구성되며 업데이트 전에 현재 Goal의 id와 revision을 읽도록 설계되어 있다. GitHub

즉 인간과 AI가 같은 Goal을 바라본다.

             Goal State
             /        \
            /          \
        사용자          Agent
        /goal          get_goal
                       update_goal

12. /goal 자체는 LLM을 거치지 않을 수도 있다

이 부분도 흥미롭다.

DeepSeek Harness의 /goal pause 같은 명령은 굳이 LLM에게

사용자가 Goal을 중지하고 싶어 합니다.
어떻게 할까요?

라고 물어보지 않는다.

Harness가 직접 처리한다.

사용자

/goal pause

   ↓

Command Parser

   ↓

Goal Service

   ↓

paused

따라서 불필요한 모델 호출이 필요하지 않는다.

DeepSeek의 command-goal 문서는 /goal 명령의 상태 조회와 수정 결과가 UI command plane에서 직접 처리되고 모델 요청에 포함되지 않는다고 명시하고 있다. GitHub

이것은 Agent Harness를 설계할 때 꽤 중요한 원칙이다.

모든 것을 LLM에게 묻지 않는다.

확실하게 프로그램으로 처리할 수 있는 것은 프로그램이 처리한다.


13. 그렇다면 Goal은 언제 완료됐다고 판단할까?

여기서 Goal 시스템의 가장 어려운 문제가 나온다.

예를 들어 목표가

/goal 로그인 문제를 완전히 해결해라

라고 하자.

AI가 코드 몇 줄을 수정한 후

문제가 해결되었습니다.

라고 말하면 정말 끝난 것일까?

아니다.

Goal 시스템에서는 완료를 증명할 수 있어야 한다.

Codex의 공식 가이드에서도 Goal completion은 단순히 모델이 “아마 끝났다”고 생각해서 처리하는 것이 아니라, 파일·테스트·로그·benchmark·artifact 등 실제 evidence와 비교해야 한다고 강조한다. OpenAI Developers

예를 들면 다음처럼 된다.

Goal

회원가입 오류 수정

      ↓

코드 수정

      ↓

npm test

      ↓

PASS

      ↓

Playwright E2E

      ↓

PASS

      ↓

TypeScript check

      ↓

PASS

      ↓

Complete

이것이 Goal을 제대로 작성할 때

"무엇을 해줘"

보다

"어떤 상태가 되면 완료인지"

가 더 중요한 이유다.


14. 좋은 Goal과 나쁜 Goal

예를 들어 다음 Goal은 좋지 않다.

/goal 프로젝트를 좋게 만들어줘.

완료 여부를 판단하기 어렵다.

이것도 애매하다.

/goal 성능을 개선해줘.

얼마나 개선하면 되는지 알 수 없다.

반면 이렇게 작성하면 훨씬 좋다.

/goal checkout API의 p95 latency를
120ms 이하로 낮춘다.

기존 correctness test는 모두 통과해야 한다.

좋은 Goal에는 자연스럽게 다음 개념이 들어간다.

목표

+

성공 조건

+

검증 방법

+

지켜야 할 제약

OpenAI 역시 좋은 Goal에는 outcome, verification surface, constraints, boundaries, iteration policy 등 명확한 완료 계약이 들어가야 한다고 설명한다. OpenAI Developers


15. 무한 루프가 되지는 않을까?

당연히 이 문제가 생긴다.

Goal이

성능을 최대한 개선해라.

같은 식이면 AI가 계속 시도할 수 있다.

수정
↓
테스트
↓
조금 개선
↓
수정
↓
테스트
↓
조금 개선
...

그래서 Goal에는 Budget이라는 개념이 중요하다.

예를 들어

최대 Round

최대 Token

최대 시간

최대 비용

최대 Tool 호출

등을 제한할 수 있다.

Codex도 Goal 상태에 budget과 progress accounting을 포함시키며, 예산에 도달하면 완료로 간주하는 것이 아니라 작업을 중단하고 현재 진행 상황과 blocker, 다음에 할 일을 정리하도록 설계되어 있다. OpenAI Developers

DeepSeek Harness에서는 현재 기본 Goal Round 제한이

256

이다. Goal을 생성할 때 별도 값을 지정하지 않으면 defaultMaxGoalRounds: 256이 사용된다. GitHub

즉 Goal의 의미는

무한정 일해라

가 아니라

정해진 목표를 향해
허용된 범위 안에서
계속 진행해라

에 가깝다.


16. /plan과 /goal은 무엇이 다를까?

이 둘도 헷갈리기 쉽다.

Plan은

어떻게 할 것인가

를 정한다.

Goal은

어디까지 가면 끝인가

를 정한다.

예를 들어

/plan

으로 이런 계획을 만들 수 있다.

1. 로그인 코드 분석
2. 오류 재현
3. 인증 로직 수정
4. Unit Test
5. E2E Test

하지만 실제 작업 과정에서 2번을 수행하다 전혀 예상하지 못한 문제가 나타날 수 있다.

Plan을 그대로 따라가는 것이 오히려 틀릴 수도 있다.

Goal은 달라진다.

로그인 오류가 재현되지 않고
모든 인증 테스트가 통과한다.

라는 목적지는 유지하되,

거기에 도달하는 경로는 Agent가 바꿀 수 있다.

현재 Codex slash command 문서에서도 Goal을 설정하기 전에 /plan으로 목표를 먼저 다듬는 방식을 안내한다. OpenAI Developers

즉 둘은 경쟁 관계가 아니라 함께 사용할 수 있다.

Plan

어떻게 갈까?


Goal

어디까지 가야 끝일까?

17. TODO와 Goal도 다르다

TODO는 보통 작업 목록이다.

[ ] API 수정
[ ] 테스트 추가
[ ] README 수정

하지만 세 항목을 모두 체크했다고 해서 실제 문제가 해결됐다는 보장은 없다.

Goal은 결과 중심이다.

회원가입 E2E Test가 통과한다.

즉

TODO = 해야 할 행동

Goal = 만들어야 할 상태

라고 이해하면 쉽다.


18. Memory와 Goal도 다르다

Memory는

이 프로젝트는 React를 사용한다.

사용자는 TypeScript를 선호한다.

API 규칙은 이것이다.

같은 정보를 기억하는 데 가깝다.

Goal은

현재 이번 작업에서
무엇을 끝내야 하는가

를 관리한다.

따라서 Agent Harness에서는 각각의 역할이 다르다.

Memory
 └─ 알아야 할 것

Context
 └─ 지금 참고하고 있는 것

Plan
 └─ 앞으로 할 것

TODO
 └─ 수행할 작업

Goal
 └─ 완료되어야 할 상태

이렇게 구분해 두면 Agent 시스템 설계가 훨씬 명확해진다.


19. 결국 /goal의 핵심은 이것이다

처음 보면 /goal은 그냥 새로운 Slash Command 하나처럼 보인다.

하지만 안쪽 구조를 살펴보면 생각보다 중요한 변화다.

기존 AI 사용 방식은 대부분 이랬다.

사람
 ↓
AI
 ↓
사람
 ↓
AI
 ↓
사람
 ↓
AI

사람이 계속 Agent를 밀어줘야 했다.

계속해.

다음으로 넘어가.

테스트해.

실패했으니 다시 해.

Goal 기반 Agent는 이 구조를 바꾸려 한다.

사람

"완료 조건은 이것이다."

        ↓

Agent

작업
 ↓
검증
 ↓
판단
 ↓
다음 행동
 ↓
작업
 ↓
검증
 ↓
...

        ↓

완료 또는 Blocked

        ↓

사람

사람이 모든 다음 행동을 지시하는 대신,

사람은 목적과 경계를 정의한다.

그리고 Harness가 실행을 관리한다.


20. 그래서 /goal은 AI 에이전트 시대에 꽤 중요한 기능이다

LLM의 성능만 좋아진다고 Agent가 자동으로 일을 잘 끝내는 것은 아니다.

장시간 작업을 맡기려면 최소한 다음 구조가 필요하다.

              Goal
                │
                ▼
          Persistent State
                │
                ▼
          Agent Execution
                │
                ▼
        Tool / Code / Shell
                │
                ▼
           Verification
                │
                ▼
         Completion Check
             /      \
            /        \
      Continue      Complete
          │
          ▼
       Budget

모델은 그중 일부일 뿐이다.

Goal을 기억하고,

언제 다시 실행할지 결정하고,

완료됐는지 검증하고,

무한 실행을 막고,

필요하면 사람에게 다시 넘기는 역할은

Harness가 담당한다.

그래서 앞으로 좋은 AI Agent를 만드는 경쟁은 단순히

“어떤 LLM이 더 똑똑한가?”

만으로 결정되지 않을 가능성이 높다.

오히려 중요한 질문은 이것일 수 있다.

이 시스템은 Agent에게 목표를 어떻게 주고, 그 목표를 얼마나 오래 유지하며, 언제 일을 끝냈다고 판단하는가?

Codex의 /goal과 DeepSeek Harness의 Goal 구조가 흥미로운 이유도 바로 여기에 있다.

AI가 단순히 질문에 답하는 도구에서

목표를 가지고 일을 끝내는 시스템으로 이동하고 있기 때문이다.


참고 자료

OpenAI의 공식 Using Goals in Codex 문서는 Goal을 persistent objective, evidence-based completion, budget-controlled continuation이라는 관점에서 설명한다. Using Goals in Codex Codex의 현재 Slash Commands 문서에서도 /goal을 persistent goal을 설정하는 명령으로 확인할 수 있다. Codex Slash Commands DeepSeek Harness의 실제 구현은 goal, tool-goal, command-goal, goal-round-driver 패키지로 나뉘어 있어 Goal 기반 Harness 구조를 공부하기 좋은 사례다. DeepSeek Harness Goal

반응형