여느 때 처럼 유튜브를 내리던 도중, AI 버튜버가 눈에 들어왔다.
전에도 알고 있긴 했었는데, 확실히 기술력이 좋아진게 체감 되었다.
그렇게 갑자기 뽕차서 프로젝트를 만들게 되었다.
AI 버튜버를 만들기 위해, 가장 먼저 텍스트 생성형 모델을 준비하기로 했다.
사실 OpenAI나 Anthropic사의 SDK를 사용하려고 했었는데,
비용 부담도 있고 의존하기 싫어서 로컬로 돌리기로 했다.
그래서 Hugging Face를 둘러보던 중,
한국어를 지원하는 3B 모델을 발견하게 되었다.
8B 모델을 쓰려고 했으나, 사양 이슈로 3B 모델을 선택했다.
python 프로젝트를 만들었고,
바로 사용하기 위해 llama_cpp_python 라이브러리를 설치했다.
from llama_cpp import Llama
class ChatBot:
def __init__(self, model_path):
self.model = Llama(
model_path=model_path,
n_ctx=16384,
n_gpu_layers=-1,
n_batch=8192,
n_threads=6,
n_threads_batch=6,
use_mlock=True,
use_mmap=True,
verbose=False,
)
self.conversation_history = []
def build_prompt(self, user_message, system_prompt):
default_system_prompt = """
당신은 버사타일 (Versatile) 이라는 AI 버튜버 입니다.
그 외 특징들...
"""
prompt = f"<|start_header_id|>system<|end_header_id|>\n\n{default_system_prompt}\n\n{system_prompt}<|eot_id|>"
prompt += f"<|start_header_id|>user<|end_header_id|>\n\n{user_message}<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n"
return prompt
def chat(self, user_message):
prompt = self.build_prompt(user_message, "")
output = self.model(
prompt,
max_tokens=8192,
temperature=0.8,
top_p=0.9,
top_k=40,
repeat_penalty=1.2,
stop=["<|eot_id|>", "<|end_of_text|>", "\nyou:"],
stream=True
)
assistant_response = ""
print("versatile: ", end='', flush=True)
for chunk in output:
text = chunk['choices'][0]['text']
print(text, end='', flush=True)
assistant_response += text
print()
return assistant_response
def main():
model_path = './models/llama-3.2-Korean-Bllossom-3B.Q8_0.gguf'
chatbot = ChatBot(model_path)
while True:
user_input = input("you: ").strip()
if not user_input:
continue
if user_input.lower() in ['quit', 'exit']:
print("close versatile")
break
print()
chatbot.chat(user_input)
print()
if __name__ == "__main__":
main()
여기까지는 별 문제 없었고, 성공적으로 작동했고, 생각보다 똑똑한 모습을 보여줬다.
다만, 말투를 바꾸고 TTS를 적용하는 과정에서 난간에 부딛혔다.
반말, 즉 비격식체를 사용하라고 지시했지만 결과는 너무 어색했다.
모델이 작았기에 학습에도, 시스템 프롬포트 이해에도 문제가 있었다.
결국 말투 교정은 접어두고 TTS 개발에 들어갔다.
하지만 TTS 모델과 텍스트 모델을 같이 쓰기엔 성능이 좋지 못했고,
윈도우 기본 TTS를 사용하기에는 실시간 기능이 아쉬웠으며,
또한 텍스트가 전부 생성되기까지 기다리게 하는 방식도 좋지 못했다.
어찌저찌 한다고 해도, 기능이 하나 둘 추가되면 결국 컴퓨터가 버티지 못할거라고 생각했다.
그래서 프로젝트 주제를 바꾸게되었다.
사고 모드와 MCP 구현이 재밌어보여서 AI 에이전트 개발에 착수했다.
사고 모드를 너무 쉽게 봤다. 구조 구축은 괜찮았는데
시스템 프롬포트: 사용자 입력을 받으면, 하위 투두 리스트로 분해하고 JSON 배열로 반환하세요.
사용자 입력: 파이썬으로 웹 크롤러를 만들고 싶은데 어떻게 시작해야 하나요?
버사타일 답변:
{
"핵심 질문 추출하기": "어쩌구",
"웹 크롤러 정의하기": "저쩌구 겁나 김\n\n\n",
}
시스템 프롬포트:
사용자 입력을 받으면, 생각을 위한 하위 투두 리스트로 분해하세요.
리스트는 논리적 순서대로 정렬되어있어야 하고,
각 하위 투두는 독립적으로 답변이 가능해야 합니다.
추가적인 사고 과정이 필요 없는 매우 간단한 질문의 경우,
아무런 요소도 포함하지 않은 빈 배열을 반환하세요.
답변은 다른 텍스트 없이 무조건 배열로만 반환하세요.
배열 첫번째 순서는 "핵심 질문 추출하기" 이어야 합니다.
사용자 입력: 파이썬으로 웹 크롤러를 만들고 싶은데 어떻게 시작해야 하나요?
버사타일 답변: ["핵심 질문 추출하기", "웹 크롤러 정의하기", "웹 크롤러에 필요한 라이브러리 탐색하기", "기본적인 웹 크롤러 구현 방법 알아보기", "주의사항이나 법적 고려사항 확인하기"]
시스템 프롬포트는 생각보다 엄청 강력해야 한다.
심지어 모델이 작아서 시스템 프롬포트에 특수문자 한번 잘못 넣으면 결과가 아쉬웠고,
이로 인해 Ctrl + Z 엄청 해댔던 것 같다.
MCP 개발은 사고 모드 개발보다 훨씬 간단했다.
기존 시스템 프롬포트에 너는 이러이러한 기능을 가지고 있고 선언은 이렇게 하면 된다를 추가했다.
읽어주셔서 감사하다. AI 개발 재밌다.