[GPTs]나만의 API서버로 독창적인 GPT Action 만들기

Seongkeun·2024년 5월 4일
1

GPT

목록 보기
2/2
post-thumbnail

이번 포스팅을 위해 잠깐 위의 포스팅을 보고 오는 것을 권장한다.

이번 포스팅은 Cloudtype 에 나만의 API서버를 구축해서 GPTs 를 만드는 방법을 알아보고자한다.

위 이미지를 클릭하면 실제 제가 만든 서비스를 테스트해볼 수 있습니다.

논문 리뷰가 필요한 경우가 많아서, 유튜브 비디오를 요약하는 GPTs 를 만들었다.

혹시나 GPT 가 요점을 잘 못 잡을 수도 있기에 전체 스크립트가 들어있는 url 도 따로 제공 하게끔 만들었다.

아래는 "EBS 다큐프라임 [돈의 얼굴 1부 - 돈을 믿습니까?]" 유튜브 영상을 부탁한 예시이다.

시작하기 전에..

사용환경

언어 : Python 3.11
프레임워크 : FastAPI
플랫폼 : CloudType [ 서버제공형태 : Serverless ]
서버배포형태 : Dockerfile

필수 체크리스트

  1. chatGPT 유료계정이 있는가?
  2. github 계정은 있는가?
  3. cloudtype 계정은 있는가?

위 세가지 사항은 필수이니 하나라도 빠지면 안 된다.

필수까지라고 하기는 뭐 하지만 서버에 대한 기본 지식도 필요하다.

또한,이번 글에서 CloudType 서버 만드는 방법은 생략된다.

CloudType 에서 내 서버 만드는 방법은 아래 글을 참고하자

[무료서버] CloudType 에 Dockerfile 로 FastAPI 구동

코드

%% 참고 %%
아래 코드는 제가 사용한 코드의 예시일 뿐입니다.
main.py 라도 본인의 아이디어로 구성하는 것을 추천합니다.

디렉토리구조

.
├── Dockerfile
├── main.py
└── requirements.txt

Dockerfile

코드 보기/숨기기
FROM python:3.11-slim-buster

ARG UID=1000
ARG GID=1000

# 그룹 및 사용자 생성
RUN groupadd -g "${GID}" appgroup && \
    useradd --create-home --no-log-init -u "${UID}" -g "${GID}" appuser

# 작업 디렉토리 설정
WORKDIR /app

# pip 업그레이드 및 패키지 설치
RUN apt-get update && \
    apt-get install -y vim && \
    pip install --upgrade pip

# requirements.txt 파일 복사 및 패키지 설치
COPY --chown=appuser:appgroup requirements.txt .
RUN pip install -r requirements.txt

# 사용자 변경
USER appuser:appgroup
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# 애플리케이션 파일 복사
COPY --chown=appuser:appgroup . .

# 포트 노출
EXPOSE 8080

# FastAPI 애플리케이션 실행
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]

requirements.txt

코드 보기/숨기기
annotated-types==0.6.0; python_version >= '3.8'
anyio==4.3.0; python_version >= '3.8'
click==8.1.7; python_version >= '3.7'
fastapi==0.110.2; python_version >= '3.8'
h11==0.14.0; python_version >= '3.7'
httptools==0.6.1
idna==3.7; python_version >= '3.5'
pydantic==2.7.1; python_version >= '3.8'
pydantic-core==2.18.2; python_version >= '3.8'
python-dotenv==1.0.1
pyyaml==6.0.1
sniffio==1.3.1; python_version >= '3.7'
starlette==0.37.2; python_version >= '3.8'
typing-extensions==4.11.0; python_version >= '3.8'
uvicorn[standard]==0.29.0; python_version >= '3.8'
uvloop==0.19.0
watchfiles==0.21.0
websockets==12.0
youtube-transcript-api>=0.6.2

main.py

코드 보기/숨기기
from fastapi import FastAPI, HTTPException, Query
from youtube_transcript_api import YouTubeTranscriptApi
import urllib.parse

app = FastAPI()

def get_video_id(encoded_path: str) -> str:
    """유튜브 경로에서 youtube ID 추출"""
    decoded_path = urllib.parse.unquote(encoded_path)  # URL 디코딩
    if "youtu.be" in decoded_path:
        video_id = decoded_path.split("youtu.be/")[1].split("?")[0]
    elif "watch" in decoded_path:
        video_id = decoded_path.split("v=")[-1].split("&")[0]
    else:
        raise HTTPException(status_code=400, detail="유효하지 않은 유튜브 경로 형식입니다.")
    return video_id

