나만의 개인 LLM을 가지고 싶었다.
누구나 그런 꿈은 하나씩 가지고 있지 않을까? 아이언맨에 나오는 자비스처럼 여러가지 도움을 받을 수 있고, 나와의 대화를 기억하는 그런 AI 비서 말이다. 그리고 무엇보다 '무료로' 사용할 수 있는 AI.
멋진 스팩을 가지고 있는 내 맥북 프로를 썩혀두기에는 조금 아쉬운 듯 하여, Ollama 모델을 받아서 한번 내 개인 AI를 만들 수 있는지 맛보기를 해보려고 한다.
llama3 모델 사용하기
먼서 Ollama에 가서 다운을 받아야 한다.
Ollama
Get up and running with large language models.
ollama.com
필자의 경우, M3칩 512G 저장공간, 36 메모리를 사용중이다. 여유롭게 사용하고 싶은 마음에 가장 최신 모델인 llama4보다 그 아래 버전인 llama3를 사용했다.
실행은 매우 간단하다. 아래의 명령어를 실행시키면 바로 동작한다.
ollama run llama3

컴퓨터 스팩만 충분하면 문제 없이 채팅을 시작할 수 있다. 생각보다 속도가 빠른 것에 놀라웠다. 한국어로 명령하면 한국어로 대답하기도 하지만, 문제는 질문을 할 때 해당 질문에 대한 것만 기억하고, 이전에 했던 질문을 기억하는 기능은 없다. 모델을 실행시키는 것 까지는 좋지만, 커스텀의 길은 멀고도 험난한 것이다.
계획 짜기
영화같은 AI를 만드는 것이 어려울 것이라는 하고 있었지만, 나와의 대화를 기억하게 하는 첫 번째 부분부터 막혀버렸다. 적어도 Bing의 코파일럿과 같이 동작해주면 좋을 것 같은데, 꽤 복잡한 작업이 될 것 같다. 우선 넣고 싶은 기능을 적어보자.
1. 웹 검색 기능
2. 나와의 대화를 기억하기
3. 말투나 성격을 제어
4. 음성으로도 소통 가능하게 만들기
이 정도가 될 것 같다. 사실 이렇게 만들어두고 나의 오랜 친구(?) 고스트에 붙여서 쓰고 싶다는 생각을 하고 있다. 실제 3D 프린팅을 통해 제작할 수 있다면 좋겠지만, 그 전까지는 웹에 띄워서 사용하는 것도 좋을 것 같다. 모델의 동작과 어느정도의 용량이 필요한지에 대한 파악도 끝나면, 내 서버에 올려서 사용하는 것도 좋을 것이다.

