본문 바로가기
AI활용, 엑셀, VBA, 파이썬, 입코딩

[파이썬] 그록(Groq) 무료 API를 활용한 챗봇 프로그램 만들기

by 엑셀런트대디 2025. 3. 25.
반응형

예전에 OpenAI API를 활용해서 엑셀 안에서 GPT 함수를 직접 사용하는 방법에 대해 글을 올린 적이 있다.
하지만 OpenAI API는 $5 이상 결제해야 사용 가능하고, API Key 발급 과정도 번거로운 편이다. -_-
 
그러던 중 인터넷을 검색하다가,
Groq에서 무료로 사용할 수 있는 API가 있다는 정보를 우연히 봤다.
단순 호기심에 간단하게 만들어봤는데, 성능이 꽤 괜찮은 것 같다.
 
혹시 나처럼 자동화나 GPT에 관심 있는 분들께 도움이 될까 싶어,
이렇게 짧게나마 공유해 본다.
 
아이디어도 이것저것 시도 해본 사람이
더 많은 아이디어가 나온다고 생각한다.^^
 
코드를 아래에 첨부하였으니 눈으로만 보지 말고,
조금(?) 시간을 내서 API에 대한감을 익힐 겸 ㅎ GPT와 함께 고민해 보길 바란다.😁

GPT처럼 지침창을 만들었고 왼쪽창에는 대화창을 만들고 오른쪽에는 대화한내용을 기록하는 창을 만들었다.^^

 


✅ Groq API란?

  • GroqCloud에서 무료로 API Key 발급 가능
  • Meta의 LLaMA3 기반 LLM 모델 사용
  • OpenAI API와 유사한 방식으로 사용 가능

 

💻 Groq API Key 발급 방법

GroqCloud - Build Fast

Build Fast with GroqCloud

console.groq.com

 
위 사이트에서 회원가입하고 Create API Key 클릭  API Key 발급

이름을 만들고 Submit 버튼을 누르면

이렇게 Api키가 발급된다.
 
이걸 복사해서 코드에 Api를 넣어주면
LLM서비스(챗봇)를 무료로 사용할 수 있다.^^
 
이것도 마찬가지로 모델명과, 토큰값등을 설정해 보면서 여러 가지 테스트?를 해보길 바란다.


프로그램 코드에 대한 자세한 설명은 GPT가😊

 

💬 PyQt5 기반 Groq 챗봇 데스크톱 앱 기능 정리

이 프로그램은 PyQt5 GUI 프레임워크를 사용하여 제작된 데스크톱 애플리케이션으로, Groq API (LLM)와 연동해 챗봇 대화를 할 수 있는 도구입니다.
주요 기능은 다음과 같습니다:

구분기능 설명

 

🧠 LLM 연동 groq 모듈을 통해 Groq의 LLaMA 3 모델을 사용해 채팅 응답 생성
🖥️ GUI 구성 PyQt5 기반의 세 가지 주요 영역 구성:
① 지침 입력란
② 실시간 채팅창
③ 대화 기록 패널
📝 지침 기능 대화 전 시스템 역할(system)로 지침 입력 가능 (예: "한글로 대답해")
🧾 대화 저장 모든 대화 내용은 JSON 파일(chat_history.json)로 자동 저장 및 불러오기 지원
🗂 기록 확인 대화 기록 영역을 통해 이전 대화 내용을 사이드 패널에 확인 가능
기록 삭제 '기록 지우기' 버튼을 눌러 저장된 대화 내용 완전 삭제 가능
⌨️ 단축키 지원 Ctrl + Enter로 메시지 전송 가능 (전송 버튼과 동일 기능)
🔁 자동 스크롤 대화가 추가될 때마다 스크롤이 자동으로 가장 아래로 이동
📁 플러그인 경로 설정 Windows 환경에서 PyQt5의 QT_QPA_PLATFORM_PLUGIN_PATH 설정 자동화 처리

💡 특징 및 장점 요약

  • 모든 UI 요소에 '맑은 고딕' 폰트 적용 → 깔끔하고 통일된 디자인
  • 대화 구조가 명확하게 분리되어 있음 → 사용자, 시스템, AI 메시지를 구분 가능
  • 사용자 지침을 시스템 메시지로 삽입 → 대화 맥락에 맞는 AI 응답 유도
  • 파일로 기록 관리 → 지속적인 대화 이력 관리가 가능
  • 직관적인 구성과 확장성 → 기능 추가(예: 모델 변경, 다크모드 등)에 유리

 

