바둑을 배우는 순서대로 AI도 배우게 한다

  • AI
  • 바둑
  • Skills

이전 글에서는 이런 질문에서 시작했다.

LLM은 바둑을 둘 수 있을까?

처음에는 단순히 바둑판의 형세를 파악할 수 있는지를 생각했다.

LLM이 직접 바둑의 모든 수를 계산할 수 없다면 바둑 엔진을 도구로 사용하면 될 것 같았다. 엔진이 판을 계산하고, LLM은 그 결과를 해석한다.

그다음에는 형세를 알 수 있다면 다음 수 역시 생각할 수 있지 않을까 하는 질문으로 넘어갔다.

다만 다음 수를 단순히 361개의 좌표 가운데 하나를 고르는 문제로 생각하는 대신, 바둑에서 사용하는 행동의 개념을 먼저 생각하게 하면 어떨까 싶었다.

붙인다.

막는다.

잇는다.

끊는다.

공격한다.

살린다.

이런 개념을 LLM이 사용할 수 있는 Skill로 만들어주고, 현재 판의 상황을 보고 어떤 행동이 필요한지를 먼저 생각하게 하는 것이다.

그러면 구조는 단순한

판면 → 착수

가 아니라,

판면 → 형세 판단 → 목적 설정 → Skill 선택 → 후보수 생성 → 엔진 검증 → 착수

가 된다.

그리고 그 판단 과정 자체를 기록해두면 AI는 자신이 왜 그곳에 돌을 놓았는지 사용자에게 설명할 수도 있다.

그렇게 생각을 따라가다 보니 내가 만들고 싶은 것은 점차 단순한 바둑 AI와는 다른 모습이 되었다.

대화형 바둑 상대이면서 동시에 사고 과정을 함께 따라가는 교습기.

바둑에서 말하는 ‘수담’, 손으로 나누는 대화에 조금 더 가까운 상대를 만들어보고 싶어졌다.

그런데 목표를 정하고 나니 오히려 그다음 문제가 생겼다.

그런데 무엇부터 만들어야 하지?#

나는 바둑을 제대로 둘 줄 모른다.

바둑이라는 행위가 무엇인지는 알고 있지만, 실제로 판을 앞에 두고 한 판을 끝까지 진행할 수 있는 정도의 규칙과 지식을 가지고 있지는 않다.

단수가 무엇인지 어렴풋이 알고, 패라는 말도 들어봤고, 집이 많으면 이긴다는 것 정도를 알고 있다.

하지만 그것들을 어떤 순서로 배워야 하는지는 모른다.

그러다 보니 프로그램을 만드는 순서 역시 애매해졌다.

처음에는 비교적 단순하게 생각했다.

먼저 바둑의 규칙을 구현한다.

그다음 돌 사이의 관계를 파악한다.

그리고 잇기, 끊기, 막기 같은 Skill을 추가한다.

조금 더 발전하면 공격과 수비 같은 전략을 생각하게 하고, 마지막에는 바둑 엔진을 붙여 실제 수읽기를 검증한다.

대략 이런 순서였다.

규칙 → 돌의 관계 → Skill → 전략 → 엔진 → 수담

프로그램을 만드는 관점에서 보면 그럴듯했다.

그런데 한 가지 의문이 들었다.

이 순서는 사람이 바둑을 배우는 순서와도 같을까?

나는 바둑을 이제 배우려고 하는 사람이다.

그런 내가 머릿속으로 만든 순서보다, 이미 오랫동안 사람에게 바둑을 가르쳐온 교육 방식에는 나름의 이유가 있을 것이다.

그렇다면 굳이 학습 순서까지 내가 처음부터 새롭게 만들 필요가 있을까?

바둑을 잘 두는 사람들은 어떤 순서로 가르칠까#

여기에서 이창호와 이세돌의 입문서를 살펴보기로 했다.

책의 모든 내용을 공부하려는 것은 아니었다.

내가 궁금했던 것은 목차였다.

어떤 개념을 먼저 설명하고, 그 개념 다음에는 무엇을 배우게 하는지.

즉 바둑 교육에서 이미 만들어져 있는 개념의 선후 관계를 보고 싶었다.

범위도 너무 넓게 잡지 않기로 했다.

