Table of contents
Open Table of contents
들어가며
Jev라고 하는 독특한 AI가 나왔다고 하여, wait list 등록을 요청하고 사용 권한을 받아 Jev를 사용해 보고 간단한 테스트를 해 본 경험을 공유합니다.
1. Jev는 무엇인가
공식 문서는 Jev를 소프트웨어가 바로 사용할 수 있는 구조화된 판단을 반환하는 System One 모델로 소개합니다. 자연어를 이해하지만, 설명문이나 코드를 생성하는 대신 정의된 답의 범위에서 판단을 반환합니다. 공식 개념 설명
그래서 일반적인 LLM에 비해 입출력에 소모되는 토큰 비용도 저렴하고(출력은 거의 없다고 보면 될 것 같습니다.) 문자열 토큰을 생성하지 않고 확률을 판단하기 때문에 속도도 정말 빨랐습니다.
Jev는 자연어 입력을 지원하지만, 질문 종류와 가능한 답의 범위를 지정해 요청합니다. Jev가 반환할 수 있는 질문의 종류는 크게 세 가지입니다.
| 질문 종류 | 역할 |
|---|---|
Choice | 주어진 선택지 중 하나를 선택 |
Score | 정의한 평가 단계에 따른 점수를 반환 |
Noul | 예/아니오 질문에 대한 확률을 반환 |
사용하는 쪽에서는 state에 판단 자료를 넣고, questions에 질문과 평가 기준을 전달합니다. 판단 이후의 실행은 애플리케이션 코드가 담당합니다. 공식 API 문서
어떻게 보면 일반 LLM에 출력 형식을 제한해둔 것처럼 보일 수도 있는데, 제가 관심을 둔 부분은 결정이 필요한 순간에 Jev가 LLM을 사용하는 것에 비해 얼마나 유용한지 확인해 보는 것이었습니다.
2. 코드 탐색 최적화
저는 첫 실험으로 LLM 에이전트에게 커다란 코드 베이스에서 자연어로 특정 기능이 어디에서 구현되는지 확인하려고 하는 요청을 전달했을 때, 수많은 파일 중에서 필요한 파일을 추려내는 결정을 하기 위해 Jev를 사용할 수 있게 구성을 해 보았습니다.
- 바닐라 에이전트는 요청을 받으면
rg를 이용해 관련된 파일과 코드를 검색해 1차로 추려내고 - 추려낸 목록을 다시 확인해서 다시 최종으로 확인하면 좋을 목록을 답변합니다.
탐색 대상은 Godot 엔진의 자체 C++ 코드 3,722개 파일이며, 전체 라인은 약 162만 줄 정도 됩니다. Godot 엔진에서 사용하는 외부 라이브러리 코드는 제외했습니다.
tree-sitter 인덱싱 + BM25 검색 + Jev 판단
실험 환경은 다음과 같이 구성했습니다.
tree-sitter를 사용해 소스 코드에서 검색할 항목을 추출(인덱스로 사용)BM25키워드 일치도 기반으로 인덱스에서 후보 추출Jev사용(optional)
그래서 전반적인 실험의 실행 흐름은 다음과 같습니다.
[전처리]
Godot 소스 코드 준비
-> tree-sitter로 선언, 정의 추출
-> 검색용 레코드 목록 저장
[요청 처리]
사용자가 LLM 에이전트에게 질문 전달
-> 에이전트는 BM25로 레코드 점수 계산
-> 상위 50개 심볼 후보 선정
-> (Jev 사용 시) Jev가 상위 50개 항목을 평가
-> 에이전트가 확인할 파일 목록 최종 선정
gpt-6-astra / low를 메인 에이전트로 사용했고, 질문 8개를 조건별로 3회씩 실행해 총 72회를 측정했습니다. 각 실행의 결과로 반환하는 파일 목록이 요구하는 파일 목록과 일치하는지에 따라 평가를 했습니다.
Recall@5는 반환 목록의 상위 5개 안에 정답 파일이 얼마나 포함됐는지를 나타내는 지표입니다.
| 조건 | 평균 시간 | 평균 추정 비용 | 필수 파일 Recall@5 |
|---|---|---|---|
| Astra 단독 | 18.92초 | $0.16581 | 100% |
| Astra + BM25 | 12.25초 | $0.18761 | 100% |
| Astra + BM25 + Jev | 15.93초 | $0.21426 | 100% |
테스트 결과 모든 조건에서 필수 파일을 상위 5개 목록 안에 반환한 것을 확인할 수 있었습니다.
BM25를 이용해 레코드 목록에서 후보를 찾으면 평균 탐색 시간이 줄었지만 Jev를 추가한 방식에서는 에이전트 단독보다는 빨랐지만, 비용은 가장 높았고, BM25에 비해 느리기까지 했습니다.
이 결과를 보고 생각을 다시 해 봤습니다.
- 이미 코드 베이스에 대한 인덱스가 존재하고, 그 인덱스에서 탐색을 하는
BM25가 있다면Jev에 추가 판단을 요청하는 것 자체가 오버헤드가 될 수 있음 Jev판단의 유용성을 검증하려면 검색을 위한 도구들이 없는 환경에서 테스트 해 보는 게 좋아 보임
그래서 인덱스를 제외하고 rg 결과를 Jev가 추린 뒤 에이전트가 최종 파일을 선정하는 방식으로 비교를 진행해 봤습니다. 다음은 앞서 실험한 것과 같은 질문 8개를 각 조건별로 1회씩 실행한 결과입니다.
| 조건 | 평균 시간 | 평균 추정 비용 / 런 | 필수 파일 Recall@10 |
|---|---|---|---|
| Astra 단독 | 21.91초 | $0.25082 | 100% |
| Jev 래퍼 1회 + Astra | 27.91초 | $0.27101 | 100% |
| Jev 재호출 허용 + Astra | 24.92초 | 미확정 — 확인된 비용 기준 $0.24922 | 100% |
인덱스가 빠진 만큼 전체적인 시간은 늘어났고, 이에 따라 비용도 상승했습니다. Jev를 사용한 경우도 에이전트를 단독으로 사용한 경우에 비해 특별한 이점을 찾을 수 없었습니다.
탐색 테스트에서는 Jev가 기존 에이전트의 작업을 충분히 대체하지 못했다고 볼 수 있겠습니다.
- 에이전트 단독으로 필수 파일을 모두 찾았고, 검색 후보를 추리고
Jev를 호출하고 확인하는 과정에도 에이전트가 모두 개입 Jev의 빠른 판단이 전체 작업 시간 단축 및 파일 탐색 시간 최적화로 이어지지 않음- 따라서 이번 테스트에서는
Jev가 에이전트 작업에 오버헤드가 된 것 같습니다.
3. 게임 상태에 따른 행동 선택
게임은 인공지능이 처한 상황을 게임 내부에서 관리할 수 있고, 게임 내부에서 수행할 수 있는 행동에도 비교적 명확한 제약이 있습니다.
그래서 게임은 Jev의 판단 자체를 다른 에이전트의 해석 없이 행동으로 이어가고, 상태를 게임에서 관리할 수 있기 때문에 적합한 환경으로 판단했습니다. (공식 소개 페이지에서도 둠을 플레이하는 예제를 보여주었습니다.)
제가 설정한 게임은 사냥으로 골드를 모으고, 강화하거나 아이템을 구매하는 단순한 선택지를 가진 게임입니다.
Jev에게 요청을 전달할 때는 Choice 방식으로 현재 처한 상황과 다음에 어떤 행동을 할지 물어보고, Jev가 선택한 행동을 게임에서 플레이할 수 있게 만들었습니다. Jev는 단순하게 게임이 보내준 상태 정보를 기반으로 목표인 20강 장비를 만들기 위한 ‘선택’만 합니다.
게임 상태와 행동별 효과 → Jev의 선택 → 게임 실행 → 갱신된 상태
3.1 결과와 입출력
어떤 정보를 전달했는가
다음은 입력 구조를 줄여 재구성한 예시입니다. 게임이 계산한 사냥 보상과 소요 시간을 선택지에 넣고, Jev가 다음 행동 하나를 고르게 합니다.
{
"model": "jev-1.13.0",
"state": {
"objective": "장비 20강 달성",
"location": "outskirts",
"gold": 0,
"equipped_level": 0
},
"questions": {
"action": {
"type": "choice",
"instructions": "제공된 행동 효과를 비교해 목표를 위한 다음 행동을 선택하라.",
"criteria": {
"farm": {
"description": "적 한 마리를 처치한다.",
"gold_gain": 6,
"game_seconds_added": 0.6
},
"return": {
"description": "마을로 돌아간다. 골드를 얻지는 않는다.",
"gold_gain": 0,
"game_seconds_added": 0
}
}
}
}
}
아래는 응답 중 answers 부분입니다.
{
"answers": {
"action": {
"type": "choice",
"choice": "farm",
"confidence": 0.94,
"probabilities": {
"farm": 0.97,
"return": 0.03
}
}
}
}
게임은 choice가 현재 허용된 행동인지 검증한 뒤 실행합니다. probabilities는 행동 선택의 분포이고, confidence는 그 분포를 요약한 값입니다. 사냥 성공률이나 판단의 정답률은 아닙니다.
계산은 코드에서, 선택은 Jev에서
처음 Jev에 요청을 보낼 때에는 현재 가지고 있는 아이템 강화 상태, 골드, 강화 비용 등과 같은 상태를 Jev에게 전달하고, 그 값을 기반으로 적절한 선택지를 제공하게 요청을 보냈습니다.
이 경우 마을 <-> 사냥터 사이를 계속 반복해 움직이기만 하는 루프에 빠졌는데, 공식 가이드를 확인해 요청 형식을 다음과 같이 변경했습니다.
- 결정적인 규칙과 제어 흐름은 코드에 둔다.
Jev는 범위가 좁은 판단을 한다.
그래서 아이템 강화 비용이나 확률, 사냥 시 얻게 되는 보상과 남은 아이템 구매 비용 등 게임 내부에서 계산을 통해 간단하게 구할 수 있는 요소들은 게임에서 계산을 하고, 그 결과와 함께 선택지를 만들어 Jev에게 전달하는 방식으로 요청을 했습니다.

