반응형
SMALL
LM Studio로 나만의 AI 비서 만들기: Windows에서 웹 서버 구축 가이드
LM Studio를 활용하여 로컬 AI 모델을 실행하고, 웹 인터페이스를 통해 어디서나 접속할 수 있는 개인 AI 비서 시스템을 구축하는 방법을 단계별로 알려드립니다.
1단계: LM Studio 설치 및 설정
LM Studio는 로컬 컴퓨터에서 대형 언어 모델을 쉽게 실행할 수 있게 해주는 도구입니다.
- LM Studio 공식 웹사이트(https://lmstudio.ai/)에서 Windows용 설치 파일을 다운로드합니다.
- 다운로드한 설치 파일을 실행하고 설치 마법사의 지시에 따라 LM Studio를 설치합니다.
- 설치가 완료되면 LM Studio를 실행합니다.
2단계: 로컬 모델 다운로드 및 설정
- LM Studio를 실행한 후, "Models" 탭으로 이동합니다.
- 목록에서 원하는 모델을 선택하거나 검색할 수 있습니다. 처음 사용하는 경우 Mistral 7B이나 Llama 2 7B와 같은 작은 크기의 모델부터 시작하는 것이 좋습니다.
- 선택한 모델 옆의 다운로드 버튼을 클릭하여 모델을 다운로드합니다.
- 다운로드가 완료되면 모델을 선택하고 "Local Server" 탭으로 이동합니다.
3단계: LM Studio 로컬 서버 실행
- "Local Server" 탭에서 "Start Server" 버튼을 클릭하여 로컬 API 서버를 시작합니다.
- 서버가 시작되면 기본적으로 http://localhost:1234 주소에서 실행됩니다.
- 이 API 서버는 OpenAI와 호환되는 API를 제공하므로, OpenAI API를 사용하는 코드를 활용할 수 있습니다.
4단계: 파이썬으로 웹 서버 개발 환경 준비
- 파이썬을 아직 설치하지 않았다면, Python 공식 웹사이트(https://www.python.org/downloads/)에서 최신 버전을 다운로드하고 설치합니다.
- 명령 프롬프트나 PowerShell을 열고 필요한 라이브러리를 설치합니다:
pip install flask openai requests
5단계: AI 비서 웹 서버 코드 작성
- 새로운 폴더를 만들고 그 안에
app.py
파일을 생성합니다. - 아래와 같이 기본적인 Flask 앱 코드를 작성합니다:
from flask import Flask, request, render_template, jsonify
import openai
app = Flask(__name__)
# LM Studio 로컬 서버 설정
openai.api_base = "http://localhost:1234/v1"
openai.api_key = "lm-studio" # 아무 값이나 설정해도 됩니다
@app.route('/')
def index():
return render_template('index.html')
@app.route('/chat', methods=['POST'])
def chat():
data = request.json
user_message = data.get('message', '')
try:
response = openai.ChatCompletion.create(
model="local-model", # LM Studio에서 실행 중인 모델
messages=[
{"role": "system", "content": "당신은 도움이 되는 AI 비서입니다."},
{"role": "user", "content": user_message}
]
)
ai_response = response.choices[0].message.content
return jsonify({"response": ai_response})
except Exception as e:
return jsonify({"error": str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
6단계: HTML 템플릿 작성
- 프로젝트 폴더 안에
templates
폴더를 생성합니다. templates
폴더 안에index.html
파일을 생성하고 다음 코드를 작성합니다:
<!DOCTYPE html>
<html>
<head>
<title>나만의 AI 비서</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
#chat-container {
height: 400px;
overflow-y: auto;
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 10px;
}
.user-message {
background-color: #e1f5fe;
padding: 8px;
border-radius: 5px;
margin-bottom: 10px;
}
.ai-message {
background-color: #f1f1f1;
padding: 8px;
border-radius: 5px;
margin-bottom: 10px;
}
#message-input {
width: 70%;
padding: 8px;
}
#send-button {
padding: 8px 15px;
}
</style>
</head>
<body>
<h1>나만의 AI 비서</h1>
<div id="chat-container"></div>
<div>
<input type="text" id="message-input" placeholder="메시지를 입력하세요...">
<button id="send-button">전송</button>
</div>
<script>
const chatContainer = document.getElementById('chat-container');
const messageInput = document.getElementById('message-input');
const sendButton = document.getElementById('send-button');
function addMessage(content, isUser) {
const messageDiv = document.createElement('div');
messageDiv.className = isUser ? 'user-message' : 'ai-message';
messageDiv.textContent = content;
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
async function sendMessage() {
const message = messageInput.value.trim();
if (!message) return;
// 사용자 메시지 추가
addMessage(message, true);
messageInput.value = '';
try {
const response = await fetch('/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ message })
});
const data = await response.json();
if (data.error) {
addMessage('오류가 발생했습니다: ' + data.error, false);
} else {
addMessage(data.response, false);
}
} catch (error) {
addMessage('서버 연결 오류가 발생했습니다.', false);
console.error('Error:', error);
}
}
sendButton.addEventListener('click', sendMessage);
messageInput.addEventListener('keypress', (event) => {
if (event.key === 'Enter') {
sendMessage();
}
});
</script>
</body>
</html>
7단계: 웹 서버 실행 및 테스트
- 프로젝트 폴더에서 명령 프롬프트를 열고 다음 명령어로 Flask 앱을 실행합니다:
python app.py
- 서버가 실행되면 웹 브라우저를 열고
http://localhost:5000
으로 접속하여 AI 비서와 대화할 수 있습니다. - LM Studio의 로컬 서버가 계속 실행 중인지 확인하세요. 만약 중지되었다면 다시 시작해야 합니다.
8단계: 외부 접속을 위한 설정
같은 네트워크 내에서 다른 기기로 접속하려면 컴퓨터의 로컬 IP 주소를 확인해야 합니다:
ipconfig
명령어를 실행하여 IPv4 주소를 확인합니다.
확인한 IP 주소(예: 192.168.1.5)와 포트를 사용하여 다른 기기에서
http://192.168.1.5:5000
으로 접속할 수 있습니다.
9단계: Ngrok을 사용한 외부 접속 설정
인터넷을 통해 외부에서 접속하려면 Ngrok과 같은 터널링 서비스를 사용할 수 있습니다:
- Ngrok 웹사이트(https://ngrok.com/)에서 계정을 만들고 Ngrok을 다운로드합니다.
- 다운로드한 파일의 압축을 풀고 Ngrok 실행 파일을 적절한 위치에 저장합니다.
- 명령 프롬프트를 열고 Ngrok이 있는 디렉토리로 이동한 후, 다음 명령어를 실행합니다:
ngrok http 5000
- Ngrok이 제공하는 URL(예: https://abcd1234.ngrok.io)을 통해 인터넷에서 어디서나 AI 비서에 접속할 수 있습니다.
10단계: 시스템 기능 확장하기
대화 기록 저장 기능 추가
app.py
파일에 대화 기록을 저장하는 기능을 추가합니다:
import json
from datetime import datetime
# 대화 기록을 저장할 함수
def save_conversation(user_message, ai_response):
try:
# 대화 기록 파일 열기 (없으면 새로 생성)
try:
with open('conversations.json', 'r', encoding='utf-8') as f:
conversations = json.load(f)
except FileNotFoundError:
conversations = []
# 새 대화 추가
conversations.append({
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'user': user_message,
'ai': ai_response
})
# 파일에 저장
with open('conversations.json', 'w', encoding='utf-8') as f:
json.dump(conversations, f, ensure_ascii=False, indent=2)
except Exception as e:
print(f"대화 저장 중 오류 발생: {e}")
# chat 함수 수정
@app.route('/chat', methods=['POST'])
def chat():
data = request.json
user_message = data.get('message', '')
try:
response = openai.ChatCompletion.create(
model="local-model",
messages=[
{"role": "system", "content": "당신은 도움이 되는 AI 비서입니다."},
{"role": "user", "content": user_message}
]
)
ai_response = response.choices[0].message.content
# 대화 저장
save_conversation(user_message, ai_response)
return jsonify({"response": ai_response})
except Exception as e:
return jsonify({"error": str(e)}), 500
다중 사용자 지원 기능 추가
- 사용자 인증을 위한 간단한 로그인 시스템을 추가합니다:
app.py
파일에 다음 코드를 추가합니다:
from flask import session, redirect, url_for
import os
app.secret_key = os.urandom(24) # 세션을 위한 비밀 키
# 사용자 계정 (실제 시스템에서는 데이터베이스를 사용해야 함)
users = {
"user1": "password1",
"user2": "password2"
}
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if username in users and users[username] == password:
session['username'] = username
return redirect(url_for('index'))
else:
return render_template('login.html', error='잘못된 사용자 이름 또는 비밀번호입니다.')
return render_template('login.html')
@app.route('/logout')
def logout():
session.pop('username', None)
return redirect(url_for('login'))
# 기존 index 함수 수정
@app.route('/')
def index():
if 'username' not in session:
return redirect(url_for('login'))
return render_template('index.html', username=session['username'])
templates
폴더에login.html
파일을 생성하고 다음 코드를 작성합니다:
<!DOCTYPE html>
<html>
<head>
<title>AI 비서 - 로그인</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: Arial, sans-serif;
max-width: 400px;
margin: 0 auto;
padding: 20px;
}
.login-form {
border: 1px solid #ccc;
padding: 20px;
border-radius: 5px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
}
input[type="text"], input[type="password"] {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
button {
padding: 10px 15px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.error {
color: red;
margin-bottom: 15px;
}
</style>
</head>
<body>
<h1>AI 비서 로그인</h1>
<div class="login-form">
{% if error %}
<div class="error">{{ error }}</div>
{% endif %}
<form method="post" action="/login">
<div class="form-group">
<label for="username">사용자 이름:</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="password">비밀번호:</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit">로그인</button>
</form>
</div>
</body>
</html>
11단계: 서비스 유지 및 관리
윈도우에서 자동 시작 설정
시작 폴더에 바로가기 파일 추가하기:
- Windows 탐색기에서
Win+R
을 눌러 실행 대화상자를 엽니다. shell:startup
을 입력하고 확인을 클릭합니다.- 시작 폴더가 열리면, 여기에 Python 스크립트를 실행하는 배치 파일의 바로가기를 만듭니다.
- Windows 탐색기에서
배치 파일 생성:
- 메모장을 열고 다음 내용을 입력합니다:
@echo off cd /d C:\path\to\your\project start "" "C:\Program Files\LM Studio\LM Studio.exe" timeout /t 10 python app.py
- 이 파일을
start_ai_assistant.bat
로 저장합니다. - 이 배치 파일의 바로가기를 시작 폴더에 추가합니다.
- 메모장을 열고 다음 내용을 입력합니다:
서비스로 등록하기 (더 안정적인 방법)
Windows에서는 NSSM(Non-Sucking Service Manager)을 사용하여 Python 스크립트를 서비스로 등록할 수 있습니다:
- NSSM을 다운로드하고 설치합니다(https://nssm.cc/download)
- 관리자 권한으로 명령 프롬프트를 열고 다음 명령어를 실행합니다:
nssm install AI_Assistant "C:\Path\to\Python\python.exe" "C:\path\to\your\project\app.py"
- 서비스 설정 창이 열리면 추가 옵션을 구성하고 저장합니다.
- 다음 명령어로 서비스를 시작합니다:
nssm start AI_Assistant
마무리
이제 여러분만의 개인 AI 비서 시스템이 완성되었습니다! 이 시스템은 LM Studio를 사용하여 로컬에서 AI 모델을 실행하고, Flask 웹 서버를 통해 원격에서 접속할 수 있도록 해줍니다. 필요에 따라 기능을 확장하거나 사용자 인터페이스를 개선할 수 있습니다.
추가적으로 고려할 수 있는 기능:
- 음성 인식 및 음성 합성 추가
- 다양한 명령어 처리 기능(일정 관리, 날씨 정보 등)
- 모바일 앱 인터페이스 개발
- 데이터베이스 연동으로 정보 저장 및 검색 기능 강화
이 튜토리얼이 여러분만의 AI 비서 시스템을 구축하는 데 도움이 되길 바랍니다!
반응형
LIST
'AI' 카테고리의 다른 글
현재 설치된 Claude MCP 서버와 추가 MCP 및 활용 가이드 (0) | 2025.04.05 |
---|---|
코드 작업에 좋은 mcp 서버 구성 (0) | 2025.04.04 |
미드저니(Midjourney) 첨부 파일을 이용항 이미지 생성 방법 (0) | 2024.01.12 |