프로기사들의 책을 모두 조사하기 시작하면 이번 프로젝트의 목적보다 바둑 교육 서적 조사가 더 커질 수 있다.

그래서 처음 떠올렸던 이창호와 이세돌, 두 사람을 중심으로 살펴봤다.

그리고 목차를 비교하면서 생각보다 흥미로운 차이를 발견했다.

이창호의 책에서는 돌 하나에서 판 전체로 올라간다#

이창호의 바둑 입문서를 따라가 보면 처음부터 포석이나 전략을 이야기하지 않는다.

먼저 돌이 어떻게 살아 있는지를 배운다.

활로를 알고,

단수를 알고,

돌을 잡고 살리는 방법을 배운다.

그다음 연결과 끊기로 넘어간다.

이후 축, 장문, 양단수, 환격, 촉촉수 같은 구체적인 전술이 등장한다.

그 다음에야 사활과 수상전으로 올라가고, 좋은 모양과 나쁜 모양을 배우고, 더 뒤에서 행마와 맥점, 포석과 정석 같은 전체 판의 개념으로 범위가 커진다.

이 순서를 보고 가장 먼저 든 생각은 이것이었다.

바둑에서는 전체 판을 이해하기 전에 돌 하나와 돌의 관계부터 이해해야 하는구나.

나는 프로그램을 생각하면서 비교적 빨리 ‘공격한다’, ‘세력을 만든다’, ‘큰 곳을 차지한다’ 같은 개념으로 올라가려고 했다.

하지만 그것보다 먼저 알아야 할 것이 있었다.

이 돌은 살아 있는가?

자유도는 몇 개인가?

지금 단수인가?

두 돌은 연결되어 있는가?

상대가 이곳을 끊으면 무슨 일이 일어나는가?

이런 질문들이다.

사람이 이런 것을 모르면서 ‘상대를 공격한다’는 말을 제대로 이해하기 어렵다면, 프로그램 역시 다르지 않을 것이다.

이세돌의 책에서는 한 판의 흐름과 판단으로 이어진다#

이세돌의 입문서를 보면서는 조금 다른 흐름이 보였다.

기본적인 규칙과 집, 활로, 단수, 연결과 끊기, 기본적인 돌 잡기, 사활과 수상전을 배우면서 한 판이 어떻게 진행되는지를 비교적 빠르게 경험하게 한다.

그리고 입문 단계를 벗어나면 점점 질문의 성격이 바뀐다.

어떻게 돌을 잡는가에서,

지금 어떤 행동을 하는 것이 좋은가

로 올라간다.

큰 자리보다 급한 자리를 먼저 본다.

상대의 두터운 곳에 가까이 가지 않는다.

내가 먼저 산 다음 상대를 공격한다.

상대의 급소가 내 급소가 되기도 한다.

손 따라 두지 않는다.

이런 원칙들은 특정 좌표를 알려주는 기술과는 조금 다르다.

현재 상황을 보고 무엇을 우선해야 하는지를 결정하는 판단 기준에 가깝다.

이 부분을 보면서 처음 생각했던 Skill의 의미도 다시 생각하게 됐다.

나는 처음에 Skill을 붙인다, 막는다, 끊는다 같은 수법의 메뉴얼 정도로 생각했다.

그런데 Skill은 그보다 훨씬 넓을 수 있었다.

“큰 곳보다 급한 곳을 먼저 보라.”

이것도 Skill이 될 수 있다.

“공격하기 전에 내 돌의 안전을 확인하라.”

이것도 Skill이 될 수 있다.

즉 바둑의 Skill에는 돌을 어떻게 움직이는지를 알려주는 것뿐 아니라, 무엇을 먼저 생각해야 하는지를 알려주는 것도 있을 수 있다.

그리고 더 흥미로웠던 것은 그다음이었다.

기풍을 생각하고,

자신의 대국을 복기하고,

어떤 장면에서 어떤 판단을 했는지 다시 살펴본다.

이것은 내가 만들려고 했던 ‘사고 과정 교습기’와 거의 그대로 연결됐다.

Skill도 한 층으로 되어 있지 않았다#

책의 학습 순서를 보고 나니 Skill을 한 종류로만 보는 것이 오히려 부자연스럽게 느껴졌다.

