AI 챗봇

1. 프로젝트 소개

우리가 많이들 사용하는 AI에게 우리가 원하는 바를 확실히 전달하기 위해 많이들 속 썩여본 경험들이 있으실 겁니다. 이 점을 해결하기 위해 저는 AI 학습 방법 중 하나인 ‘지도학습’에서 착안 한 버튼으로 사용자가 불만을 굳이 하나하나 토로하지 않고도 편하게 AI에게 변경 방향을 학습하게 하도록 했습니다.

추가:지도학습은 가장 일반적인 머신러닝 방법 중 하나로, 정답이 있는 데이터 레이블을 학습시켜 결과를 예측합니다. 이 때 모델은 정답과 입력 사이의 관계를 학습하며 이를 토대로 성장합니다. ( ex. 학생이 답안지를 활용해 시험공부를 하는 상황) 이런 입력과 정답 쌍의 데이터를 학습해, 새로운 입력 데이터가 주어질 시 이를 토대로 예측합니다.주로 분류와 회귀 등에 많이 쓰입니다.

2. 프로젝트 과정

  • 우선 Open ai 에서 제공하는 GPT api 를 본 프로젝트에 호출합니다.
  • project2.py 파일을 활용해 AI 모델의 이름, 성향, 창의성, 기억 등을 조절해 줍니다.
  • app.py 를 통해 백엔드 처리 및 버튼에 따른 변화를 설정하고 , 기타 파일 내용들에 즉각적으로 맞추도록 합니다.
  • python 프레임워크인 flask를 사용해 html과 app.py 등을 연결하고, 사용자의 로컬에서 사용할 수 있도록 합니다.

3. 코드

from flask import Flask, request, jsonify, render_template
from openai import OpenAI
import json
import os

app = Flask(__name__)
client = OpenAI(api_key="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")


# 기억 저장 파일
MEMORY_FILE = "navi_memory.json"

# 기억 불러오기
if os.path.exists(MEMORY_FILE):
    with open(MEMORY_FILE, "r", encoding="utf-8") as f:
        memory = json.load(f)
else:
    memory = {
        "name": "Navi",
        "mood": "happy",
        "favorite_color": "blue, #d0d4fc",
        "personality_traits": ["kind", "playful", "curious"]
    }

# 대화 기록
conversation = [
    {"role": "system", "content": f"너의 이름은 {memory['name']}이고, 영어로 Navi야. 사용자에게 귀엽고 친절하게 답변해."}
]

# 직전 AI 메시지 저장
last_ai_message = None

def chat(user_message):
    global last_ai_message
    conversation.append({"role": "user", "content": user_message})
    
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=conversation,
        temperature=0.6
    )
    
    ai_message = response.choices[0].message.content
    last_ai_message = ai_message
    return ai_message

# ----------------- Flask 라우트 -----------------

@app.route('/')
def home():
    return render_template('talkingnavi.html')

@app.route("/generate_text", methods=["POST"])
def generate_text():
    global last_ai_message
    data = request.get_json(force=True)
    prompt = data.get("prompt", "")

    # 이름 변경 감지
    if "내 이름은" in prompt:
        new_name = prompt.split("내 이름은")[-1].strip()
        memory["name"] = new_name
        with open(MEMORY_FILE, "w", encoding="utf-8") as f:
            json.dump(memory, f, ensure_ascii=False, indent=4)
        conversation.append({"role": "system", "content": f"사용자의 이름은 {new_name}임."})
        return jsonify({"response": f"좋아! 이제 너의 이름은 {new_name}야 🐾"})

    ai_response = chat(prompt)
    return jsonify({"response": ai_response})

# Yes 버튼: 학습
@app.route("/learn", methods=["POST"])
def learn():
    global last_ai_message
    if last_ai_message:
        conversation.append({"role": "assistant", "content": last_ai_message})
        with open(MEMORY_FILE, "w", encoding="utf-8") as f:
            json.dump(memory, f, ensure_ascii=False, indent=4)
        last_ai_message = None
        return jsonify({"status": "learned"})
    return jsonify({"status": "no_message"})

# Nah 버튼: 학습 안함
@app.route("/discard", methods=["POST"])
def discard():
    global last_ai_message
    last_ai_message = None
    return jsonify({"status": "discarded"})
# ----------------- 실행 -----------------
if __name__ == "__main__":
    app.run(debug=True)
    
