일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- ML
- 영상처리
- Image Processing
- MDP
- 파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습
- DART
- fastapi를 사용한 파이썬 웹 개발
- Flutter
- Got
- rao
- FastAPI
- Stream
- ARM
- system hacking
- Algorithm
- llm을 활용 단어장 앱 개발일지
- 백준
- PCA
- bloc
- Kaggle
- pytorch
- Computer Architecture
- BFS
- BOF
- Widget
- Dreamhack
- study book
- C++
- MATLAB
- BAEKJOON
- Today
- Total
Bull
[Dev] LLM을 활용 단어장 앱 개발일지 003: Fast API로 Langchain 설정하기 본문
LLM을 통해서 채팅을 하는 것이 주목적이기 때문에 간단하게 Fast API로 gpt api 요청을 하는 서버를 구축해보겠다. OpenAI의 라이브러리만 써도 gpt 사용하는데 무방하지만 나중에 여러 모델을 쓰게 된다면 Langchain을 이용하는 것이 좋다. 그럼 코드만 간단하게 작성해보겠다.
디렉토리 구조
현업에서는 어떻게 하는 지 모르지만 나는 그냥 플러터 프로젝트에 server 디렉토리를 만들어서 그곳에서 사용하겠다.
server
├── .env
└── app
├── main.py
└── service.py
# requirements.txt
fastapi
uvicorn
langchain
openai
python-dotenv
Fast API
env에 gpt api key를 둔다.
OPENAI_API_KEY={key value}
괄호 없애고 그냥 넣으면 된다. 이제 service.py
에서 이 오픈키를 dotenv
패키지를 통해서 정의해줄 것이다.
# service.py
from langchain_openai import ChatOpenAI
import os
from dotenv import load_dotenv
load_dotenv()
class LLMService:
def __init__(self):
self.llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.1,
openai_api_key=os.getenv("OPENAI_API_KEY")
)
def ask_question(self, question: str) -> str:
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": question},
]
response = self.llm.invoke(messages)
return response.content
load_dotenv()
를 통해서 key를 로드한다.
LLMService
클래스의 프로퍼티 llm
에 ChatOpenAI
클래스를 등록해준다. model 설정을 원하는 모델로 지정해주고 temperature는 창의성 정도이다. openai_api_key로 로드된 키 값을 os.getenv
메소드를 통해서 저장한다.
ask_question
메소드는 질문에 대한 응답을 문자열 형식으로 반환해준다. 여기서 messages 리스트를 보면 role과 content 키에 페르소나가 들어갔는데 이것은 GPT 공식 문서에서 지정해주는 기본적인 context setting
방식이다.
이제 invoke
를 통해 질문을 던지면 그 대답을 response에 저장하고 str 형으로 반환한다.
# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from app.services import LLMService
app = FastAPI()
# CORS 설정
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 모든 도메인에서의 접근을 허용
allow_credentials=True,
allow_methods=["*"], # 모든 HTTP 메소드를 허용
allow_headers=["*"], # 모든 HTTP 헤더를 허용
)
# LLMService 인스턴스 생성
llm_service = LLMService()
# 요청 모델
class QuestionRequest(BaseModel):
question: str
# 응답 모델
class AnswerResponse(BaseModel):
answer: str
@app.post("/ask", response_model=AnswerResponse)
async def ask_question(request: QuestionRequest):
answer = llm_service.ask_question(request.question)
return AnswerResponse(answer=answer)
app.add_middleware
메소드는 CORS 설정을 해준다. 일종의 보안 설정인데 모두 허용시켜준다. 이거 안해주면 요청할 때 막힌다.
BaseModel
은 pydantic
에서 모델을 지정할 때 편리하게 도와준다. 현재 QuestionRequest
모델의 question: str 같은 경우, 해당 클래스에 question="bla bla" 처럼 모델의 프로퍼티 취급이지만 반환될 때는
{question: "Hello World!"}
처럼 json으로 모델을 키 값 형태로 지정한다. answer도 동일한 형태이니 넘어간다.
<---- @app.post("/ask", response_model=AnswerResponse)
---->
POST 요청을 하는데 응답을 AnswerResponse
형식으로 해주겠다는 뜻이다. 즉 json 형태로 반환된다.
<---- async def ask_question(request: QuestionRequest)
---->
프로퍼티 request는 QuestionRequest
모델 형식으로 요청 받아야 한다. 실제로 request 프로퍼티를 프린트하면
question='What is the capital of South Korea?'
이라고 나온다. 즉 question은 객체의 필드 취급을 하지만 객체로 반환될 때는
{question: 'What is the capital of South Korea?'}
이 되니 주의하자. (변수 = 필드 = 프로퍼티, 여기서는 필드로 호칭을한다.)
<---- answer = llm_service.ask_question(request.question)
---->
answer는 필드, 즉 문자열 변수이다. question의 값은 문자열이니 아까 본 함수에서 질문에 대한 답변도 문자열이니 answer에 대답이 저장된다.
<---- return AnswerResponse(answer=answer)
----> AnswerResponse
클래스로 반환되니 응답은 json 형태를 띌 것이다.
서버 실행 및 동작 확인
uvicorn app.main:app --host 0.0.0.0 --port 12345
fast api 애플리케이션을 실행해주는 명령어이다. 실제 모바일에서 요청할 수 있어야하기 때문에 포트포워딩을 해주었다. 그래서 --host 0.0.0.0 을 꼭 해주어야 한다. 외부에서 들어올 수 있는 IP를 지정해주는 옵션이다. 포트는 대충 12345로 했다.
그럼 이제 URL 요청을 도와주는 Postman 앱을 통해서 직접 내 IP:12345로 요청을 해보았다.
요청은 성공적으로 되었고 응답도 성공적으로 되었다. 이제 이것을 통해서 채팅 UI를 구현할 것이다. (현재 구현된 상태지만 개발일지 쓰기가 매우 귀찮... 지만 해야지)
'일상 > 개발일지' 카테고리의 다른 글
[Dev] LLM을 활용 단어장 앱 개발일지 006: 단어장 UI 변경 (0) | 2024.08.27 |
---|---|
[Dev] LLM을 활용 단어장 앱 개발일지 005: CRUD - 단어 DB 읽어서 표시하기 (0) | 2024.08.20 |
[Dev] LLM을 활용 단어장 앱 개발일지 004: Bloc 상태 관리(대화 내용) (0) | 2024.08.18 |
[Dev] LLM을 활용 단어장 앱 개발일지 002: key 기기 보관 (0) | 2024.08.16 |
[Dev] LLM을 활용 단어장 앱 개발 일지 001: UI 구성 (0) | 2024.08.14 |