아무튼, 우선은 한번 제대로 Python을 통해 동작이 가능한지 테스트해보자. 음성으로 내가 말한 내용을 토대로 llama3가 답변하는 간단한 코드를 Cursor에게 작성해보라고 지시했다.
import requests
import speech_recognition as sr
import pyttsx3
import platform
import importlib.util
import os
import asyncio
import edge_tts
from langdetect import detect
OLLAMA_URL = "http://localhost:11434/api/generate"
OLLAMA_MODEL = "llama3" # 현재 사용 중인 모델명으로 변경
# TTS_MODE: 'pyttsx3', 'say', 'coqui' 중 선택. 'auto'는 자동 감지
TTS_MODE = 'say'
# 프롬프트 튜닝: Neo의 성격/역할
NEO_PROMPT = (
"너의 이름은 Neo야."
)
def ask_ollama(prompt, model=OLLAMA_MODEL):
# 프롬프트 튜닝 적용
full_prompt = f"{NEO_PROMPT}\n\n사용자: {prompt}\nNeo:"
data = {"model": model, "prompt": full_prompt, "stream": False}
try:
response = requests.post(OLLAMA_URL, json=data)
response.raise_for_status()
return response.json().get("response", "답변을 가져오지 못했습니다.")
except Exception as e:
return f"Ollama와 통신 중 오류 발생: {e}"
def listen_microphone():
recognizer = sr.Recognizer()
with sr.Microphone() as source:
print("마이크를 준비 중입니다...")
recognizer.adjust_for_ambient_noise(source, duration=1)
recognizer.pause_threshold = 2.0 # 말이 멈춘 뒤 2초 후에 인식 종료
print("질문을 시작하세요. (말이 끝나면 2초 후 자동으로 인식합니다)")
audio = recognizer.listen(source)
try:
question = recognizer.recognize_google(audio, language="ko-KR")
print(f"질문: {question}")
return question
except sr.UnknownValueError:
print("음성을 인식하지 못했습니다.")
return None
except sr.RequestError as e:
print(f"음성 인식 서비스 오류: {e}")
return None
def speak(text):
# 언어 감지
try:
lang = detect(text)
except Exception:
lang = 'ko' # 감지 실패 시 기본값
if lang == 'en':
voice = "en-US-GuyNeural" # 영어 남성
else:
voice = "ko-KR-InJoonNeural" # 한국어 남성
async def _speak():
communicate = edge_tts.Communicate(text, voice=voice)
await communicate.save("output.mp3")
os.system("afplay output.mp3")
try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = None
if loop and loop.is_running():
import nest_asyncio
nest_asyncio.apply()
asyncio.ensure_future(_speak())
else:
asyncio.run(_speak())
def main():
EXIT_KEYWORDS = [
"종료", "끝", "exit", "quit",
"그만", "그만할래", "이만할게", "이만 대화를 마칠게", "여기까지 할게", "대화 종료", "그만둘래"
]
try:
while True:
question = listen_microphone()
if not question:
continue
if any(keyword in question.strip().lower() for keyword in EXIT_KEYWORDS):
print("비서를 종료합니다.")
break
answer = ask_ollama(question)
print(f"답변: {answer}")
speak(answer)
except KeyboardInterrupt:
print("\n비서를 종료합니다.")
if __name__ == "__main__":
main()
대화 종료, 이렇게 말하면 알아서 종료까지 하도록 커스터마이즈 했고, 필요하다면 프롬프트를 직접 추가하여 성격을 지정하는 것도 가능할 것 같다. 음성도 한국어로 답변할 때와 영어로 답변할 때의 음성을 각각의 언어에 적합한 목소리로 변경하여 자연스럽게 말할 수 있도록 해두었지만, 아직 마음에 드는 목소리가 아닌 것이 아쉽다. 이 부분은 추후에 더 자연스러운 음성이 있는지 확인해보려 한다.
https://github.com/Lajancia/LLM-voice-control
GitHub - Lajancia/LLM-voice-control: chatting LLM model with mic
chatting LLM model with mic. Contribute to Lajancia/LLM-voice-control development by creating an account on GitHub.
github.com
해당 코드는 깃허브에 올려두었다. 실행 전에 llama3를 먼저 실행시켜 두어야 한다는 것을 잊지 말자.
웹 검색은 어떻게 붙일까?
문제는 이것이다. 사실 지금 사용중인 llama3는 이제 대학 전공을 선택해야 하는 고등학생과 같은 상태이다. 무궁무진한 가능성을 가졌지만, 현재 할 수 있는 것은 불특정한 주제에 대해 한정적인 답변을 하는 것이다. 때문에 우리는 이 친구에게 여러가지 학습을 시켜줘야 한다. 아니면 웹에서 검색해와 직접 답변할 수 있도록 연결해줘야 한다. 예를 들어 실시간 주식 흐름과 같은 건, 웹에 접근해 가져와야 하는 지식이다.
모델에 학습 데이터를 주어 강화시키는 것은 그래픽카드가 필요한 부분이고, 학습이 힘들더라도 웹 검색이 가능하다면 당분간 여러가지 사용할만할 정도는 될 것이다.
이렇게 검색 기능을 확장할 수 있는 방법을 찾아보던 중, 코파일럿이 LangChain 사용을 추천했다.
| LLM 래퍼 | OpenAI, Ollama, Hugging Face 등 다양한 LLM을 쉽게 연동 |
| 프롬프트 템플릿 | 사용자 입력을 구조화된 프롬프트로 변환 |
| 체인 (Chains) | 여러 단계를 연결해 복잡한 작업을 수행 |
| 에이전트 (Agents) | 상황에 따라 적절한 도구를 선택해 사용하는 지능형 흐름 |
| 도구 (Tools) | 웹 검색, 계산기, 데이터베이스 등 외부 기능과 연동 |
| RAG (Retrieval-Augmented Generation) | 문서 기반 질의응답 시스템 구축 가능 |
이런 기능을 수행할 수 있다고 하는데, 딱 내가 원하는 기능들이었다. 특히 도구! 데이터베이스와 연결이 가능하다면, 이전에 나눴던 대화를 기억하게 하여 연속적인 대화가 가능하게도 할 수 있을 것 같다.
이번 토이프로젝트에서는 llama3 + LangChain + Django 이런 조합으로 한번 개인 AI 비서를 만들어보도록 하자.
'개발 > 바이브 코딩' 카테고리의 다른 글
| Ollama + MCP Server 붙이기 - 3 (5) | 2025.07.27 |
|---|---|
| Ollama + MCP Server 붙이기 - 2 (9) | 2025.07.20 |
| Ollama + MCP Client 붙이기 - 1 (4) | 2025.07.07 |
| MCP 도전기 (4) | 2025.06.22 |