SYDESYDE
SYDESYDE
  • 피드
  • 쇼케이스
  • 블로그
  • 모임
SYDESYDE© 2026 SYDE. All rights reserved.
SYDE 소개문의하기
Kakao
SYDE 오픈채팅
Instagram
Instagram
Threads
Threads
커뮤니티 가이드라인협업문의이용약관개인정보처리방침
커뮤니티 가이드라인협업문의이용약관개인정보처리방침

© 2026 SYDE. All rights reserved.

Local LLM을 게임에 실제로 넣어봤더니 — UNSPECIFIED #4

mmustardoo· 15시간 전· 기술
목차
  • 먼저, 정말 게임 안에서 Local LLM을 돌렸다
  • 첫 번째 시도 — 이미 완성된 스킬 중에서 골라보게 했다
  • 두 번째 시도 — 그럼 스킬 자체를 조합하게 해보자
  • 실패한 이유가 정말 ‘스킬을 못 만들어서’였을까?
  • 세 번째 시도 — 내부 배선은 코드가 하고, 모델은 ‘의미’만 고르게 했다
  • 그래도 결과는 크게 달라지지 않았다
  • 문제는 JSON이 아니었다
  • 그래서 권한을 어디까지 줘야 할지가 문제가 됐다
  • 그렇다고 여기서 “LLM은 안 된다”는 결론은 아니다
  • 그래도 더 해볼 방법은 많았다

목차

  • 먼저, 정말 게임 안에서 Local LLM을 돌렸다
  • 첫 번째 시도 — 이미 완성된 스킬 중에서 골라보게 했다
  • 두 번째 시도 — 그럼 스킬 자체를 조합하게 해보자
  • 실패한 이유가 정말 ‘스킬을 못 만들어서’였을까?
  • 세 번째 시도 — 내부 배선은 코드가 하고, 모델은 ‘의미’만 고르게 했다
  • 그래도 결과는 크게 달라지지 않았다
  • 문제는 JSON이 아니었다
  • 그래서 권한을 어디까지 줘야 할지가 문제가 됐다
  • 그렇다고 여기서 “LLM은 안 된다”는 결론은 아니다
  • 그래도 더 해볼 방법은 많았다

지난 글에서는 AI에게 스킬을 만들게 하려다가, 오히려 먼저 게임이 스킬을 표현할 수 있는 언어부터 만들게 된 이야기를 했다.

플레이어가 어떤 행동을 반복하는지는 게임이 계산한다.

그 행동을 실제 능력으로 표현할 수 있는 문법도 만들었다.

잘못된 조합이 들어오면 걸러낼 Compiler도 만들었다.

그리고 실제 효과와 플레이어가 읽는 설명 역시 같은 검증 결과에서 나오도록 했다.

여기까지 만들고 나니 드디어 처음부터 해보고 싶었던 질문을 시험할 수 있게 됐다.

이 조합 문제를 Local LLM이 규칙 기반 방식보다 실제로 더 잘 풀 수 있을까?

이번에는 아이디어 수준에서 끝내고 싶지 않았다.

그래서 실제 Local Model을 게임에 연결하고, 같은 플레이 데이터를 규칙 기반 시스템과 모델에게 넣어 직접 비교하기 시작했다.

결과는 처음 예상했던 것과 꽤 달랐다.


먼저, 정말 게임 안에서 Local LLM을 돌렸다

비교에는 세 종류의 quantized Local Model을 사용했다.

구분

모델

작은 모델

Qwen3 1.7B

2B급 모델

Qwen3.5 2B

3B급 모델

Granite 4.2 3B

비교 기준

Deterministic 규칙 기반 시스템

최종 비교에서는 같은 CPU 환경과 같은 입력 조건을 사용했고, 결과가 흔들리지 않도록 temperature를 0으로 두고 fixed seed를 사용했다.

모델이 실패했을 때 게임 자체가 멈추는 구조도 아니었다.

Local worker가 정상적으로 준비됐는지 확인하고, 요청이 늦거나 잘못된 결과가 오면 폐기하고, 사용할 수 없는 결과라면 규칙 기반 결과로 돌아가도록 했다.

즉 이번 실험은 프롬프트 창에 플레이 로그를 넣어보고 답변을 읽는 식이 아니었다.

실제로 게임에서 사용할 수 있는 파이프라인 안에 Local LLM을 넣은 상태에서 비교했다.

그리고 가장 먼저 모델에게 준 일은 생각보다 단순했다.


첫 번째 시도 — 이미 완성된 스킬 중에서 골라보게 했다

처음부터 모델에게 스킬 전체를 만들게 하지는 않았다.