테스트 결과는 나름 인상적이었습니다. 우선 어떤 행동을 해야 하는지 규칙을 지정하지 않아도, 입력으로 제공한 상태를 바탕으로 최종 목표인 20강 완주에 필요한 선택을 했다는 점입니다.
- 다른 LLM의 판단 없이 순수
Jev의 선택 기반으로 게임을 진행했고, - 사냥 행동의 99%가 현재 레벨에서 최대 골드 효율을 가진 사냥터에서 진행됐고,
- 확률 강화권, 구매 조건, 강화 수치 등의 정보가 변화함에 따라 유연한 선택을 했습니다.
안전형 규칙 봇은 Jev보다 평균 게임 시간이 짧았습니다. Jev를 이용한 실험에서는 상태와 행동을 제공하는 방식으로 완주에 필요한 선택을 비교적 저렴한 비용으로 테스트했습니다.
더 복잡한 게임 규칙을 가진다면, 규칙 봇보다 Jev 기반 게임 테스팅이 좀 더 유연할 수 있겠다는 생각도 해 보았습니다.
- 5회 기준
Jev총 비용은 0.63달러, 1회 평균은 0.127달러였습니다. - 기준은 입력 0.042달러/백만 토큰, 출력 무료
정리하며
- 코드 탐색에서는 기존 에이전트의 성능이 높았고, 판단을 분리하는 추가 비용이 발생했습니다.
- 게임에서는 상태와 행동의 효과를 코드가 제공하자, 상세한 행동 정책 없이도
Jev가 효율적인 플레이를 수행했습니다.
두 실험에서 얻은 가설은 다음 판단에 필요한 맥락을 현재 상태로 얼마나 충분히 표현할 수 있는가가 중요하다 는 것입니다. 게임은 상태를 계속 보존하지만, Jev 호출에는 필요한 스냅샷을 매번 제공했습니다. 탐색에서는 무엇을 확인하고 배제했는지까지 별도로 구성해야 했습니다.
참고 자료
- TypeSafe — System One — 모델의 역할과 LLM과의 차이
- TypeSafe — API reference — 상태, 질문, 응답 형식
- TypeSafe — How to build — 코드와 판단 모델의 역할 분리
- Godot Engine — 코드 탐색 실험 대상
이 게시물은 직접 수행한 실험 기록을 바탕으로 LLM의 도움을 받아 작성한 초안입니다.