적어도 세 층 정도로 나눌 수 있을 것 같았다.

첫 번째는 아주 구체적인 기초 전술 Skill이다.

단수를 찾는다.

잡을 수 있는 돌을 찾는다.

위험한 돌을 살린다.

연결한다.

끊는다.

축이 성립하는지 확인한다.

이 단계에서는 프로그램도 비교적 명확한 상태와 규칙을 다룬다.

두 번째는 전략과 판단의 Skill이다.

약한 돌을 공격한다.

큰 곳과 급한 곳을 구분한다.

상대가 강한 곳에서는 싸우지 않는다.

공격하기 전에 자신의 약한 돌을 먼저 살핀다.

지금 반드시 응수해야 하는지, 손을 빼도 되는지를 판단한다.

여기서부터는 단순한 패턴 인식보다 여러 상태를 비교하는 의사결정이 필요하다.

그리고 세 번째는 자신의 판단을 다시 살펴보는 Skill이다.

왜 이 수를 생각했는가?

다른 후보는 무엇이었는가?

어느 수에서 판단이 잘못되었는가?

비슷한 실수를 반복하고 있지는 않은가?

이 단계에 도달하면 AI는 단순히 바둑을 두는 상대가 아니라 사용자의 사고를 함께 복기하는 상대가 된다.

처음에 생각했던 붙이기, 막기, 잇기에서 시작했던 Skill이라는 개념이 이제는 전술 → 판단 → 복기라는 세 단계로 확장된 셈이다.

내가 배우는 순서대로 프로그램도 배우게 한다#

여기까지 보고 나서 프로젝트의 개발 원칙을 조금 더 명확하게 정할 수 있었다.

내가 바둑을 배우는 순서와 프로그램이 바둑을 배우는 순서를 최대한 맞춘다.

내가 활로를 배운다면 프로그램에도 돌의 자유도를 계산하는 기능을 넣는다.

내가 단수를 배운다면 프로그램에는 단수를 감지하는 기능을 넣는다.

내가 돌을 잡고 살리는 방법을 배우면 capture, escape 같은 Skill을 만든다.

연결과 끊기를 배우면 프로그램도 개별 돌이 아니라 돌의 그룹을 보기 시작한다.

축을 배우면 축이라는 전술을 어떻게 계산해야 하는지 생각한다.

사활을 배우면 지금 상태만 보는 것이 아니라 몇 수 이후의 결과까지 탐색해야 한다는 문제를 만나게 된다.

그리고 언젠가 내가 ‘큰 곳’과 ‘급한 곳’의 차이를 이해하면 프로그램에도 새로운 판단 구조가 생긴다.

예전에는 단순히 가치가 큰 곳을 찾았다면 이제는 그 전에 이런 질문을 해야 한다.

지금 당장 대응하지 않으면 안 되는 곳이 있는가?

있다면 그곳을 먼저 본다.

없다면 큰 곳을 찾는다.

바둑 개념 하나를 새롭게 이해할 때마다 프로그램의 그래프에 판단 하나가 추가된다.

그래서 이 프로젝트에서는 바둑 공부와 개발 공부가 따로 진행되지 않을 것 같다.

내가 바둑 개념 하나를 배우는 것이 프로그램에는 알고리즘이나 Skill 하나를 추가하는 일이 된다.

로드맵도 다시 만들었다#

처음에는 규칙 → Skill → 전략 → 엔진 정도로 생각했던 로드맵을 다시 나누었다.

첫 번째 세대의 목표는 바둑판이다.

9×9 바둑판에서 흑과 백이 번갈아 돌을 놓을 수 있고, 활로와 단수, 포획, 착수금지, 연결과 끊기를 프로그램이 이해한다.

아직 AI가 잘 둘 필요는 없다.

우선 바둑이라는 세계가 어떤 규칙으로 움직이는지를 코드로 표현하는 단계다.

두 번째 세대에서는 바둑을 아는 프로그램으로 발전한다.

축과 장문 같은 기본 전술을 알고, 사활과 수상전을 이해하고, 좋은 모양과 나쁜 모양, 행마와 맥점 같은 개념을 조금씩 다룬다.

세 번째 세대에서야 생각하는 상대가 된다.

