[알토르] #19 챗봇 - 사용자별 chat thread 생성

Hyungjun·2024년 7월 19일
0

알토르

목록 보기
21/23

Mission

포트폴리오 사이트 디자인 업데이트

  • 스레드 생성
    - 브라우저 저장장소가 무엇이 있는지 정리
    - localstorage와 cookie 조사
    • http get method, query string 조사
    • http post method, form data 조사
    • content-type 조사

배경지식

#1 쿠키

1) 쿠키의 역사
HTTP는 비연결성 무상태성의 성질을 갖고있음. 그래서 클라이언트와 서버가 한번 연결을 맺은 뒤에 요청과 응답이 끝나면 연결을 끊고 상태를 유지하지도 않는다. 그래서 사이트를 방문했었는지 서버는 모른다.
이를 알려고 쿠키가 고안되었다.

2) 쿠키의 특징

  • 쿠키는 서버에 저장되고 서버에서 사용됨.
  • HTTP 요청시 headers에 실려서 전송된다. (같은 도메인에서 생성된 쿠키만)
  • 만료기간 설정가능 (expires, max-age)
  • 만료기간 있으면 영구쿠키 : 만료기간이 끝나면 삭제, 브라우저 종료와 관계없음
  • 만료기간 없으면 세션쿠키 : 브라우저 종료시 삭제
  • 퍼스트파티 쿠키 : 같은 도메인, 서브 도메인에서 생성된 쿠키
  • 서드파티 쿠키 : 다른 도메인에서 생성된 쿠키, 이미지, 폰트, 스크립트가 존재해 다른 도메인으로 요청해야할때 생성됨, 광고에 사용

3) 문제점
CSRF, XSS,
부족한 저장용량 4kB
HTTP 요청시 모든 쿠키 전송 - 불필요한 트래픽 증가

#2 웹 스토리지

1) 쿠키의 문제점 보안

  • 5MB의 저장용량
  • HTTP 요청시 headers에 실리지 않음
  • 문자열만 저장가능 : 직렬화를 통해 객체도 저장 가능

2) 종류

  • 로컬 스토리지 : 도메인별, 브라우저별로 다름 / 만료기간이 없음
  • 세션 스토리지 : 탭 별로까지 다름 / 탭 종료시 삭제됨

3) 문제점
XSS에 취약
브라우저와 탭 간의 공유 불가
만료기간 설정 불가
동기적으로 실행

#3 실습준비

현재 챗봇 assistant에 api를 요청하면 이미 만들어진 스레드로 로그인해서 질문을 입력하고 있다. 하지만 이렇게 놔두면 사용자마다 다른 맥락을 제공해줄 수 없어 사용자 경험이 떨어질 수 있다. 최신의 chat-gpt는 맥락까지 생각하면서 답변해주기 때문이다. 쿠키와 웹스토리지를 조사하니, 스레드 정보는 사용자가 다시 브라우저를 켰을 때 그대로 있어야 하기 때문에 local storage에 저장하면 되겠구나 결론지을 수 있었다.

#4 http request, get method와 post method

클라이언트에서 서버로 데이터를 넘겨주는 방식은 get방식인지 post 방식인지에 따라서 구별된다.
get request는 action url에 query string parameter로 전달된다.

post request는 form data는 http request의 message body에 들어가서 전달된다.

파일을 업로드하기 위해서는 form을 통해서 파일을 등록한다. 파일들 또한 문자로 이루어져있기 때문에 데이터 타입을 같이 전달해줘야 서버에서 읽을 수 있다. 그림에서 http header에 content-type과 MIME 타입을 기술해줄수있다.

content-type
Http 통신에서 전송되는 데이터의 타입을 명시하기 위해 header에 실리는 정보다. 즉, api 요청 시 request에 실어 보내는 데이터(body)의 타입 정보다.

실습

#1 현재 로직

  1. request의 data 안에 question 값을 user_input으로 받아옴
  2. assistant_id와 thread_id를 .env에서 받아옴
  3. thread에 들어가 user의 질문을 user_input을 기반으로 만듬
  4. thread_id와 assistant_id로 run을 만듬
  5. run_id와 thread_id로 retrieve 구동
  6. 특정 thread에 만들어진 message 안에 data, content로 들어가 답변 값을 ai_response로 받아옴
  7. response : ai_response로 JSON 으로 만들어서 응답

수정이 필요한 곳
thread_id를 .env에 받아오면 안되고
1. Front에서 local storage에 thread_id가 있는지 확인
2. 없으면 첫 접속이니 새로운 스레드를 생성해주고 그것을 사용

#2 목표 로직

  1. openai assistant를 import해서 새로운 thread_id를 만들어야 함. -> X
    -> 이미 api 서버가 있기 때문에 post 요청을 한번 더하기만 하면 된다.
  2. /createNewThread를 만들고 front에서 post 요청을 하면 새로운 thread_id를 생성하도록 한다.
  3. thread_id를 fetch를 이용해 post 요청을 할때, 질문과 함께 request body에 담아 전달
  4. thread_id를 받아서 assistant 안에 각각의 thread에 들어가 질문을 해 답변을 만듦

#3 code

  1. next.js front-end code
useEffect(() => {
    // 컴포넌트가 마운트될 때 로컬 스토리지에서 thread_id 확인
    let storedThreadId = localStorage.getItem("thread_id");

    if (storedThreadId === null || storedThreadId == "undefined") {
      // thread_id가 없으면 새로 생성
      createNewThread();
    } else {
      setThreadId(storedThreadId);
    }
  }, []);

  const createNewThread = async () => {
    const res = await fetch("https://api.junresume.com/createNewThread", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({}),
    });
    const data = await res.json();
    const newThreadId = data.thread_id;

    // 새로 생성된 thread_id를 로컬 스토리지에 저장
    localStorage.setItem("thread_id", newThreadId);
    setThreadId(newThreadId);
  };
  1. flask back-end Code
@app.route('/createNewThread', methods=['POST'])
def createNewThread():
	try: // 새로운 thread_id를 생성해서 응답
		createdThread = client.beta.threads.create()
		createdThread_id = createdThread.id

		return jsonify({"thread_id" : createdThread_id})
	
	except Exception as e:
		return jsonify({"error" : str(e)})

#4 결과 및 배포

  1. localhost에서 먼저 test
    브라우저에 local storage를 확인 -> 개발자도구 - application - localstorage

  2. 배포를 한 후 local storage의 thread_id 확인

출처
https://im-developer.tistory.com/166
https://www.youtube.com/watch?v=-4ZsGy1LOiE
https://velog.io/@onady/HTTP-Content-Type
https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-FormData-%EC%A0%95%EB%A6%AC-fetch-api
https://lena-chamna.netlify.app/post/http_multipart_form-data/

profile
Cloud Security Expert

0개의 댓글