그건 너무 많은 변수를 한꺼번에 시험하는 것 같았다.

그래서 먼저 실제 게임에서 이미 검증된 몇 개의 Adaptive Skill을 준비했다.

각 스킬은 이미 Compiler를 통과했고, 실제 전투에서 실행할 수 있고, UI에도 정상적으로 설명할 수 있는 상태였다.

모델에게는 플레이어의 Motif를 보여주고 이렇게 묻는 셈이었다.

“현재 플레이어에게 가장 잘 맞는 능력은 무엇인가?”

규칙 기반 시스템에도 똑같은 정보를 줬다.

규칙 기반 쪽은 어떤 Motif가 얼마나 반복됐는지, 최근 같은 스킬이 계속 선택되지는 않았는지 등을 보고 순위를 정한다.

Local LLM은 같은 후보들을 보고 의미적으로 가장 잘 맞는 순서를 고른다.

기술적으로는 꽤 잘 작동했다.

모델 호출도 됐고, 구조화된 결과도 정상적으로 돌아왔고, 실제 게임에 적용할 수 있었다.

그런데 정작 비교해보니 다른 문제가 보였다.

규칙 기반 시스템과 모델이 같은 선택을 하는 경우가 많았다.

물론 다른 선택이 나온 경우도 있었다.

하지만 당시 사람 비교는 작은 개발자 파일럿이었고, 일부는 시스템이 제대로 작동하는지 확인하기 위한 guided sanity test에 가까웠다.

그래서 이 결과를 가지고

“규칙 기반과 LLM이 동급이라는 것이 증명됐다.”

라고 말할 수는 없다.

다만 한 가지 신호는 꽤 분명했다.

추가 Local Model 비용을 정당화할 정도로 뚜렷한 차이는 보이지 않았다.

생각해보면 이상한 결과도 아니었다.

어떤 능력이 사용 가능한지는 이미 코드가 정하고 있었다.

Motif의 강도도 코드가 계산했다.

후보 스킬은 전부 실행 가능한 상태였다.

최근 어떤 스킬을 사용했는지도 코드가 알고 있었다.

이 상태에서 모델에게 남은 일은 결국

“이미 정리된 후보 중 어떤 게 조금 더 어울려 보이는가?”

에 가까웠다.

그러다 보니 이런 의문이 생겼다.

혹시 내가 LLM에게 너무 쉬운 일만 시키고 있는 건 아닐까?

그래서 모델에게 더 많은 권한을 주기로 했다.


두 번째 시도 — 그럼 스킬 자체를 조합하게 해보자

이번에는 완성된 능력 중 하나를 고르는 게 아니라,

스킬 구조 자체를 모델이 만들도록 했다.

앞 글에서 만든 Skill Grammar를 실제로 사용했다.

어떤 행동에서 시작하는지.

무엇을 기억하는지.

어떤 대상과 연결하는지.

어떤 효과로 끝나는지.

모델이 이런 구조를 직접 조립하도록 한 것이다.

여기까지가 애초에 Local LLM을 사용하고 싶었던 이유와 훨씬 가까웠다.

사람이 완성된 스킬을 전부 만들어놓고 고르게 하는 게 아니라,

사람이 만든 게임 언어 안에서 모델이 새로운 조합을 만드는 것.

그런데 결과는 좋지 않았다.

각 시스템에 여러 상황을 넣고, 상황마다 세 개의 스킬 후보를 만들게 했다.

규칙 기반 시스템은 60개의 후보를 전부 실제 게임에서 사용할 수 있는 구조로 만들었다.

Local Model 세 종류는 모두 60개 중 0개였다.

방식

실제 파이프라인을 통과한 후보

규칙 기반

60 / 60

Local 1.7B

0 / 60

Local 2B

0 / 60

Local 3B

0 / 60

처음 보면 꽤 강한 결과처럼 보인다.

그런데 나는 여기서 실험을 끝내지 않았다.

왜냐하면 모델에게 시킨 일을 다시 보니 조금 불공정하다고 느꼈기 때문이다.


실패한 이유가 정말 ‘스킬을 못 만들어서’였을까?

당시 모델은 의미 있는 스킬을 생각하는 것뿐 아니라,

게임 내부에서 사용하는 꽤 낮은 수준의 연결 구조까지 직접 작성해야 했다.

어떤 node를 만들지.

어떤 기능의 어떤 입력 형식을 사용할지.

앞 node의 어떤 출력을 다음 node에 연결할지.

이런 내부 배선까지 모델이 직접 맞춰야 했다.

실제로 실패 결과를 보면 존재하지 않는 연결 방식을 사용하거나, 필요한 입력을 빼먹거나, 잘못된 node를 참조하는 문제가 많이 나왔다.