전체 판의 형세를 보고, 약한 돌과 강한 돌을 찾고, 큰 곳과 급한 곳을 구분하고, 무엇을 할 것인지 목적을 세운다.

그리고 그 목적에 맞는 Skill을 선택해 후보수를 만든다.

구체적인 수읽기는 바둑 엔진으로 검증한다.

여기에서 내가 처음 생각했던 구조가 완성된다.

판면 → 상황 이해 → 전략 목적 → Skill → 후보수 → 엔진 검증 → 착수

그리고 네 번째 세대가 가르치는 상대다.

사용자가 자신의 착수 의도를 말한다.

AI 역시 자신이 생각한 의도를 기록한다.

한 판이 끝난 뒤 둘의 판단을 비교한다.

어느 쪽이 맞았는지만 보는 것이 아니라 서로 어떤 것을 보고 어떤 것을 놓쳤는지를 살펴본다.

여러 판을 두면서 비슷한 실수가 반복된다면 그것도 찾아낸다.

이 단계에 도달하면 처음 상상했던 ‘대화형 바둑 상대 + 사고 과정 교습기’에 꽤 가까워질 것이다.

그런데 첫 번째 목표는 훨씬 작게 잡기로 했다#

로드맵을 만들다 보면 마지막 모습부터 만들고 싶어진다.

LLM을 붙이고,

KataGo 같은 바둑 엔진을 연결하고,

Skills를 만들고,

복잡한 그래프를 구성하고,

멋진 대화 인터페이스까지 만들고 싶어진다.

하지만 이번에는 그렇게 시작하지 않기로 했다.

첫 번째 목표는 훨씬 작다.

9×9 바둑판에서 활로, 단수, 포획, 연결과 끊기를 나와 프로그램이 함께 이해하는 것.

아마 처음 만들어질 프로그램에는 LLM이 필요하지 않을 수도 있다.

내가 바둑판 위에 돌을 놓는다.

프로그램은 그 돌이 몇 개의 활로를 가지고 있는지 계산한다.

단수가 되면 그것을 알려준다.

돌이 잡히면 판에서 제거한다.

연결된 돌들을 하나의 그룹으로 판단한다.

나는 그 코드를 보면서 왜 그렇게 계산되는지를 이해한다.

그리고 그다음에 처음으로 LLM을 불러본다.

detect_atari

capture

escape

connect

cut

같은 아주 작은 Skill을 제공한다.

그리고 비교해본다.

아무 Skill 없이 다음 수를 생각하게 했을 때와,

방금 내가 배운 바둑 개념을 Skill로 제공했을 때,

LLM의 판단은 정말 달라지는가?

아마 그것이 이 프로젝트에서 처음으로 해볼 만한 제대로 된 실험일 것이다.

프로그램을 만들기 위해 바둑을 공부하는 것이 아니다#

처음에는 바둑 AI를 만들고 싶어서 바둑을 공부해야 한다고 생각했다.

그런데 지금은 조금 다르게 생각한다.

바둑 공부를 먼저 끝내고 나서 프로그램을 만드는 것이 아니다.

프로그램을 만드는 과정 자체를 바둑 공부로 삼아보려 한다.

활로라는 말을 처음 배우면,

그것을 프로그램에서는 어떻게 표현할 수 있는지를 생각한다.

단수를 배우면,

어떤 상태를 단수라고 판단해야 하는지 코드로 만들어본다.

축을 배우면,

사람은 축을 어떤 순서로 읽는지를 이해하고 그것을 알고리즘으로 옮겨본다.

큰 곳과 급한 곳을 배우면,

둘을 구분하는 판단 노드를 그래프에 추가한다.

그리고 그런 구조가 하나씩 쌓이는 것을 보면서 나는 바둑뿐 아니라 알고리즘과 LLM의 도구 사용, Skill 설계, 그래프 형태의 의사결정도 함께 배우게 될 것이다.

앞선 사고실험의 마지막에는 이런 질문을 남겼다.

LLM과 정말로 바둑에 대한 대화를 나누면서 한 판을 둘 수 있을까?

그 질문에 답하려면 아직 멀었다.

일단 나는 바둑판의 첫 번째 원리부터 배워야 한다.

그리고 프로그램 역시 나와 같은 곳에서 시작하게 할 생각이다.