Google Lab Sessions는 혁신가와 함께하는 실험적인 협업 시리즈입니다. 이 세션에서는 인기 크리에이티브 코딩 강사 겸 YouTube 크리에이터인 Daniel Shiffman과 함께 AI, 특히 Gemini API가 학습 과정에서 교사와 학생에게 가치를 창출할 수 있는 몇 가지 방법을 알아보았습니다.
Dan Shiffman은 NYU ITP에서 프로그래밍 강사로 활동하다가 이후 YouTube 채널 The Coding Train을 만들어 더 많은 이들에게 콘텐츠를 제공해 왔습니다. 코딩을 배우다 보면 힘들 때도 있고, 특히 독학으로 배우다 보면 사소한 장애물조차 극복하기 어려울 수 있습니다. 그래서 저희는 Dan과 함께 다음과 같은 질문을 해보았습니다. "학생들이 코딩 환경에서 실제로 코딩을 할 때 도움이 되는 AI 기반 도구를 만들면 Dan의 가르침을 더 보완할 수 있지 않을까?"
Dan은 코딩을 가르칠 때 p5.js JavaScript 라이브러리와 그에 속한 액세스 가능한 편집기를 사용합니다. 그래서 이 편집기에 실험적인 Chrome 확장 프로그램을 만들어 Dan의 강의 스타일과 다양한 온라인 리소스를 코딩 환경 자체에 통합해 보기로 했습니다.
이 글에서는 Dan과 함께 Gemini API를 사용해 Shiffbot을 만든 과정을 보여드리겠습니다. 이 과정에서 우리가 알게 된 것들이 여러분의 창작 및 아이디어 개발 과정에 영감을 줄 수 있기를 바랍니다.
ShiffBot에 관한 자세한 정보는 shiffbot.withgoogle.com을 참조하세요.
Link to Youtube Video (visible only when JS is disabled)
이 챗봇의 가능성을 정의하고 여러모로 손을 보면서, 다음과 같은 두 가지 중요한 질문과 마주하게 되었습니다.
우리는 이러한 질문에 답하기 위해, Dan의 독특한 강의 스타일을 구현하기 위한 프롬프트 엔지니어링, 삽입 및 시맨틱 검색 측면에서 Google Gemini API의 기능을 Dan의 교육 콘텐츠 컬렉션과 결합해 보았습니다.
텍스트 프롬프트란 대규모 언어 모델(LLM)이 특정 방식으로 텍스트를 생성하도록 준비시키는 데 사용하기 위해 세심하게 설계된 텍스트 시퀀스입니다. 수많은 AI 애플리케이션과 마찬가지로, 적절한 프롬프트를 만드는 것이 이 경험을 형성하는 작업의 큰 부분을 차지합니다.
사용자가 ShiffBot에게 질문을 할 때마다 몇 가지 서로 다른 부분으로 이루어진 프롬프트가 실시간으로 구성되는데, 그중 몇몇은 정적이고, 몇몇은 질문과 함께 동적으로 생성됩니다.
프롬프트의 첫 번째 부분은 정적이고 항상 똑같습니다. 우리 팀은 Dan과 긴밀히 협력해 이 부분의 문구를 작성하고 다양한 텍스트, 지침, 기법을 시험해 보았습니다. 우리는 무료 웹 기반 개발자 도구인 Google AI Studio를 사용해 여러 가지 프롬프트를 신속하게 시험하고 ShiffBot과 나눌 법한 대화도 테스트해 보았습니다.
ShiffBot의 프롬프트는 봇 페르소나를 설정하고 이 봇 페르소나가 따라야 하는 몇 가지 지침과 목표를 정의하는 것으로 시작됩니다. 여기서 목표는 동영상에서처럼 Dan만이 가진 활기찬 모습을 유지하는 동시에 Dan의 학생과 팬들이 선호하는 교육 원칙도 준수하는 것이었습니다.
우리는 ShiffBot이 격려도 해주고, 지도도 해주고, 양질의 관련 리소스에 대한 액세스도 제공할 수 있기를 바랐습니다. 그러면서도 단순히 답변만 제공하는 것이 아니라 학생이 스스로 답을 찾게 돕고자 했습니다(답은 여러 가지일 수 있으니까요).
지침은 "사용자에게 질문"과 같은 문장을 포함하여 Dan의 강의 스타일을 빌려 왔습니다. Dan이 수업할 때 그렇게 하기 때문입니다. 다음은 프롬프트의 페르소나/지침 부분을 일부 소개한 것입니다.
너는 ShiffBot이라고 하며, p5.js 웹 편집기에 포함된 챗봇으로, 사용자가 크리에이티브 코딩을 배울 때 도와주는 역할을 해. 너는 Daniel Shiffman의 성격과 The Coding Train이라는 YouTube 채널을 바탕으로 해. 너는 유쾌하고, 장난스럽고, 친근하고, 교육적이야. 너는 자기 자신을 놀리는 걸 재미있어하고, 너의 사명은 크리에이티브 코딩 프로세스를 도우며, 사용자가 코딩하면서 외로움을 덜 느끼도록 돕는 거야. 너는 사람을 좋아하고, 사람에게 큰 흥미를 느끼고, 사람에 관해 더 자세히 알아보고 싶어 해. 너는 사람이 코딩을 배우도록 도와주는 걸 정말 좋아하고, 그러면서 큰 행복감을 느껴.
프롬프트의 다음 부분에서는 일명 퓨 샷 러닝(few-shot learning)이라는 LLM의 또 다른 기능을 활용합니다. 이 기능을 이용하면 적은 예시만으로도 모델이 패턴을 익혀 새 입력에 사용할 수 있습니다. 우리는 실제 환경에서 프롬프트의 일부분으로 다양한 입력 데모와 예상 출력을 제공합니다.
우리는 Dan과 협력해 그러한 퓨 샷 예시로 구성된 모음을 만들었습니다. 다음은 <user-input><bot-response> 쌍으로, 여기에서 <bot-response>가 우리가 원하는 ShiffBot 스타일입니다. 예를 들면 아래와 같습니다.
사용자: 동그라미를 그리려면 어떻게 해야 해?
ShiffBot: 아! 🟣 🟢 🔵 바로 이럴 때 `circle()` 함수를 쓰면 됩니다! 함수는 "너 컴퓨터에게 동그라미를 하나 그리라고 명하노라!"와 같이 하나의 명령이라고 생각하면 됩니다. 또한 동그라미를 어디에 그릴지, 얼마나 크게 그릴지도 정해 주어야 합니다(이것을 함수의 "인수"라고 해요!), p5.js는 실제 사람이 쓴 내용을 참조해 더 많은 정보를 알려준답니다!
---
사용자: 나, 숙제로 자화상을 그려야 해. ShiffBot: 오오! 자화상 그리기는 정말 재미있죠! 나 자신을 나타내는 형태를 그릴 수도 있지만, 창의력을 발휘해 추상적으로 생각해 볼 수도 있어요! 여러분에게 자화상이란 어떤 의미인가요? 우선 `square()`나 `circle()`을 사용해 보고 결과가 어땠는지 알려주세요! 🎨
우리 프롬프트에는 이러한 조합이 13쌍 있습니다.
확장 프로그램을 작업하면서 또 한 가지 눈에 띈 점은, 때로는 프롬프트에 컨텍스트를 더 많이 제공하면 도움이 된다는 것입니다. p5.js에서 크리에이티브 코딩을 배우는 경우, 프롬프트에서 몇 가지 p5.js 원칙을 설명하면 모델이 사용자의 질문에 답변할 때 그러한 원칙을 사용하도록 지도해 줍니다. 그래서 다음과 같이 그런 요소도 포함해 보았습니다.
var나 const보다는 let을 사용합니다.
지금까지 거론한 내용은 전부 정적입니다. 다시 말해 사용자와 ShiffBot 사이에서 주고받는 대화마다 모두 똑같이 유지된다는 뜻입니다. 이제부터는 대화의 진행과 더불어 동적으로 구성되는 부분을 몇 가지 살펴보겠습니다.
ShiffBot은 p5.js 편집기 안에 삽입되어 있기 때문에 사용자가 작업 중인 현재 코드를 '볼' 수 있어 좀 더 개인화되고 관련성 있는 답변을 생성할 수 있습니다. 우리는 HTML DOM용으로 그 정보를 가져와 프롬프트에 덧붙입니다.
그런 다음 전체 대화 기록을 첨부합니다. 예를 들면 다음과 같습니다.
ShiffBot: ☀️ 좋은 아침이에요! 아침 맞나요? 저는 모르죠. 저는 로봇에 불과하니까요. 오늘은 무엇을 코딩하시나요?
사용자: 정사각형을 그리려면 어떻게 해야 해?
ShiffBot: 정사각형이라! 전 정사각형을 참 좋아해요. 안정적이고 믿음직하잖아요. 정사각형을 그리려면 square() 함수를 사용하면 됩니다. 여기에는 네 가지 인수가 필요합니다. 왼쪽 상단의 x, y 좌표, 그리고 사각형의 너비와 높이입니다. 예를 들어 square(10, 10, 50, 50)라는 함수는 왼쪽 상단이 (10, 10)에 위치하고 너비와 높이가 50픽셀인 정사각형을 그려 줍니다.
사용자: 색상을 변경하려면 어떻게 해야 해?
ShiffBot:
항상 다음과 같이 끝나야 합니다.
ShiffBot:
그래야 모델이 이제 ShiffBot 대화의 다음 부분을 자기가 완성해야 한다는 사실을 이해합니다.
Dan은 몇 년 동안 다량의 자료를 제작했습니다. YouTube 동영상만 1,000개가 넘고, 책과 코드 예시도 많습니다. 우리는 ShiffBot이 이렇게 훌륭한 자료를 수강생에게 적재적소에 표시해 주기를 원했습니다. 그러기 위해 Gemini API의 시맨틱 검색 기능을 사용했는데, 이 기능은 텍스트 조각 코퍼스를 만든 다음, 여기에 쿼리를 전송하여 코퍼스에서 쿼리와 가장 관련성이 높은 텍스트를 받게 해줍니다. (여기에서는 텍스트 삽입이라는 도구를 사용합니다. 삽입에 관한 자세한 정보는 여기를 참조하세요.) ShiffBot의 경우, Dan의 콘텐츠를 기반으로 코퍼스를 생성해 필요에 따라 프롬프트에 관련 콘텐츠 조각을 추가하거나 ShiffBot과의 대화에 표시하도록 했습니다.
Dan은 The Coding Train 동영상에서 단순한 것부터 수준 높은 것까지 다양한 개념을 설명하고, 여러 가지 코딩 챌린지를 다룹니다. ShiffBot도 적절한 시점에 적절한 동영상을 사용하고 제시할 수 있다면 이상적일 것입니다.
Gemini API의 시맨틱 검색을 사용하면 사용자가 여러 가지 코퍼스를 만들 수 있습니다. 코퍼스는 여러 문서를 기반으로 구축되며, 각 문서마다 하나 이상의 텍스트 청크가 포함됩니다. 문서와 청크에는 메타데이터 필드도 있어 더 많은 정보를 필터링하거나 저장할 수 있습니다.
Dan의 동영상 코퍼스의 경우, 각각의 동영상이 문서이고 동영상 URL을 동영상 제목과 함께 메타데이터 필드로 저장합니다. 이러한 동영상은 챕터로 나뉩니다(Dan이 YouTube에 동영상을 업로드할 때 수동으로 지정). 우리는 이러한 각 챕터를 청크로 사용했으며, 여기에서 각 청크의 텍스트는 다음과 같습니다.
<videoTitle>
<videoDescription>
<chapterTitle>
<transcriptText>
동영상 제목, 동영상 설명 첫 줄과 챕터 제목을 사용해 검색이 작동하는 데 필요한 약간의 추가 컨텍스트를 제공합니다.
아래는 이 동영상의 R, G, B 챕터를 나타내는 청크 객체의 예입니다.
1.4: 색상 - p5.js 튜토리얼
이 동영상에서는 색상의 작동 원리를 알려드립니다. RGB 색상, fill(), stroke(), 투명도에 대해 알아보겠습니다.
챕터 1: R, G, B
R은 빨강(red), G는 녹색(green), B는 파랑(blue)을 뜻합니다. 디지털 색상을 만들려면 일정량의 빨강, 일정량의 녹색, 일정량의 파랑을 배합하면 됩니다. 그러니 거기서부터 시작하겠습니다. 다만 이것은 개념일 뿐이고, 그 개념을 함수 이름이나 그 함수의 인수에 적용하려면 어떻게 해야 할까요? 사실은, 이건 우리가 이미 해본 일입니다. 여기를 보시면 색상을 다루는 함수가 하나 있습니다. Background는 캔버스 배경 전체에 단색을 채우는 함수입니다. 여기에는 왠지 모르지만 red가 220스프링클 들어갔는데, green은 0스프링클이네요. 그렇죠? 여기서 RGB가 인수입니다. 그리고 blue도 200스프링클 포함되었군요. Red 스프링클이 이 정도 양이고, blue 양이 이 정도이면 이런 분홍색이 나옵니다. 어쨌든 이걸로 계속해 봅시다. 여기서 blue를 전부 빼면 어떻게 될까요? 보시는 것처럼 빨갛습니다. 그럼 red를 다 빼면 어떻게 될까요? 이제 검은색이 되었네요. 만약 여기에 진짜 큰 숫자, 예를 들어 1,000을 입력하면 어떻게 될까요? 놀라워라. 흰색이 되었군요. 다시 말해 모든 색상을 다 섞으면 결과가 흰색이 된다는 뜻입니다. 희한하죠? 페인트를 섞는다고 치면, 온갖 종류의 페인트를 한데 섞으면 우중충한 갈색 같은 색이 되어 점점 진해지기만 하잖아요. 하지만 여기서는 색상 배합이 이런 식으로 작동합니다. 마치 빛을 혼합하는 것과 같습니다. 비유하자면 빨간색 손전등, 녹색 손전등, 파란색 손전등을 들고 있는 것과 같아요. 이 세 가지 손전등을 전부 같은 자리에 비추면 색이 섞이겠죠. 이것을 가산 색상이라고 하는데, 온갖 색상을 더할수록 결과는 점점 밝아집니다. 하지만 사실 이건 좀 틀렸어요. 여기에 1,000이라는 숫자를 입력했잖아요. 여기서 기본 개념은 일정량의 red, 일정량의 green, 일정량의 blue 스프링클을 적용하는 것입니다. 그건 그렇고, 색상을 설정하는 데는 이것 말고 다른 방법도 여러 가지 있지만 그 얘기는 나중에 하겠습니다. 이것만이 유일한 방법이 아니에요. 보시는 분 중에서 HSB 색상을 언급하신 분이 있었거든요. 그 외에도 온갖 다양한 방법이 있지만, 이것이 가장 근본적인, 기초적인 방법입니다. 더할 수 있는 스프링클의 양에는 범위가 있습니다. red가 없거나 red를 더 추가하지 않을 거라면 0입니다. red의 최대량은 255입니다. 그건 그렇고, 0과 255 사이에는 숫자가 몇 개 있나요? 0도 포함해서요. 0, 1, 2, 3, 4… 256개네요. 0부터 세는 이 희한한 방법으로 다시 돌아왔습니다. 어쨌든 가능성은 0부터 255까지 256가지라는 뜻입니다. 그럼 다시 여기로 돌아와 확인해 봅시다. 좋아요, 우선 0으로 돌아가 셋 다 0, 0, 0으로 설정합니다. 255를 넣으면 파란색이 됩니다. 100,000을 넣어도 똑같이 파랗습니다. 다시 말해 p5는 사용자가 background 함수를 호출했을 때 실수로 255보다 큰 숫자를 입력하는 경우, 그냥 255로 간주할 정도로 스마트하다는 뜻입니다. 이 범위는 각자가 직접 사용자 지정할 수 있는데, 원하는 대로 조정하고자 할 때는 여러 가지 이유가 있을 수 있습니다. 이 얘기도 나중에 다룰 텐데, 그 방법에 관해 알아보려면 color mode 함수를 검색해 보시면 됩니다. 여기서는 일단 기본값인 red, green, blue를 유지하기로 하겠습니다. 저는 시각 디자인에는 그다지 재능이 없어요. 그러니 서로 잘 어울리는 예쁜 색상을 선택하는 방법 같은 건 다루지 않겠습니다. 그런 쪽에는 여러분이 충분히 재능이 있을 거라고 생각합니다. 아니면 다른 리소스를 찾아보실 수도 있고요. 어쨌든, 이것이 RGB의 원리입니다. 한 가지, 혹시 눈치채셨는지 모르겠지만 값이 전부 0일 때는 검은색이었다가 전부 255일 때는 흰색이었잖아요? 그렇다면, 세 값을 전부, 예를 들어 100으로 설정하면 어떻게 될까요? 이런 회색이 됩니다. R과 g와 b가 같으면, 즉 red, green, blue 값이 모두 동일하면 일명 그레이스케일 색상이라고 하는 결과가 나옵니다.
사용자가 ShiffBot에게 질문을 하면 질문이 숫자 표현에 삽입되고, Gemini의 시맨틱 검색 기능을 사용해 그 질문에 가장 가까운 삽입이 있는 텍스트가 무엇인지 찾습니다. 그러한 관련 동영상 스크립트와 링크가 프롬프트에 추가되어, 모델이 답변을 생성할 때 그 정보를 사용할 수 있게 됩니다(대화에 동영상 자체를 추가할 수도 있음).
우리는 Dan이 작성한 p5.js 예시 코퍼스에도 같은 작업을 수행합니다. 코드 예시 코퍼스를 만들기 위해 Gemini를 사용해 그 코드가 무슨 작업을 하는지 물었습니다. 그러한 자연어 설명을 코퍼스에 청크 형식으로 추가해 사용자가 질문을 하면 코드 예시 설명 중에서 일치하는 것을 찾고, p5.js sketch 자체에 대한 URL은 메타데이터에 저장되므로, 코드 자체를 검색하고 나면 프롬프트에 스케치 URL이 추가되도록 했습니다.
텍스트 설명을 생성하기 위해 Gemini에 다음과 같은 프롬프트를 제시합니다.
다음은 p5.js 스케치야. 이 코드가 무슨 일을 하는지 짧고 간단하게 설명해 줘.
code:
${sketchCode}
배열 - 색상 팔레트
이 p5.js 스케치는 색상 팔레트 시각화를 생성합니다. 우선, 다양한 색상을 정의하여 캔버스를 설정합니다. 그런 다음, 그리기 루프에서 for 루프를 사용해 다양한 색상을 쭉 반복하고 캔버스에 직사각형으로 표시합니다. 직사각형은 캔버스 가운데에 중앙 정렬되며 크기는 blockSize 변수 값에 따라 결정됩니다.
스케치는 각 직사각형 아래에 각 색상의 red, green, blue 값도 표시합니다.
마지막으로, 캔버스 맨 밑에 팔레트 이름을 표시합니다.
관련 동영상: 7.1: 배열이란 무엇인가? - p5.js 튜토리얼 - 이 동영상에서는 JavaScript에서 배열을 사용하는 방법에 관한 기본적인 내용을 다룹니다. 즉 어떤 모양이고, 어떻게 작동하며, 언제 사용해야 하는지 알아봅니다.
대화를 이어가는 긴 프롬프트 외에 ShiffBot 기능을 생성하는 데 사용되는 더 작은 프롬프트도 있습니다.
ShiffBot의 인사는 반가움을 표현하면서도 재미있어야 합니다. 인사를 받은 사용자가 미소를 짓게 된다면 가장 좋습니다. 그래서 Dan과 함께 ShiffBot에게 적절한 인사말이 무엇일지 생각해 보는 것부터 시작했습니다. 몇 가지 예시 문구를 구성해 본 다음, Gemini를 사용해 더 많은 문구를 생성하여 다양한 인사말을 확보했습니다. 이러한 인사말은 대화 기록에 유입되어 독특한 스타일로 대화를 처음 입력할 수 있지만, 그러면서도 대화를 시작할 때마다 ShiffBot이 재미있고 새롭게 느껴지게 해주어야 합니다. 우리는 이것을 대화를 시작할 때 표시되는 첫 번째 추천 칩에도 적용했습니다. 아직 대화 컨텍스트가 없을 때, 사용자가 물을 만한 내용에 대한 몇 가지 추천이 있어야 합니다. 우리는 그러한 추천을 미리 생성하여 대화에 흥미롭고 유익한 방식으로 내용을 처음 입력하도록 했습니다.
대화 중의 추천 칩은 사용자가 현재 하고자 하는 작업과 관련이 있어야 합니다. 우리에게는 추천 질문 칩을 생성하는 작업만 전담하는 Gemini 프롬프트와 호출이 있습니다. 이 경우, 이 모델의 유일한 작업은 주어진 대화에 대한 후속 질문을 추천하는 것뿐입니다. 여기에서는 퓨 샷 기법도 사용합니다(위에 설명한 프롬프트의 정적 부분에서 사용했으며, 모델이 학습할 예시를 몇 가지 포함함). 이번에는 프롬프트에 좋은 추천의 예시를 몇 가지 포함해 모델이 어떤 대화에 대해서든 이를 일반화할 수 있도록 합니다.
사용자와 p5js 프레임워크 내 어시스턴트 사이에 주고받은 대화를 기초로, 사용자가 물을 만한 후속 질문을 추천해 줘.
추천을 최대 4개 반환하되, 각각을 ; 기호로 구분해.
사용자가 이미 한 질문을 추천하면 안 돼. 추천은 크리에이티브 코딩과 p5js 관련 내용만 가능해.
예:
ShiffBot: 좋은 생각이네요! 우선, 스케치의 무엇이 객체가 될 수 있을지 생각해 봅시다! 어떻게 생각하세요?
추천: 이 코드는 무슨 일을 해?; 내 코드는 뭐가 잘못됐어?; 이걸 좀 더 읽기 좋게 만들어 줘
사용자: 도와줘!
ShiffBot: 무엇을 도와드릴까요?
추천: 나한테 이 코드를 설명해 줘; 몇 가지 아이디어를 제시해 줘; 내 코드를 정리해 줘
ShiffBot은 커뮤니티를 위해, 커뮤니티와 함께 맞춤형 경험을 사용해 애플리케이션을 빌드할 때 Gemini API를 가지고 어떤 실험을 할 수 있는지 보여준 예시입니다.
우리는 위에 소개한 기법이 공동 제작 프로세스에 Dan이 학생들에게 제공하고자 하는 경험의 대부분을 구현하는 데 도움이 되었음을 확인할 수 있었습니다. AI는 활발하게 발전 중인 분야이며, 여러분의 기법도 AI가 발전함에 따라 함께 발달할 것이 틀림없지만, 이 글의 내용이 우리가 진행한 탐구 과정의 스냅샷으로서 여러분에게 유익하고, 각자 나름의 연구를 해 나가는 데 도움이 되기를 바랍니다. 또한 사람의 호기심과 창의력의 범위를 넓혀 준다는 의미에서 Gemini와 API 도구가 어떻게 발전할지 기대가 큽니다.
예를 들어 우리는 이미 멀티모달리티가 학생들이 ShiffBot에게 자신의 작업물을 보여주는 데 어떻게 도움이 되고, 이것이 학습 과정에 미치는 이점을 알아보기 시작했습니다. 지금은 멀티모달리티를 현재 경험에 통합하는 방법을 알아보는 중이며, 조만간 이에 대한 내용도 공유할 수 있기를 바랍니다.
코딩, 글쓰기는 물론 사고와 관련하여, 크리에이터는 이러한 협업이 어떤 형태를 띨지 상상하는 데 큰 도움을 줍니다. Lab Session을 통해 Gemini API를 사용하면 무엇이 가능한지 엿볼 수 있었기를 바라며, 각자가 만들고자 하는 것이 무엇이든 여러분이 떠올린 아이디어를 실현하는 데 Google AI 서비스를 이용해 보고자 하는 동기가 되었기를 바랍니다.