일부 출력은 길어지면서 잘리기도 했다.

그러니까 이 결과만 가지고

“작은 Local LLM은 게임 스킬을 설계하지 못한다.”

라고 결론 내리기는 어려웠다.

스킬의 의미를 설계하는 능력과,

Compiler 내부의 배선을 정확하게 작성하는 능력을 동시에 시험하고 있었기 때문이다.

그래서 한 번 더 구조를 바꿨다.

이번에는 모델에게 내부 구현을 최대한 숨겼다.


세 번째 시도 — 내부 배선은 코드가 하고, 모델은 ‘의미’만 고르게 했다

마지막 실험에서는 모델이 더 이상 node나 내부 연결을 작성하지 않았다.

대신 이런 것만 결정하게 했다.

어떤 행동들이 어떤 순서로 이어지는지.

같은 물체인지, 다른 물체인지.

같은 대상인지, 다른 대상인지.

어느 시점의 위치를 사용할지.

한 지점에서 효과를 만들지, 두 위치의 중간을 사용할지.

어떤 종류의 효과로 끝낼지.

그리고 어떤 Motif를 이 스킬의 근거로 삼았는지.

예를 들어 모델 입장에서는 이런 수준의 의미만 결정하면 된다.

대시를 한다
→ 이후 근접 공격을 성공시킨다
→ 대시 시작 위치와 적중 위치를 연결한다
→ 두 위치 사이에 효과를 만든다

게임 내부에서 이걸 어떤 Skill Block으로 연결하고, 어떤 입력과 출력을 사용해야 하는지는 전부 코드가 대신 처리한다.

모델이 정한 의미 구조를 게임이 실제 Skill Graph로 변환한 뒤,

이전과 똑같은 Compiler, Runtime, Presentation을 통과시켰다.

중요한 건 여기서 게임 규칙을 느슨하게 만든 게 아니라는 점이다.

모델이 작성해야 하는 표현만 단순하게 만들었다.

기존 방식과 의미가 달라지지 않았는지도 전체 조합 공간을 대상으로 따로 확인했다.

이제 적어도

“내부 배선이 너무 복잡해서 모델이 실패했다.”

라는 이유는 상당 부분 걷어낸 셈이었다.


그래도 결과는 크게 달라지지 않았다

마지막 비교에서는 실제 스킬 생성이 가능한 20개의 상황을 준비했다.

각 시스템은 한 상황마다 서로 다른 세 개의 후보를 만들도록 했다.

즉 시스템 하나당 총 60개의 후보를 생성한다.

결과는 다음과 같았다.

방식

파이프라인 통과

중복 제거 후 후보

하나라도 성공한 상황

규칙 기반

60 / 60

60

20 / 20

Local 1.7B

0 / 60

0

0 / 20

Local 2B

6 / 60

4

4 / 20

Local 3B

0 / 60

0

0 / 20

여기서 ‘통과했다’는 것은 재미있는 스킬이라는 뜻이 아니다.

게임의 규칙과 제약을 만족해서 실제로 컴파일하고 실행할 수 있는 구조였다는 뜻이다.

2B 모델만 일부 결과를 통과시켰다.

하지만 6개의 통과 결과 중 중복을 제거하면 4개가 남았고,

그 4개도 구조적으로 보면 사실상 같은 형태 하나였다.

세 모델 중 어느 것도 한 상황에서 요구했던

실행 가능하면서 서로 구조적으로 다른 세 가지 후보

를 만들어내지는 못했다.

여기서부터는 단순히 출력 형식 문제가 아니었다.


문제는 JSON이 아니었다

마지막 실험에서는 모델이 JSON을 못 만들어서 실패한 경우가 핵심이 아니었다.

겉으로 보면 출력은 멀쩡했다.

필요한 필드도 있고,

허용된 값도 사용했고,

정해둔 구조도 대체로 맞췄다.

그런데 각각의 선택을 서로 연결해서 보면 모순이 생겼다.

예를 들어 이런 식이다.

물체 정보가 존재하지 않는 행동을 선택해놓고
“첫 번째 행동과 같은 물체여야 한다”는 조건을 붙인다.

또는,

대상이 없는 행동을 골라놓고
“이전에 공격한 대상과 같은 대상”을 참조한다.

한 단계씩 따로 보면 각각은 그럴듯하다.

하지만 스킬 전체를 보면 동시에 성립할 수 없다.

최종 생성된 180개의 Local Model 후보 중 150개가 이런 종류의 의미 관계 모순에서 막혔다.

즉 작은 모델들이 가장 어려워한 건

올바른 JSON을 만드는 것

보다는,