@app.get("/transcripts/")
def get_transcripts(
    youtube_path: str = Query(..., description="유튜브 비디오 경로, URL 인코딩 필요")
):
    """youtube id 를 받고 'script' key 로 반환"""
    video_id = get_video_id(youtube_path)
    try:
        transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
        transcripts = []
        for transcript in transcript_list:
            language_code = transcript.language_code
            transcript_text = YouTubeTranscriptApi.get_transcript(video_id, languages=[language_code])
            # 여러개의 String 배열을 단일 String 배열로
            combined_transcript = ' '.join(item['text'] for item in transcript_text)
            transcripts.append(combined_transcript)
        return {"script": transcripts}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"자막을 가져오는 중 오류 발생: {e}")

GPTs 들어가기

첫번째 화면

Explore GPTs -> Create

두번째 화면

Create | Configure 에서 Configure -> Create new action

참고로 Create | Configure 의 Create 를 눌러서 스키마를 구성하라는 글이나 유튜브들이 많은데,
GPT 가 갑자기 바보가 되면서 뺑뺑이 돌리는 경우가 많다.
그러면 아직 시작도 안 했는데 usage 를 다 사용해버려서 3시간을 기다려야한다.
그렇기에 스키마는 그냥 알아서 구성하는게 좋은 것 같다.
지구 온난화를 위해서라도 gpt 사용을 최소한 하는 것도 좋지 않겠는가???

우회하는 방법이 있겠지만, Name 에 특정 도메인명이 들어가면 마지막에 publish가 되지 않는다. ( 나만 보기는 제외 )

저 칸에 YouTube 를 적고 싶었으나, 우회 방법을 몰라서 아래와 같이 VIDEO 로 적었다

Capabilities 는 필요한 것이 있으면 체크하면 된다.

하지만 난 다 필요없으니 다 해제했다.

위 섹션들에 대한 설명이 필요한가???

[GPTs] GPT action 전체 개념 쉽게 이해하기 를 보고 오라.

알아서 적기위해 필요한 개념들을 설명해준다. ( 아래 Actions 에 대한 설명도 포함한다 )

Actions

그러니까 위의 예시에 색깔을 매치해서 url 을 표기하면 아래와 같다.

https://weather.example.com/location?location=Seoul


operationId 에 대한 설명이 필요한가??? 그렇다면 아직 아래 포스팅을 안 보고 온 것이다.

[GPTs] GPT action 전체 개념 쉽게 이해하기 를 보고 오라.

Privacy policy

위 API 사용정책은 따로 내가 사용하고 있는 외부 API 사용하고 있는 것이 아니면 그냥 아래 openAPI 사용 정책 넣으면 된다.

아래 url 복사해서 넣으면 됨

https://openai.com/policies/jun-2023-privacy-policy

나만의 GPT actions schema 구성

위와 같이 변경하면 된다.

필자와 같이 클라우드타입을 사용하고 있다면,
paths 밑 endpoint 적는 곳에 /endpoint 후에 "/" 를 반드시 기입해야한다.

즉, /endpoint/ 와 같이 기입해야한다는 말이다.

저 것 때문에 몇 시간 동안 헤맨건 안 비밀

그게 아니면 url 의 끝에 "/" 을 붙이고 paths 에는 "transcripts/" 를 적으면 된다.

뭐 나머지 description 부분들과 title 은 알아서 원하는 대로 적으면 된다.

title 은 대충 Youtube Transcript 정도로하면 되지 않을까? 원하는게 있으면 원하는대로..

다시한번 말하지만 privacy policy 섹션의 url은 반드시 적어야 한다

위 스키마에 해당하는 Key ( required, schema, components 등 등 ) 가 무엇을 의미하는지 궁금하다 싶으면 어디를 참고한다???

[GPTs] GPT action 전체 개념 쉽게 이해하기

마무리

다시 Create | Configure 페이지로 돌아온 후,

수정하거나 채워주고 싶은 부분이 있다면 Create 에서 GPT 와 상호작용으로 마무리해도 좋다.

예를들어 "내 설정에 어울리는 프로필 이미지를 생성" 하면 알아서 생성하고 적용한다.

이와 같은 마무리 작업까지 다 했다면 우측 상단의 초록색 Create를 눌러라.

그렇다면 아래와 같은 페이지가 팝업될 것이다.

Publish to GPT Store 로 하고, 카테고리는 본인이 생각하기에 알맞은 카테고리로 적용하면된다.

필자는 Education 으로 했다.

Share 버튼 ㄱㄱ

짜잔 Publish 되었다.

EXPLOSIVE VIDEO SUMMARIZER 사용해보기

profile
지혜는 지식에서 비롯된다

0개의 댓글