포스팅 개요
대규모 언어 모델(Large Language Model, LLM) 서비스를 개발하면서, 회사에서건 개인적으로건 매번 프롬프트를 관리하는 페이지를 구성했었는데요. 이번 포스팅은 제가 매번 사용했던 LLM 프롬프트 관리 서비스를 개발한 과정과 후기를 정리하는 포스팅입니다. 또한, 이 서비스에 대해서 궁금하신 분들을 위해 원하신다면 사용이 가능하도록 코드도 github에 공개해두었고 사용하는 방법에 대해서도 정리를 진행한 포스팅입니다. 개인적으로는 이 프롬프트 관리 서비스를 기반으로 회사에서 또는 프로젝트 성격별로 다양하게 응용하여 사용하고 있습니다. 대단한 코드나 로직은 아니어서 조금 민망하기도 하고 부끄럽기도 한 내용이지만, 저 개인적으로 사용하는 것을 넘어서 누군가에게 도움이 되시길 바라는 마음으로 글을 작성합니다.
본격적인 글 내용에 앞서, 프롬프트 관리 서비스 코드 링크 먼저 공유드립니다. 아래 github에서 확인할 수 있습니다.
GitHub - lsjsj92/prompt-playground-lab: prompt tuning, management, playground lab(w/ Python Streamlit, FastAPI)
prompt tuning, management, playground lab(w/ Python Streamlit, FastAPI) - lsjsj92/prompt-playground-lab
github.com
포스팅 본문
포스팅 개요에서 말씀드린 것처럼 본 포스팅은 제가 개인적으로 LLM의 프롬프트(Prompt) 템플릿 관리를 위해 만들어둔 서비스를 개발한 개발기를 작성합니다. 본격적인 내용에 앞서, 먼저 이 질문을 먼저 해야할 것 같습니다. "왜 만들었는가?"
왜 LLM Prompt 관리 서비스를 만들었는가?
ChatGPT나 Claude, Llama 그리고 요즘 이슈가 되고 있는 딥시크(Deepseek)와 같은 대규모 언어 모델(Large Language Model, LLM)을 활용한 서비스 및 시스템 개발이 정말 많이 이루어지고 있습니다. 아무래도 LLM을 활용하는 것이다보니 가장 중요한 것 중 하나가 프롬프트(Prompt)에 대한 관리였는데요. 이때, 제가 말씀드린 LLM 프롬프트 관리라는 것은 아래와 같은 것을 포함합니다.
- 새로운 프롬프트를 추가: 원하는 신규 프롬프트를 추가. 이때, 원하는 변수를 추가하고 이 값을 입력 받을 수 있도록 포멧을 설정함. 예를 들어, 사용자의 정보라던가, LLM에게 강조하는 중요사항 등이 있음
- 만들어둔 프롬프트를 관리: 미리 만들어둔 프롬프트를 수정하고, 삭제할 수 있는 것. 추가된 프롬프트에 대한 유지보수나 오타 등을 방지하기 위한 목적
- 프롬프트를 활용한 LLM 실행: 프롬프트를 설계할 때 만들어두었던 변수에 값을 넣고 LLM에게 제공하여 결과를 실행함. 이때, 실행한 결과의 히스토리도 저장되며, LLM의 실행 결과를 즉각 수정할 수도 있어야 함
- LLM 실행 결과에 대한 평가: 만들어둔 프롬프트와 실행 결과에 대한 평가를 할 수 있음. 나만 마음에 들면 되는 것이 아니라, 다른 사람들의 의견도 필요할 수 있기 때문에 평가 페이지를 구성
저는 개인적으로 위와 같은 프롬프트 관리가 필요하다는 생각이 들었고, 해당 관리 서비스를 개인적인 목적으로 사용하기 위해서라도 간단하게 만들어야겠다고 생각했습니다.
그럼 다시 본문으로 돌아와서, 제가 구성해본 프롬프트 관리 서비스에 대해서 메뉴 하나하나 별로 설명을 드리겠습니다.
가장 먼저, 저는 아래와 같은 개발 환경에서 이 페이지를 구성하였습니다.
개발 환경 및 사전 데이터베이스 구성
- 개발 환경: Python 3.9
- 웹 화면: Streamlit
- 백엔드: FastAPI
- DB: MySQL or MariaDB
- LLM 활용: Langchain
이때, 저는 데이터베이스로 MySQL 또는 MariaDB를 사용했다고 위에 작성했는데요. 프롬프트 관리 서비스를 사용하기 위해서는 먼저 아래와 같이 DB 구성을 해주어야 합니다.
1. MySQL 또는 MariaDB 설치
2. 사용을 원하시는 계정과 비밀번호 셋팅
- 저의 default 설정 값은 계정은 root, 비밀번호는 1234 입니다.
3. prompt_db 이름으로 데이터베이스 생성
- create database prompt_db
이렇게만 준비해두면 프롬프트 관리 페이지 실행과 개발 환경 구축 준비는 완료됩니다!
그리고 아래와 같이 실행하면 됩니다.
1. FastAPI 실행: uvicorn app.main:app --reload
2. (선택 사항) 테스트 데이터 삽입 sql 실행
- mysql -u root -p < insert_test_data.sql
- FastAPI를 먼저 실행하는 이유는, API 실행 시 테이블 등을 생성하기 때문입니다.
3. streamlit 서버 실행
- streamlit run web/main.py --server.port 8501
그럼, 이제 각 메뉴별로 기능을 설명해보겠습니다.
프롬프트 관리 시스템 정보 페이지
먼저, 정보 페이지입니다. 사실 이 페이지는 별 것 없고 프롬프트 관리 서비스에 대한 정보가 기록되어 있는 페이지입니다.
각 메뉴에 대한 설명과 개발 환경, 상세 내용과 코드 링크 등의 내용으로 구성되어 있는 페이지입니다.
프롬프트 추가 페이지
다음은 프롬프트 추가하기 페이지입니다. 이 페이지에서는 새로운 신규 LLM 프롬프트를 추가하는 페이지입니다.
이 페이지의 특징은 아래와 같습니다.
- 프롬프트 제목: 말 그대로 프롬프트 템플릿의 대한 제목입니다. 나중에 프롬프트 템플릿을 찾을 때 유용하게 사용할 수 있도록 만들어두었습니다.
- 시스템 메세지: LLM에게 프롬프트를 구성할 때 시스템 메세지(System message)를 넣는 부분에 대한 값입니다. LLM이 어떤 역할로 수행하기를 원하는지 작성하는 것이죠. 이 부분은 추후 랭체인(Langchain)과 연동할 때 Langchain의 system message의 값으로 활용됩니다.
- 프롬프트 포멧: 프롬프트를 추가할 때 활용되는 메인 내용입니다. 원하는 프롬프트 템플릿을 만드는 과정이라고 보시면 되는데요. 예를 들어서, 저는 아래와 같이 템플릿을 구성했습니다.
아래와 같은 요구사항에 따라, 업무를 수행해주세요.
1. 목표
{target}
2. 내용
{desc}
3. 조건
{condition}
이때 중괄호 { }로 묶여저 있는 부분은 추후 '프롬프트 실행하기 메뉴'에서 실제 값으로 들어가는 변수들입니다. { }로 설정한 이유는 파이썬에서 제공하는 format 함수를 활용해서 텍스트와 값을 매칭시켜 LLM에게 제공하는 prompt를 완성하기 위한 목적이기 때문입니다.
이 부분이 잘 이해가 가지 않을 수 있는데요. 이는 추후 프롬프트 실행하기 설명에서 다시 확인할 수 있으니 지금 당장 이해가 가지 않더라도 괜찮습니다.
저는 독자님들의 이해를 돕기 위해 아래와 같은 내용으로 또 하나의 프롬프트를 추가해두겠습니다.
- 프롬프트 제목: 이수진의 테스트2
- 시스템 메세지: 당신은 행복하고 아름답게 말하는 AI입니다.
- 프롬프트 포멧:
아래 내용을 확인하시고, 멋진 문구를 만들어주세요.
1. 문구의 주제
{topic}
2. 조건
{condition}
원하는 프롬프트 포멧을 작성하고 저장하면 프롬프트가 정상적으로 저장되었다는 메세지를 확인할 수 있습니다.
저는 이렇게 '이수진의 테스트'와 '이수진의 테스트2'라는 프롬프트 포멧 제목으로 2개를 넣어두었습니다.
만들어둔 프롬프트 관리 페이지
세 번째 페이지 메뉴는 프롬프트 관리 페이지입니다. 프롬프트 추가 페이지에서 저장해둔 프롬프트들을 수정 및 삭제할 수 있는 페이지입니다. 페이지에 들어가면 만들어두었던 프롬프트의 제목 리스트들이 나오게 되고, 그 제목을 누르면 시스템 메세지와 프롬프트 포멧 등의 상세 정보가 출력되게 됩니다.
위 사진은 그 과정을 보여주는데요. 제가 방금 추가했던 '이수진의 프롬프트' 2개의 리스트를 볼 수 있습니다(왼). 이 리스트 중에서 하나를 클릭하면 해당 프롬프트의 상세 정보가 출력되게 됩니다(오).
만약, 수정을 원하신다면 수정할 수 있는데요. 저는 위에서 만들어두었던 프롬프트 중 '이수진의 테스트2'의 내용을 살짝 변경했습니다. 프롬프트 포멧의 내용을 바꿔서 수정한 뒤 프롬프트 수정 버튼을 누르면 수정된 정보가 데이터베이스에 저장되게 됩니다.
삭제도 가능합니다. 맨 아래에 프롬프트 삭제 버튼을 누르면 프롬프트가 삭제가 되는데요. 단, 실제 로직을 보면 값을 delete하지는 않고 use_yn 값을 n으로 변경하도록 설정했습니다. 만약에라도 실수로 삭제한 것을 방지하는 목적도 있고 당시엔 필요없어서 삭제했는데 나중에 필요할 것 같을 때 다시 재사용할 수 있도록 하기 위해 이렇게 구성해두었습니다.
만들어둔 프롬프트를 활용해 LLM을 실행하는 페이지
다음 페이지는 만들어둔 프롬프트 템플릿을 활용해서 실제 LLM에게 메세지를 던져 결과를 받아오는 실행 페이지입니다.
페이지에 들어가면 구성해둔 프롬프트 템플릿 리스트가 보이게 됩니다. 이 중 프롬프트를 선택하면 이제 실제 값을 입력하게 되는데요.
여기서 이제 아래 사진과 같이 변수에 해당되는 값을 입력하게 됩니다. 이게 무슨 의미냐면, 위에서 프롬프트를 추가할 때 중괄호 { } 로 변수를 추가한 부분이 있었는데요. 이것에 맞는 값을 입력받도록 하는 것입니다.
단순히 글로만 보면 헷갈리실 것 같아 추가 그림과 함께 조금 더 상세하게 설명을 드리겠습니다.
예를 들어, 저는 위에서 '이수진의 테스트2'라는 제목을 가진 프롬프트를 만들 때 '행복하고 아름다운 문구를 만들라'라는 시스템 메세지와 더불어 프롬프트 포멧에 문구의 주제 {topic} 조건 {condition}을 추가했었습니다. 아래와 같이 말이죠.
- 프롬프트 제목: 이수진의 테스트2
- 시스템 메세지: 당신은 행복하고 아름답게 말하는 AI입니다.
- 프롬프트 포멧:
아래 내용을 확인하시고, 멋진 문구를 만들어주세요.
1. 문구의 주제
{topic}
2. 조건
{condition}
이때 중괄호 안에 프롬프트에 구성될 값을 넣게 되는데, 이 중괄호에 넣을 값을 입력할 수 있도록 페이지가 구성되는 것입니다.
이는 '프롬프트 실행하기' 메뉴에 해당되는 streamlit 코드에서 자동으로 중괄호 영역의 변수명을 인식해, text를 입력할 수 있도록 아래와 같이 코드가 구성되어 있습니다.
# {} 안의 변수 추출
variable_names = re.findall(r"\{(.*?)\}", prompt["prompt_format"])
# 사용자 입력 폼
with st.form("execute_prompt_form"):
for var in variable_names:
st.text_area(f"{var} 값 입력", value="", height=200)
그래서 저는 위 사진과 같이 topic에 "귀여운 고양이가 AI와 놀고있다"라는 값을 넣었고 condition(조건) 값에 "50자 이내로 작성해주세요", "다른 말은 하지말고 역할만 수행해주세요"라는 값을 입력하였습니다.
따라서, 프롬프트는 아래와 같이 완성되는 것이겠죠.
당신은 행복하고 아름답게 말하는 AI입니다.
아래 내용을 확인하시고, 멋진 문구를 만들어주세요.
1. 문구의 주제
귀여운 고양이가 AI와 놀고있다
2. 조건
- 50자 이내로 작성해주세요
- 다른 말은 하지말고 역할만 수행해주세요
이렇게 셋팅된 프롬프트 값을 기반으로 이제 실행 버튼을 누르면 LLM에게 실행이 됩니다.
저는 현재, OpenAI의 API를 사용하는 방법과 Azure OpenAI를 사용하는 방법 2가지를 구현해두었습니다.
만약, vLLM을 쓰신다거나 Claude 계열 모델(Sonnet, Haiku 등)또는 Ollama 등 다른 모델 API를 쓰신다면 코드에서 해당 로직을 추가하시면 될 것 같습니다.
저는 OpenAI의 API를 활용해 gpt-4o-mini 모델에 테스트를 해보았습니다. 그리고 gpt-4o-mini는 "고양이의 호기심과 AI의 지혜, 함께하는 놀이터!"와 같은 메세지를 전달해주었습니다.
프롬프트를 실행한 직후 이 결과를 바로 수정해서 저장할 수 있도록 해놨습니다. 그 이유는, LLM의 결과가 마음에 들지 않을 시 그 즉시 수정할 수 있도록 처리하는게 개인적으로 편리한 부분이 있어(회사에서 소통했을 때도 이런 니즈가 있었어서) 이렇게 추가해두었습니다. 가령 아래 사진과 같이 수정할 수 있습니다.
저는 LLM(OpenAI GPT-4o-mini)이 제공해준 결과에서 지혜를 조화로, 이모지가 있는 부분은 제거한 상태로 수정하고 이를 저장하였습니다.
프롬프트 실행 결과를 평가하는 페이지
마지막은 프롬프트 실행 결과를 평가하는 페이지입니다. 이 페이지의 목적은 실제 LLM의 실행 결과가 마음에 들었는지 여러 사람들의 의견을 들을 수 있게 일종의 설문이 가능한 형태로 제공한 것인데요. 제가 봤을 때는 프롬프트의 LLM 실행 결과가 좋을 수 있지만, 다른 사람이 보기엔 그렇지 않을 수 있으니 이를 위한 목적으로 만든 페이지입니다.
위 사진을 보면 방금 실행한 프롬프트 실행 결과가 출력됩니다. 어떤 모델을 썼는지(openai-4o-mini) 그리고 환경이 무엇인지(OpenAI 또는 Azure 등)를 보여주고 그 결과가 어땠는지 출력되고 있습니다.
프롬프트 실행 결과는 10점 척도와 더불어 피드백 내용을 작성하도록 구성되어 있습니다.
만약, 다른 분들이 보고 마음에 들면 높은 점수와 더불어 좋은 코멘트를 달아두실 것입니다.
마무리
이번 포스팅은 제가 개인적으로 계속 활용하던 LLM의 프롬프트 관리 서비스 페이지 개발기를 정리하고 코드 등을 공유한 내용입니다.
사실, 복잡하거나 어려운 것은 아니어서 공개를 하는 게 민망하고 부끄럽기도 하지만, 단 1명이라도 도움이 되기를 바라며 자신감을 가지고 공유해봅니다.
도움이 되시길 바랍니다.
긴 글 읽어주셔서 감사합니다.
혹시라도 저에게 연락을 주시고 싶으시다면,
- Linkedin: https://www.linkedin.com/in/lsjsj92/
- 블로그 댓글 또는 방명록
으로 연락 남겨주시면 됩니다!
'LLM&RAG' 카테고리의 다른 글
PGVector와 Python FastAPI를 연동하여 벡터 데이터 저장 및 유사도 기반 조회하기 (0) | 2025.01.06 |
---|---|
PostgreSQL PGVector 설치 및 사용하기(Feat. 벡터 데이터베이스(Vector Database) 구축) (2) | 2024.12.09 |
vLLM OpenAI API 서버와 랭체인(LangChain) 연동하여 RAG 구축하기 (1) | 2024.11.02 |
vLLM을 OpenAI API server(OpenAI-Compatible Server)로 배포하는 방법 및 예제(example) (3) | 2024.10.26 |
vLLM 사용법 - LLM을 쉽고 빠르게 추론(inference) 및 API 서빙(serving)하기 (4) | 2024.05.06 |