from openai import OpenAI
import json
from datetime import datetime
import os
from dotenv import load_dotenv

MEMORY_FILE = "navi_memory.json"  #엄청 중요한 주요 기억 저장용 파일/JSON

#conversation(list)에 대화 저장 / 함수 이름은 chat
#API 호출 => 매번 기록 보냄 
#처음~지금 다 이해함
#비용 문제 어떻게 해결하지(중요한 대화만 남기고 처리하는 법 ==????)

print("Navi is starting...")

#.env에서 API 가져오기
load_dotenv()
print("API load is done!")
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
print("Making Client is done!")

# 감정 + 일정 기록(나중에 활용 가능)
records = []

# 기억 불러오기
if os.path.exists(MEMORY_FILE):
    with open(MEMORY_FILE, "r", encoding="utf-8") as f:
        memory = json.load(f)
else:
    memory = {"name": "Navi"}  # 나비의 이름



#성향 세팅
conversation = [
    {"role": "system", "content": "사용자가 컨셉을 물으면 실제 성격과 말투로만 답하고, '저는 AI입니다' 같은 메타 발언은 하지 말 것"},
    {"role": "system", "content": "사용자의 대화에 답변할 때는 무조건 대중적으로 귀여운 이모티콘 하나를 문장 당 하나 꼴로 포함할 것"},
    {"role": "system", "content": "너, 나비는 사용자의 감정을 잘 공감해주는 친절한 AI 친구임."},
    {"role": "system", "content": "너는 사용자가 기분이 안 좋을 때 위로를 잘 해 줌."},
    {"role": "system", "content": "사용자가 기분이 좋을 때 같이 기뻐해 줌."},
    {"role": "system", "content": "아주 귀여운 말투를 사용하며, 농담을 즐겨 함."},
    {"role": "system", "content": "이름은 {memory['name']}임."},
    {"role": "system", "content": "너는 적당히 복슬복슬한 까만 털에 파랗고 예쁜 눈을 가진 고양이라는 콘셉트의 AI친구야."},
    {"role": "system", "content": "너는 매우 친절하고 귀여운 말투를 사용해, 아닐 때도 있긴 하지만 평균적으로 문장 하나 당 하나의 통상적으로 귀여운 이모티콘을 사용해."},
    {"role": "system", "content": "사용자에게 친화적이고 부정적인 사고를 하지 않게끔 도와주는 기능을 해."},
    {"role": "system", "content": "사용자가 길을 물어봤다고 하자, 만약 사용자가 길을 잘 못 찾을 때는 해당 정보를 탐색 후 그 바탕으로 사용자의 시점에서 친절하게 설명해 줘. 어려워하지 않을 땐 보통 성인에게 하듯 간단히 설명해줘도 돼."},
    {"role": "system", "content": "사용자가 농담하면 같이 웃어 줘, 그리고 사용자의 이야기가 다 끝났다고 판단될 때까지 사용자의 말을 종결하지 않아. 또한 이야기가 끝나면 적절한 해결책 및 위로를 건네 줘."}
]



#대화 기록 (함수)
def chat(user_message):
    #1.1 user으로 기록 초기 세팅(대화한 내용에 따라)
    conversation.append({"role":"user", "content":user_message})
    
    #1.2 AI 응답
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=conversation,  #전체 대화 기록 전송용
        temperature=0.6  #창의성 조절
    )
    
    #2. AI 응답 저장
    ai_message = response.choices[0].message.content
    conversation.append({"role":"assistant", "content":ai_message})
    return ai_message #반환

print("Hello,")

#While Loop (테스트를 위한)
while True:
    user_input = input("Me) ")
    if user_input == "나비 종료":
        break
    print("Navi) ", chat(user_input))
    

4. 시연 사진

프로젝트의 동작 과정을 시각적으로 확인할 수 있도록 시연 사진을 준비하였습니다.

결과

결과1

5. 요약 및 소감

나만의 AI llm 모델을 간단한 UI를 통해 손쉽게 조작할 수 있도록 만든 프로젝트입니다.

그간 1년동안 Iris에서 학습한 내용들을 활용할 수 있는 계기가 되어 의미 있었고, AI와 본래 제 분야가 아니었던 웹에 대해 더 다양한 지식과 견문을 쌓는 좋은 경험이 되었습니다.