코드보기

import sys
import groq
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                            QHBoxLayout, QTextEdit, QPushButton, QLabel)
from PyQt5.QtCore import Qt, QCoreApplication
from PyQt5.QtGui import QFont, QIcon
from typing import List, Dict
import os
import PyQt5

class GroqChatApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Groq 챗봇")
        self.setMinimumSize(800, 600)
        
        # Groq API 설정
        self.groq_client = groq.Client(api_key="무료로 발급한 API키 입력하세요^^")
        self.conversation_history = []
        
        # 대화 내용 파일 경로
        self.chat_history_file = "chat_history.json"
        
        # UI 설정을 먼저 실행
        self.init_ui()
        
        # UI 초기화 후에 대화 내용 불러오기
        self.load_chat_history()
        
    def init_ui(self):
        # 메인 위젯과 레이아웃 설정
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        layout = QVBoxLayout(main_widget)
        
        # 지침 입력 영역
        instruction_container = QWidget()
        instruction_layout = QHBoxLayout(instruction_container)
        
        instruction_label = QLabel("지침:")
        instruction_layout.addWidget(instruction_label)
        
        self.instruction_input = QTextEdit()
        self.instruction_input.setFixedHeight(40)  # 높이를 40으로 조정 (약 2줄)
        self.instruction_input.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)  # 필요시 스크롤바 표시
        self.instruction_input.setFont(QFont("맑은 고딕", 10))
        self.instruction_input.setPlaceholderText("예: 한글로 답변해 주세요")
        instruction_layout.addWidget(self.instruction_input)
        
        layout.addWidget(instruction_container)
        
        # 채팅 및 기록 컨테이너
        chat_container = QWidget()
        chat_layout = QHBoxLayout(chat_container)
        
        # 채팅 표시 영역
        self.chat_display = QTextEdit()
        self.chat_display.setReadOnly(True)
        self.chat_display.setFont(QFont("맑은 고딕", 10))
        chat_layout.addWidget(self.chat_display)
        
        # 대화 기록 영역 컨테이너 (제목과 버튼을 포함)
        history_container = QWidget()
        history_layout = QVBoxLayout(history_container)
        
        # 대화 기록 제목과 버튼을 위한 수평 레이아웃
        history_header = QWidget()
        header_layout = QHBoxLayout(history_header)
        header_layout.setContentsMargins(0, 0, 0, 0)
        
        # 대화 기록 제목
        history_title = QLabel("대화 기록")
        header_layout.addWidget(history_title)
        
        # 기록 지우기 버튼
        clear_history_button = QPushButton("기록 지우기")
        clear_history_button.clicked.connect(self.clear_chat_history)
        header_layout.addWidget(clear_history_button)
        
        history_layout.addWidget(history_header)
        
        # 대화 기록 표시 영역
        self.chat_history_display = QTextEdit()
        self.chat_history_display.setReadOnly(True)
        self.chat_history_display.setFont(QFont("맑은 고딕", 10))
        self.chat_history_display.setPlaceholderText("대화 기록")
        history_layout.addWidget(self.chat_history_display)
        
        chat_layout.addWidget(history_container)
        history_container.setFixedWidth(300)  # 고정 너비 설정
        
        layout.addWidget(chat_container)
        layout.setStretch(1, 1)
        
        # 입력 영역 컨테이너
        input_container = QWidget()
        input_layout = QHBoxLayout(input_container)
        
        # 메시지 입력창
        self.message_input = QTextEdit()
        self.message_input.setFixedHeight(40)  # 높이를 40으로 조정 (약 2줄)
        self.message_input.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)  # 필요시 스크롤바 표시
        self.message_input.setFont(QFont("맑은 고딕", 10))
        input_layout.addWidget(self.message_input)
        
        # 전송 버튼
        send_button = QPushButton("전송")
        send_button.setFixedSize(40, 40)  # 입력창 높이와 동일하게 설정
        send_button.clicked.connect(self.send_message)
        input_layout.addWidget(send_button)
        
        layout.addWidget(input_container)
        
        # 상태 표시줄
        self.statusBar().showMessage("준비됨")
        
        # 단축키 설정
        self.message_input.installEventFilter(self)
    
    def eventFilter(self, source, event):
        if (event.type() == event.KeyPress and
            source is self.message_input and
            event.key() == Qt.Key_Return and
            event.modifiers() == Qt.ControlModifier):
            self.send_message()
            return True
        return super().eventFilter(source, event)
    
    def load_chat_history(self):
        """저장된 대화 내용을 불러옵니다."""
        import json
        try:
            with open(self.chat_history_file, 'r', encoding='utf-8') as f:
                self.conversation_history = json.load(f)
                # 대화 기록 표시
                for msg in self.conversation_history:
                    if msg["role"] == "user":
                        self.chat_history_display.append(f"Q: {msg['content']}")
                    elif msg["role"] == "assistant":
                        self.chat_history_display.append(f"A: {msg['content']}\n")
                        self.chat_history_display.append("■" * 42)
        except FileNotFoundError:
            pass

    def save_chat_history(self):
        """현재 대화 내용을 파일로 저장합니다."""
        import json
        with open(self.chat_history_file, 'w', encoding='utf-8') as f:
            json.dump(self.conversation_history, f, ensure_ascii=False, indent=2)

    def send_message(self):
        user_message = self.message_input.toPlainText().strip()
        if not user_message:
            return
        
        # 지침 가져오기
        instruction = self.instruction_input.toPlainText().strip()
        
        # 지침이 있는 경우 대화 시작 시 추가
        if instruction:
            # 기존 시스템 메시지 제거
            self.conversation_history = [msg for msg in self.conversation_history if msg["role"] != "system"]
            # 새로운 시스템 메시지 추가
            self.conversation_history.insert(0, {
                "role": "system",
                "content": f"{instruction}\nYou must follow these instructions strictly and consistently throughout the entire conversation."
            })
        
        # 채팅 표시 영역 초기화
        self.chat_display.clear()
        
        # 사용자 메시지 표시
        self.chat_display.append(f"사용자: {user_message}")
        self.message_input.clear()
        
        # 대화 기록에 추가
        self.conversation_history.append({"role": "user", "content": user_message})
        
        # 상태 업데이트
        self.statusBar().showMessage("응답을 생성하는 중...")
        
        try:
            # Groq API 호출
            response = self.groq_client.chat.completions.create(
                model="llama-3.3-70b-versatile",
                messages=self.conversation_history,
                temperature=0.7,
                max_tokens=4096
            )
            
            # AI 응답 처리
            ai_message = response.choices[0].message.content
            self.conversation_history.append({"role": "assistant", "content": ai_message})
            
            # AI 응답 표시
            self.chat_display.append(f"AI: {ai_message}\n")
            
            # 대화 기록에 레이블 형태로 추가
            self.chat_history_display.append("■" * 42)  # 구분선 추가
            self.chat_history_display.append(f"Q: {user_message}")
            self.chat_history_display.append(f"A: {ai_message}\n")
            
            self.save_chat_history()  # 대화 내용 저장
        except Exception as e:
            self.chat_display.append(f"오류 발생: {str(e)}\n")
        
        # 상태 업데이트
        self.statusBar().showMessage("준비됨")
        
        # 스크롤을 가장 아래로
        self.chat_display.verticalScrollBar().setValue(
            self.chat_display.verticalScrollBar().maximum()
        )

    def clear_chat_history(self):
        """대화 기록을 지웁니다."""
        import json
        import os
        
        # 대화 기록 초기화
        self.conversation_history = []
        self.chat_history_display.clear()
        
        # 파일이 존재하면 삭제
        if os.path.exists(self.chat_history_file):
            os.remove(self.chat_history_file)
            
        # 상태 업데이트
        self.statusBar().showMessage("대화 기록이 삭제되었습니다.")

def main():
    # Qt 플러그인 경로 설정
    qt_plugin_paths = [
        os.path.join(os.path.dirname(PyQt5.__file__), 'Qt5', 'plugins'),
        os.path.join(os.path.dirname(PyQt5.__file__), 'Qt', 'plugins'),
        os.path.join(sys.prefix, 'Lib', 'site-packages', 'PyQt5', 'Qt5', 'plugins'),
    ]
    
    # 유효한 플러그인 경로 찾기
    for path in qt_plugin_paths:
        if os.path.exists(path):
            os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = path
            break
    
    app = QApplication(sys.argv)
    window = GroqChatApp()
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

 
끝.
 

반응형