스킬 전체에 걸쳐 여러 조건을 동시에 일관되게 유지하는 것

에 가까웠다.

이 차이가 생각보다 컸다.

문법에 맞는 구조를 만드는 능력과, 실행 가능한 게임 규칙을 만드는 능력은 같은 것이 아니었다.


그래서 권한을 어디까지 줘야 할지가 문제가 됐다

여기까지 실험하고 나니 한 가지 패턴이 보였다.

처음처럼 모델의 역할을 아주 좁게 만들면 안정적이다.

이미 실행 가능한 스킬을 준비해놓고 그중 하나만 고르게 하면 Local LLM도 충분히 할 수 있다.

그런데 그 정도로 제한하면 규칙 기반 시스템과 비교했을 때 모델이 추가로 해주는 일이 별로 없다.

반대로 모델이 진짜 새로운 조합을 만들 수 있도록 자유도를 넓혀주면,

이번에는 실제 게임에서 사용할 수 없는 결과가 급격히 많아졌다.

결국 내가 마주친 건 이런 상황이었다.

모델의 권한을 좁히면 굳이 LLM이 필요하지 않았고,
권한을 넓히면 실행 가능한 결과를 안정적으로 만들지 못했다.

이게 이번 실험에서 가장 크게 남은 결과였다.


그렇다고 여기서 “LLM은 안 된다”는 결론은 아니다

이 결과를 너무 넓게 해석하고 싶지는 않다.

이번에 시험한 건 작은 Local Model이, 한 번의 추론으로, 실제 게임에서 실행 가능한 스킬 관계를 만들어내는 조건이었다.

1.7B부터 3B 정도의 모델을 시험했다.

그보다 훨씬 큰 모델은 시험하지 않았다.

Cloud Model도 시험하지 않았다.

Fine-tuning이나 LoRA도 하지 않았다.

여러 번 생성한 뒤 스스로 수정하게 하는 구조도 시험하지 않았다.

따라서

“LLM으로 게임 메커닉을 만드는 건 불가능하다.”

는 결론은 아니다.

정확하게 말하면,

내가 이 프로젝트에서 사용하려고 했던 크기와 실행 조건의 Local LLM은, 규칙 기반 방식보다 충분히 나은 결과를 안정적으로 보여주지 못했다.

정도다.

3B 모델로 조금 키워본다고 문제가 자동으로 해결되는 신호도 이번에는 보이지 않았다.

오히려 마지막 실험에서는 3B 모델도 통과한 결과가 없었다.


그래도 더 해볼 방법은 많았다

여기서 끝까지 밀어붙이는 방법은 분명히 있었다.

가능한 선택지를 코드가 더 좁혀줄 수도 있다.

현재 상태에서 합법적인 조건만 모델에게 보여줄 수도 있다.

잘못된 결과를 코드가 자동으로 고친 뒤 다시 Compiler에 넣을 수도 있다.

모델에게 한 번에 완성된 답을 요구하지 않고 여러 단계에 걸쳐 수정하게 할 수도 있다.

더 큰 모델을 사용할 수도 있다.

더 많은 플레이 데이터를 모델에게 줄 수도 있다.

문제는 하나씩 추가할 때마다 새로운 질문이 생긴다는 점이었다.

그렇게 해서 성공한 시스템은, 내가 처음 만들고 싶었던 시스템과 여전히 같은가?

AI를 안전하게 만들기 위해 가능한 선택지를 게임 코드가 거의 전부 계산해놓고,

잘못된 선택은 코드가 고치고,

모델에게 마지막 선택만 맡긴다면,

과연 그 스킬을 만든 주체는 누구라고 해야 할까?

그리고 그런 구조라면 Local LLM을 게임 안에 넣으면서 발생하는 비용을 감수할 이유가 있을까?

여기까지 오고 나니 다음 질문은 더 이상 기술적인 문제가 아니었다.

이 실험을 계속할 이유가 있는가?

다음 글에서는 더 큰 모델이나 더 복잡한 시스템으로 계속 밀어붙이는 대신, UNSPECIFIED의 개발을 여기서 멈추기로 결정한 이유를 정리해보려고 한다.

  • #게임개발
  • #ai
  • #llm
5
m
mustardoo

mustardoo님의 다른 글

  • AI 게임을 만들겠다고 시작했는데, 여기서 멈추기로 했다 — UNSPECIFIED #완15시간 전
  • AI에게 스킬을 만들게 하려다 게임의 언어부터 만들었다 — UNSPECIFIED #31일 전
  • Dash를 30번 했다고 ‘Dash형 플레이어’일까? — UNSPECIFIED #21일 전

댓글 0

My avatar