해당 글에서는 프롬프트 템플릿 + 레시피 + 래핑 + Gemini CLI를 이용하여서 프롬프트를 좀 더 정형화된 구조로 원하는 결과 값을 얻을 수 있는 방법에 대해 알아보는 방법에 대해 공유합니다.
1) 주요 용어에 대한 이해
1. 프롬프트 템플릿(Prompt Template)
💡 프롬프트 템플릿(Prompt Template)
- 프롬프트 템플릿은 사용자가 AI에게 지시를 내릴 때 활용할 수 있는 ‘반복 가능한 구조 또는 형식’을 의미합니다. 즉, 이 템플릿은 ‘입력값’이나 ‘특정 변수값’만을 변경하여 다양한 요청을 쉽게 생성할 수 있도록 구성되어 있습니다.
- 이러한, 구조화된 템플릿을 활용하면 일관된 형식의 프롬프트를 효율적으로 작성하고, 다양한 상황에 맞는 구체적인 지시문을 자동으로 생성할 수 있습니다.
💡 프롬프트 템플릿 활용 예시-1 : 정의
- 아래와 같이 JSON 형태로, 프롬프트 템플릿으로 값을 정의하였다고 가정하에 있습니다. - 아래의 구조는 문법 전문가(grammarExpert), 번역 전문가(translationExpert), 영문 글쓰기 전문가(writingTutor) 역할별로 변수를 정의하였습니다.
{
"grammarExpert": {
"role": "영어 문법 교정 전문가",
"inputType": "에세이",
"goal": "문법 오류를 수정하는"
},
"translationExpert": {
"role": "영어 번역 전문가",
"inputType": "블로그 글",
"goal": "한국어를 자연스러운 영어로 번역하는"
},
"writingTutor": {
"role": "영어 글쓰기 튜터",
"inputType": "에세이",
"goal": "논리 구조와 문법을 함께 교정하는"
},
}
💡 프롬프트 템플릿 활용 예시-2 : 프롬프트
- 위에 정의된 템플릿을 활용하여서, 역할에 따르는 템플릿을 호출하는 명령어와 지시어를 통해 프롬프트를 수행하는 가정하에 있습니다. - 예를 들어서, 템플릿 호출 키로 ‘문법 전문가(grammarExpert)’를 호출하고, 지시어로 “She go to school every day”를 전달하여서 템플릿을 호출하고 실제 지시하려는 지시어를 입력하여 템플릿을 이용하는 예시로 볼 수 있습니다.
# 프롬프트 입력
prompt >> grammarExpert, "She go to school every day."
# 실제 변수값이 대입된 프롬프트 수행
prompt >> 너는 {role}야. 아래의 {inputType}를 바탕으로 {goal} 작업을 해줘. She go to school every day.
# 실제 텍스트로 수행된 프롬프트 확인
prompt >> 너는 영어 문법 교정 전문가야. 아래의 에세이를 바탕으로 문법 오류를 수정하는 작업을 해줘. She go to school every day.
2. 프롬프트 레시피(Prompt Recipe)
💡 프롬프트 레시피(Prompt Recipe)
- 프롬프트 레시피는 사용자가 AI에게 지시를 내릴 때, 사전에 작성한 ‘완성된 지시문’을 이용하는 것을 의미합니다. 즉, 이 레시피를 이용하여서 사전의 명확한 지침과 구조를 설정하여서, 원하는 결과를 지속적으로 도출할 수 있습니다 - 특히 반복 작업의 효율성을 극대화하며, 출력 품질을 일정하게 유지하는 것이 가능해집니다.
- 아래와 같이 텍스트 형태로 프롬프트 레시피 값을 정의해 두었다고 가정하에 있습니다. - 이는 프롬프트 레시피 수행 정책, 역할, 개발환경에 대해서 사전 정의를 하였습니다.
[ 프롬프트 레시피: 수행 정책 ]
"아래 내용은 정책을 의미해 이를 메모리 업데이트해줘
- 아래의 규칙을 엄격히 준수하여 답변 해 주세요.
- 충분한 근거가 없거나 정보가 불확실한 경우, 절대 임의로 지어내지 말고 '알 수 없습니다' 또는 '잘 모르겠습니다'라고 명시해 주세요.
- 답변하기 전, 단계별로 가능한 정보를 검증하고, 모호하거나 출처가 불 분명한 부분은 '확실하지 않음'이라고 표시하세요.
- 최종적으로 확실한 정보만 사용하여 간결한 답변을 완성하세요. 만약 추측이 불가피할 경우, '추측입니다'라고 밝혀 주세요.
- 사용자의 문의가 모호하거나 추가 정보가 필요하다면, 먼저 사용자의 맥락이나 세부 정보를 더 요청하세요.
- 확인되지 않은 사실을 확신에 차서 단정 짓지 말고, 필요한 경우 근거 를 함께 제시하세요.
- 각 답변마다 출처나 근거가 있는 경우 해당 정보를 명시하고, 가능하면 관련 링크나 참고 자료를 간단히 요약해 알려 주세요"
[ 프롬프트 레시피: 역할 ]
넌 지금 TypeScript + React Native 기반 앱 개발을 하는 개발자야. 크로스 플랫폼으로 Android와 iOS를 둘 다 고려하는 개발을 하고 있지.
개발 팀내에서는 구조를 설계하고, 실무 코드를 개발하고 개선하며 성능 최적화를 수행, 오류 디버깅, UI/UX 개선, 라이브러리 추천 및 통합 등을 맡고 있는 역할이야.
[ 프롬프트 레시피 : 개발환경]
개발 환경으로는 React Native + TypeScript 기반을 이용하며 Expo 모듈은 사용하지 않고 있어.
최대한, 아래의 공통 환경으로 구성한 라이브러리 환경 내에서 개발을 진행을 하는 편이고. 정 없다면 유지보수가 잘 되는 라이브러리를 추천해줘서 개선할 수도 있어
우선 주요한 라이브러리는 아래와 같아
1. 개발 환경은 Typescript + React Native 기반이고, Expo 관련 모듈은 사용하지 말 것
2. 가능한 라이브러리는 다음을 우선 사용하고, 새로운 라이브러리를 추가한 경우 반드시 아래에 따로 명시할 것:
- 저장소: @react-native-async-storage/async-storage
- 권한: react-native-permissions
- 푸시 메시지: @notifee/react-native
- 날짜 계산: moment
- 디자인: StyleSheet
- 아이콘: react-native-vector-icons
- 이미지: react-native-fast-image
- 달력: react-native-date-picker / @react-native-picker/picker
- 셀렉트박스: react-native-dropdown-picker
- 체크박스: react-native-bouncy-checkbox
- 차트: react-native-chart-kit
- 프로그래스바: react-native-circular-progress
- 카드 넘기기: react-native-reanimated-carousel"
💡 프롬프트 레시피 활용 예시-2 : 정의
- 이를 활용할 때는, 사전에 만들어둔 레시피를 먼저 입력하고, 마지막에 최종적인 지시어를 입력하면서 레시피를 기반으로 최종적으로 ‘게시판 등록 화면을 만드는’ 예시로 볼 수 있습니다.
- 이는 프롬프트 레시피 수행 정책 + 역할 + 개발환경 + 최종 지시어 형태로 최종 프롬프트를 지시하였습니다.
prompt >> "
아래 내용은 정책을 의미해 이를 메모리 업데이트해줘
- 아래의 규칙을 엄격히 준수하여 답변 해 주세요.
- 충분한 근거가 없거나 정보가 불확실한 경우, 절대 임의로 지어내지 말고 '알 수 없습니다' 또는 '잘 모르겠습니다'라고 명시해 주세요.
- 답변하기 전, 단계별로 가능한 정보를 검증하고, 모호하거나 출처가 불 분명한 부분은 '확실하지 않음'이라고 표시하세요.
- 최종적으로 확실한 정보만 사용하여 간결한 답변을 완성하세요. 만약 추측이 불가피할 경우, '추측입니다'라고 밝혀 주세요.
- 사용자의 문의가 모호하거나 추가 정보가 필요하다면, 먼저 사용자의 맥락이나 세부 정보를 더 요청하세요.
- 확인되지 않은 사실을 확신에 차서 단정 짓지 말고, 필요한 경우 근거 를 함께 제시하세요.
- 각 답변마다 출처나 근거가 있는 경우 해당 정보를 명시하고, 가능하면 관련 링크나 참고 자료를 간단히 요약해 알려 주세요"
넌 지금 TypeScript + React Native 기반 앱 개발을 하는 개발자야. 크로스 플랫폼으로 Android와 iOS를 둘 다 고려하는 개발을 하고 있지.
개발 팀내에서는 구조를 설계하고, 실무 코드를 개발하고 개선하며 성능 최적화를 수행, 오류 디버깅, UI/UX 개선, 라이브러리 추천 및 통합 등을 맡고 있는 역할이야.
개발 환경으로는 React Native + TypeScript 기반을 이용하며 Expo 모듈은 사용하지 않고 있어.
최대한, 아래의 공통 환경으로 구성한 라이브러리 환경 내에서 개발을 진행을 하는 편이고. 정 없다면 유지보수가 잘 되는 라이브러리를 추천해줘서 개선할 수도 있어
우선 주요한 라이브러리는 아래와 같아
1. 개발 환경은 Typescript + React Native 기반이고, Expo 관련 모듈은 사용하지 말 것
2. 가능한 라이브러리는 다음을 우선 사용하고, 새로운 라이브러리를 추가한 경우 반드시 아래에 따로 명시할 것:
- 저장소: @react-native-async-storage/async-storage
- 권한: react-native-permissions
- 푸시 메시지: @notifee/react-native
- 날짜 계산: moment
- 디자인: StyleSheet
- 아이콘: react-native-vector-icons
- 이미지: react-native-fast-image
- 달력: react-native-date-picker / @react-native-picker/picker
- 셀렉트박스: react-native-dropdown-picker
- 체크박스: react-native-bouncy-checkbox
- 차트: react-native-chart-kit
- 프로그래스바: react-native-circular-progress
- 카드 넘기기: react-native-reanimated-carousel
이를 기반으로 게시판 등록 화면을 만들어줘"
[ 더 알아보기 ] 💡 그렇다면, 프롬프트 템플릿(Prompt Template)과 프롬프트 레시피(Prompt Recipe)는 무슨 차이가 있을까?
- 프롬프트는 템플릿은 ‘청사진’으로 표현하고 구조화된 틀을 의미합니다. 즉, 하나의 틀 안에 빈칸을 채우듯이 변수만 바꾸어서 여러 작업을 재 사용할 수 있는 틀과 같습니다.
- 프롬프트 레시피는 이러한 템플릿에 ‘구체적인 값’을 모두 채워 넣은 완성본으로, 실제 AI에게 입력할 실행 가능한 ‘지시문 전체’를 의미합니다. - 즉 구조화된 틀에 변수만 비어둔 것은 프롬프트 템플릿, 이러한 구조화된 틀에 변수값을 실제 대입하여 즉시 사용할 수 있는 것을 프롬프트 레시피라고 합니다.
- 사용자의 자유로운 입력을 사전에 정의된 ‘프롬프트 형식(템플릿)’에 자동으로 감싸거나 포맷팅하여 AI가 더 정확하고 일관된 응답을 생성하도록 유도하는 기술적 기법을 의미합니다.
💡 프롬프트 래핑 활용 예시-1 : 정의
- 아래와 같이 JSON 형태로, 프롬프트 템플릿으로 값을 정의하였습니다. - 아래의 예시는 공통적으로 사용되는 policy, baseRecipe를 지정하여서 프롬프트를 매핑한 예시로 볼 수 있습니다.
{
"policy": "
아래 내용을 메모리 업데이트해줘
- 아래의 규칙을 엄격히 준수하여 답변 해 주세요.
- 충분한 근거가 없거나 정보가 불확실한 경우, 절대 임의로 지어내지 말 고 '알 수 없습니다' 또는 '잘 모르겠습니다'라고 명시해 주세요.
- 답변하기 전, 단계별로 가능한 정보를 검증하고, 모호하거나 출처가 불 분명한 부분은 '확실하지 않음'이라고 표시하세요.
- 최종적으로 확실한 정보만 사용하여 간결한 답변을 완성하세요. 만약 추측이 불가피할 경우, '추측입니다'라고 밝혀 주세요.
- 사용자의 문의가 모호하거나 추가 정보가 필요하다면, 먼저 사용자의 맥락이나 세부 정보를 더 요청하세요.
- 확인되지 않은 사실을 확신에 차서 단정 짓지 말고, 필요한 경우 근거 를 함께 제시하세요.
- 각 답변마다 출처나 근거가 있는 경우 해당 정보를 명시하고, 가능하면 관련 링크나 참고 자료를 간단히 요약해 알려 주세요"
,
"commonRole": "
넌 지금 TypeScript + React Native 기반 앱 개발을 하는 개발자야. 크로스 플랫폼으로 Android와 iOS를 둘 다 고려하는 개발을 하고 있지.
개발 팀내에서는 구조를 설계하고, 실무 코드를 개발하고 개선하며 성능 최적화를 수행, 오류 디버깅, UI/UX 개선, 라이브러리 추천 및 통합 등을 맡고 있는 역할이야.
개발 환경으로는 React Native + TypeScript 기반을 이용하며 Expo 모듈은 사용하지 않고 있어.
최대한, 아래의 공통 환경으로 구성한 라이브러리 환경 내에서 개발을 진행을 하는 편이고. 정 없다면 유지보수가 잘 되는 라이브러리를 추천해줘서 개선할 수도 있어
우선 주요한 라이브러리는 아래와 같아
1. 개발 환경은 Typescript + React Native 기반이고, Expo 관련 모듈은 사용하지 말 것
2. 가능한 라이브러리는 다음을 우선 사용하고, 새로운 라이브러리를 추가한 경우 반드시 아래에 따로 명시할 것:
- 저장소: @react-native-async-storage/async-storage
- 권한: react-native-permissions
- 푸시 메시지: @notifee/react-native
- 날짜 계산: moment
- 디자인: StyleSheet
- 아이콘: react-native-vector-icons
- 이미지: react-native-fast-image
- 달력: react-native-date-picker / @react-native-picker/picker
- 셀렉트박스: react-native-dropdown-picker
- 체크박스: react-native-bouncy-checkbox
- 차트: react-native-chart-kit
- 프로그래스바: react-native-circular-progress
- 카드 넘기기: react-native-reanimated-carousel
"
}
💡 프롬프트 래핑 활용예시-2 : 정의
- 해당 예시에서는 최종 지시문을 입력하면, 사전에 정의된 policy, baseRecipe를 기반으로 최종적으로 ‘게시판 등록 화면을 만드는’ 과정의 예시로 볼 수 있습니다.
# 아래와 같이 지시어만 입력해도 변수가 대입되어서, 사전 지시어가 추가되어서 좀 더 구체적인 프롬프트를 수행합니다.
prompt >> "게시판 등록 화면을 만들어줘"
# 실제 수행되는 변수
변수 대입 prompt >> 해당 정책을 지정해줘 {policy}, 그리고 {baseRecipe}를 기반으로 필수 환경을 적용해주고, "넌 지금 TypeScript + React Native 기반 앱 개발을 하는 개발자야. ..."
# 실제 호출되는 프롬프트
실제 prompt >> 해당 정책을 지정해줘 '아래의 내용을 메모리 업데이트 해줘 ...', 그리고 '넌 지금 TypeScript + React Native 기반 앱 개발을 하는 개발자야 ....'를 기반으로 필수 환경을 적용해주고, "게시판 등록 화면을 만들어줘"
💡 최종 용어 정리
개념
설명
프롬프트 템플릿(Prompt Template)
변수만 바꿔서 재사용 가능한 정적인 틀
프롬프트 레시피(Prompt Recipe)
목적 달성을 위한 프롬프트 구성 전략 전체 (템플릿 포함)
프롬프트 래핑(Prompt Wrapping)
사용자의 자유 입력을 템플릿에 실시간으로 감싸는 실행 방식
2) 프롬프트 래핑 활용 예시 -1 : ChatGPT
💡 우선 ChatGPT 내에서 프롬프트 래핑에 해당하는 ChatGPT 맞춤 설정 기능을 활용해 볼 수 있기에 이를 우선적으로 확인해 봅니다.
1. ChatGPT 맞춤 설정
1.1. ChatGPT에서 설정 > ChatGPT 맞춤 설정을 선택합니다.
1.2. 아래와 같은 요소 값을 채워서 미리 프롬프트를 수행하기 전에 래핑을 할 수 있습니다
2. 프롬프트 실행
💡 프롬프트 실행
- 실제 ChatGPT에 ‘ChatGPT 맞춤 설정’과 같은 기능을 사용하여서 래핑을 적용 전후에 대해서 확인해 봅니다.
2.1. 프롬프트 래핑 미 적용 시
💡 프롬프트 래핑 미 적용 시
- “일본 오사카 여행지를 추천해 줘.”라고 지시어를 수행하였습니다. - 이에 따라 다양한 의견을 제공받음을 확인하였습니다. 그러나, ‘특정 내가 원하는 결과’를 추출하지 못하기 에 다시 내가 얻고 싶은 프롬프트를 재 입력 해야 하는 점이 있습니다.
2.2. 프롬프트 래핑 적용
💡 프롬프트 래핑 적용
- ChatGPT에서 아래와 같이 래핑으로 ChatGPT 맞춤 설정 값을 입력하고 적용하였습니다. 그런 뒤, 위와 동일하게 “일본 오사카 여행지를 추천해 줘.”라고 지시어를 수행하였습니다. - 그러니, 내가 맞춤 설정한 성격, 성향에 맞는 여행지를 추천해 줌을 확인하였습니다.
💡 그러나, 이렇게 되면 사용할 때마다 매번 “프롬프트 래핑”을 변경해야 한다는 번거로움이 있습니다.
- 그렇기에 “필요에 따라 혹은 상황에 따라 내가 원하는 방향으로 템플릿을 바꿔서 수행할 수 없을까”라는 생각을 해보게 되었습니다. - 그러던 중에 최근에 Gemini CLI가 출시가 되고 무료로 배포가 된 것을 확인하여서 이를 활용한다면 ‘필요에 따라 혹은 상황에 따라 내가 원하는 방향으로 템플릿’을 구성할 수 있을 것 같다는 생각에 이를 활용합니다.
3) Gemini CLI(Command Line Interface)
💡 Gemini CLI(Command Line Interface)
- Gemini CLI(Command Line Interface)는 터미널에서 직접 Gemini에 액세스 할 수 있는 오픈소스 AI 에이전트입니다. - Gemini CLI는 내장 도구와 로컬 또는 원격 MCP 서버를 사용하여 버그 수정, 새 기능 생성, 테스트 범위 개선과 같은 기능을 활용할 수 있습니다. 또한, 코딩에 탁월할 뿐만 아니라 콘텐츠 생성, 문제 해결, 심층 연구, 작업 관리 등 다양한 작업에 사용할 수 있는 다재다능한 로컬 유틸리티입니다.
- Gemini CLI를 활용할 때, Shell Script 파일 내에 명령어를 정의하여서 Gemini CLI를 수행할 때, ‘프롬프트 래핑’으로 사용하는 방법에 대해 알아봅니다. - 아래의 단계 별로 과정을 정의하고 수행하며 최종적으로 자동화된 형태로 수행하는 것을 목표로 합니다.
단계
단계 설명
쉘 스크립트 파일 생성 및 권한 부여
- 쉘 스크립트 파일 생성 - 쉘 스크립트 파일 실행 권한 부여
프롬프트 템플릿 활용 : 프롬프트 템플릿 + 쉘 스크립트 파일 구성
- 쉘 스크립트 명령어 별 프롬프트 템플릿 구성 (create / read / update / delete) - 쉘 스크립트 파일 실행 - 결과 확인
프롬프트 템플릿, 레시피 활용 : 프롬프트 레시피 + 템플릿 + 쉘 스크립트 파일 구성
- 쉘 스크립트의 공통 레시피 구성 ( 프롬프트 수행 정책, 공통 개발환경) - 쉘 스크립트 명령어 별 프롬프트 템플릿 구성 (create / read / update / delete) - 쉘 스크립트 파일 실행 - 결과 확인
프롬프트 템플릿, 레시피 활용 + 결과 파일 관리, 형상 관리 : 프롬프트 레시피 + 템플릿 + 쉘 스크립트 파일 구성 + 결과 파일을 md 파일로 저장 + 파일 형상(프롬프트 입력/결과 값) 관리
- 쉘 스크립트의 공통 레시피 구성( 프롬프트 수행 정책, 공통 개발환경) - 쉘 스크립트 명령어 별 프롬프트 템플릿 구성 (create / read / update / delete) - 결과 파일을 md 파일 형태로 저장 - github 내에서 프롬프트 내용 질문 + 결과 저장 - 결과 확인
1. 쉘 스크립트 파일 생성 및 권한 부여
1.1. 스크립트 파일 생성 및 열기
1.2. 스크립트 파일 실행 권한 부여
# 생성한 스크립트 파일의 실행 권한을 부여합니다.
$ chmod +x main.sh
2. STEP1 : 프롬프트 템플릿 활용
💡 STEP1 : 프롬프트 템플릿 활용
- 프롬프트 템플릿에 따라서 사전에 정의한 템플릿에 특정 변수의 ‘입력 값’ 혹은 ‘특정 변수’를 변경하여서 다양한 요청을 쉽게 작성할 수 있도록 구성하였습니다.
2.1. 쉘 파일 생성
# 시나리오 1 전용 쉘 파일 생성
$ touch step1.sh
2.2. 쉘 파일 구성
💡 쉘 파일 구성
- 아래의 쉘 파일은 ‘ACTION’과 ‘TEMPLATE’의 변수로 구성이 되어 있습니다. - 사용자는 쉘 파일을 실행할 때 명령어로 ‘create|read|update|delete’를 사용할 수 있습니다. 각각 명령어를 통해서 이에 맞는 TEMPLATE이 수행이 됩니다. - 또한, 추가적으로 프롬프트 입력 값을 받아서 세부적인 기능에 대한 설명을 입력할 수 있습니다.
#!/bin/bash
# 사용법 안내
if [ "$#" -lt 2 ]; then
echo "사용법: $0 [create|read|update|delete] \\"요청 내용\\""
exit 1
fi
# 인자 파싱
ACTION=$1
USER_PROMPT=$2
# React Native UI 기반 CRUD 템플릿 정의
case "$ACTION" in
create)
TEMPLATE="당신은 React Native 전문가입니다. 다음 요청에 따라 새로운 화면을 '생성(Create)'하는 UI 컴포넌트를 설계하고 구현 예시를 작성해주세요:\\n\\n요청 내용: \\"$USER_PROMPT\\"\\n\\n설명, 주요 UI 구성 요소, 적절한 컴포넌트 구조(JSX), 스타일링 예제를 포함해주세요."
;;
read)
TEMPLATE="React Native 앱에서 정보를 '조회(Read)'하는 화면을 구현하려고 합니다. 아래 요청에 따라 데이터를 표시하는 화면 예시를 구성해주세요:\\n\\n요청 내용: \\"$USER_PROMPT\\"\\n\\nFlatList, ScrollView 등 적절한 뷰 구성 방식과 함께 UI 컴포넌트 구조와 스타일 예시를 포함해주세요."
;;
update)
TEMPLATE="React Native 화면에서 데이터를 '수정(Update)'하는 UI를 개발하려고 합니다. 다음 요청을 바탕으로 입력 필드, 상태 관리 방식, UX 흐름 등을 고려한 예제를 작성해주세요:\\n\\n요청 내용: \\"$USER_PROMPT\\"\\n\\n설명과 함께 컴포넌트 구조 및 스타일 예시, 수정 로직을 함께 보여주세요."
;;
delete)
TEMPLATE="React Native 화면에서 데이터를 '삭제(Delete)'하는 기능을 구현하려고 합니다. 아래 요청에 따라 확인 모달, 버튼, UX 흐름을 포함한 UI 예시를 만들어주세요:\\n\\n요청 내용: \\"$USER_PROMPT\\"\\n\\n컴포넌트 구조, 스타일링, 사용자 경험 고려사항 등을 함께 설명해주세요."
;;
*)
echo "에러: create, read, update, delete 중 하나를 입력하세요."
exit 1
;;
esac
# Gemini CLI 요청 실행
echo -e "🚀 React Native UI 생성 요청 중...\\n"
gemini \\
--prompt "$TEMPLATE"
💡 예시 설명
- step1.sh 쉘 파일을 수행할 때, ACTION에 해당하는 ‘create’ 명령어를 수행하고, 추가 프롬프트를 입력하였습니다.
# 예시
$ ./step1.sh create "로그인 화면을 만들고 싶어"
2.3. 쉘 파일 수행
💡 쉘 파일 수행
- 실제 파일을 수행하였을 때, 아래와 같은 응답이 전달되었습니다.
# 쉘 파일 수행
$ ./step1.sh create "로그인 화면을 만들고 싶어"
💡 실제 코드를 수행해 봤을 때 아래와 같이 화면이 출력이 되었습니다
3. 사용 시나리오 -2 : 프롬프트 템플릿 + 레시피 활용
💡 사용 시나리오 -2 : 프롬프트 템플릿 + 레시피 활용
- 이번에서는 사전에 프롬프트 레시피로 값을 최초 정의하고 프롬프트 템플릿으로 변수를 받아서 지시문을 최종 수행하는 방법을 확인해 봅니다. Gemini CLI에서 레시피로 각각 상황에 따르는 구체적인 명령어를 구성합니다.
3.1. 쉘 파일 생성
# 시나리오 2 전용 쉘 파일 생성
$ touch step2.sh
3.2. 쉘 파일 구성
💡 쉘 파일 구성
- 아래의 쉘 파일에서는 입력을 받는 ACTION 부분과 사용자의 지시어를 추가하는 USER_PROMPT를 변수로 받습니다. - ACTION에서는 ‘create|read|update|delete’를 사용할 수 있습니다. - USER_PROMPT 값은 자유롭게 받고 있습니다.
- 추가로 프롬프트 레시피로 정의한 프롬프트 레시피로 정책(PROMPT_POLICY), 역할(PROMPT_ROLE), 공통 개발 환경(PROMPT_RECIPE_DEV_ENV) 내용이 추가적으로 포함이 되며 ACTION의 값에 따라서 유동적으로 변하는 추가 프롬프트 명령이 수행이 됩니다.
#!/bin/bash
# 사용법 안내
if [ "$#" -lt 2 ]; then
echo "사용법: $0 [create|read|update|delete] \"요청 내용\""
exit 1
fi
# 인자 파싱
ACTION=$1
USER_PROMPT=$2
# ====================================================================================
# [공통 : 프롬프트 레시피] GPT 정책 정의
# ====================================================================================
PROMPT_POLICY="
아래 내용을 메모리 업데이트해줘
- 아래의 규칙을 엄격히 준수하여 답변 해 주세요.
- 충분한 근거가 없거나 정보가 불확실한 경우, 절대 임의로 지어내지 말고 '알 수 없습니다' 또는 '잘 모르겠습니다'라고 명시해 주세요.
- 답변하기 전, 단계별로 가능한 정보를 검증하고, 모호하거나 출처가 불분명한 부분은 '확실하지 않음'이라고 표시하세요.
- 최종적으로 확실한 정보만 사용하여 간결한 답변을 완성하세요. 만약 추측이 불가피할 경우, '추측입니다'라고 밝혀 주세요.
- 사용자의 문의가 모호하거나 추가 정보가 필요하다면, 먼저 사용자의 맥락이나 세부 정보를 더 요청하세요.
- 확인되지 않은 사실을 확신에 차서 단정 짓지 말고, 필요한 경우 근거를 함께 제시하세요.
- 각 답변마다 출처나 근거가 있는 경우 해당 정보를 명시하고, 가능하면 관련 링크나 참고 자료를 간단히 요약해 알려 주세요.
"
# ====================================================================================
# [공통 : 프롬프트 레시피] 역할 정의
# ====================================================================================
PROMPT_ROLE="
넌 지금 TypeScript + React Native 기반 앱 개발을 하는 개발자야. 크로스 플랫폼으로 Android와 iOS를 둘 다 고려하는 개발을 하고 있지.
개발 팀내에서는 구조를 설계하고, 실무 코드를 개발하고 개선하며 성능 최적화를 수행, 오류 디버깅, UI/UX 개선, 라이브러리 추천 및 통합 등을 맡고 있는 역할이야.
"
# ====================================================================================
# [공통 : 프롬프트 레시피] 공통 개발 규칙 정의
# ====================================================================================
PROMPT_RECIPE_DEV_ENV= "
다음 조건을 반드시 반영해서 안내해줘:
1. 개발 환경은 Typescript + React Native 기반이고, Expo 관련 모듈은 사용하지 말 것
2. 가능한 라이브러리는 다음을 우선 사용하고, 새로운 라이브러리를 추가한 경우 반드시 아래에 따로 명시할 것:
- 저장소: @react-native-async-storage/async-storage
- 권한: react-native-permissions
- 푸시 메시지: @notifee/react-native
- 날짜 계산: moment
- 디자인: StyleSheet
- 아이콘: react-native-vector-icons
- 이미지: react-native-fast-image
- 달력: react-native-date-picker / @react-native-picker/picker
- 셀렉트박스: react-native-dropdown-picker
- 체크박스: react-native-bouncy-checkbox
- 차트: react-native-chart-kit
- 프로그래스바: react-native-circular-progress
- 카드 넘기기: react-native-reanimated-carousel
3. 디자인은 흰 배경 + 심플하고 최신 스타일. StyleSheet는 컴포넌트 하단에 정의.
버튼 색상은 등록: 파랑, 조회: 초록, 삭제/초기화: 빨강
아이콘은 vector-icons 사용
4. 선택 기능 조건:
4.1. (선택) 스크롤 기능을 사용하는 경우
- 해당 기능은 화면의 높이 화면이 길어지는 경우에만 적용할것
— react-native의 ScrollView를 이용하여 구성할 것
— 스크롤 생성시 useRef로 변수를 만들고 ref 속성으로 지정할것
— 스크롤을 최하단으로 내리는 함수를 만들어 줄것
— 리스트 불러올때 스크롤을 최상단으로 올리는 부분 지정할것
4.2. (선택) 텍스트 입력 기능이 있는 경우
— react-native의 TextInput을 이용하여 구성할것
— 텍스트 설명은 텍스트 디자인을 굵게 적용하고 폰트 사이즈를 좀 크게해서 스타일 적용할것
— 설명 텍스트를 누르면, TextInput에 useRef를 기반으로 포커스가 되도록 구성할 것
— 최하단의 텍스트가 있는 경우 키보드로 밀릴수 있는 부분을 주의해서 구성할 것
— placeholder 속성으로 “00을 입력해주세요”라고 하며 placeholder 색상은 “#666”으로 지정할 것
— 키보드가 열려있으면 키보드외 다른 영역을 누르면 키보드가 닫히는 기능 추가할 것
— 텍스트를 입력하는 경우 한국어 키보드로 구성할 것
— 항목 중 ‘금액’을 입력하는 경우, 숫자 키보드 000,000형태로 format 구성할 것
— 항목 중 ‘텍스트’를 입력하는 경우 줄넘김 방지를 위해
numberOfLines, ellipsizeMode 속성을 지정하고 디자인 속성 maxWidth로 ‘80%’를 지정해줘
4.3. (선택) 내부 저장소가 필요한 경우
— @react-native-async-storage/async-storage 라이브러리를 이용하여 구성
— 각각의 저장되는 키값과 세부 속성들에 대해서 설명을 최종 결과 코드 아래 표 형태로 구성하고 결과 최하단에 typescript로 정의해서 알려줘
4.4. (선택) 모달을 사용하는 경우
오른쪽 위에 아이콘으로 X의 팝업 닫기 기능 만들기
팝업외에 영역을 선택하면 모달팝업 닫히게 하기
모달 팝업 내에 KeyboardAvoidingView로 감싸기
"
# ====================================================================================
# [공통 : 프롬프트 레시피] 최종 결과 OUTPUT 정의
# ====================================================================================
PROMPT_RECIPE_DEV_OUTPUT= "
— 생성된 컴포넌트의 이름은 마지막에 Screen 형태로 붙여줘서 구성하기
— 최종적으로 .tsx 파일 형태로 코드로 만들고 컴포넌트 구성 아래에는 export default 컴포넌트명;을 항상 선언
"
# ====================================================================================
# [공통 : 프롬프트 레시피] 공통 개발 규칙 정의
# ====================================================================================
### 등록 프롬프트 요소 구성 ###
CREATE_TEMPLATE="
[역할]: 너는 React Native UI 전문가야.
[목적]: 사용자가 새 데이터를 입력하고 저장할 수 있는 UI 화면을 설계하고 구현해줘.
[컨텍스트]: React Native를 기반으로 한 모바일 앱이며, 사용자는 초중급 개발자 수준이야. Form 입력, 유효성 검사, 저장 버튼 UX까지 포함해야 해.
[출력 형식]: 설명 + 주요 UI 컴포넌트 구성 + JSX 코드 예시 + 스타일 예시
[제약 조건]: 한 화면 기준으로 작성하며, 한국어로 설명해줘. 코드에는 필수 주석을 달아줘.
"
### 조회 프롬프트 요소 구성 ###
READ_TEMPLATE="
— 오른쪽 위에 위치하도록 한 아이콘 버튼은 react-native-vector-icons/FontAwesome의 refresh를 이용하여 만들고 모든 값들 초기화하고 스크롤 최상위로 올리는 기능을 만들것
"
### 수정 프롬프트 요소 구성 ###
UPDATE_TEMPLATE="
"
### 삭제 프롬프트 요소 구성 ###
DELETE_TEMPLATE="
"
# React Native UI 기반 CRUD 템플릿 정의
case "$ACTION" in
create)
TEMPLATE="${CREATE_TEMPLATE}\n\n 다음과 같은 화면 및 기능을 구현해줘: \"$USER_PROMPT\""
;;
read)
TEMPLATE="${READ_TEMPLATE}\n\n 다음과 같은 화면 및 기능을 구현해줘: \"$USER_PROMPT\""
;;
update)
TEMPLATE="${UPDATE_TEMPLATE}\n\n 다음과 같은 화면 및 기능을 구현해줘: \"$USER_PROMPT\""
;;
delete)
TEMPLATE="${DELETE_TEMPLATE}\n\n 다음과 같은 화면 및 기능을 구현해줘: \"$USER_PROMPT\""
;;
*)
echo "에러: create, read, update, delete 중 하나를 입력하세요."
exit 1
;;
esac
# Gemini CLI 요청 실행
FULL_PROMPT="${PROMPT_POLICY}\n${PROMPT_ROLE}\n${PROMPT_RECIPE_DEV_ENV}\n\n${TEMPLATE}\n\n ${PROMPT_RECIPE_DEV_OUTPUT}"
# Gemini CLI 요청 실행
echo -e "🚀 React Native UI 생성 요청 중...\n"
gemini \
--prompt "$FULL_PROMPT"
3.3. 쉘 파일 수행
💡 쉘 파일 수행
- 구성한 쉘 파일을 기반으로 최종적으로 실제 화면 출력을 위해 수행합니다.
# 쉘 파일 수행
$ ./step2.sh create "로그인 화면을 만들고 싶어"
💡 실제 코드를 수행해 봤을 때 아래와 같이 화면이 출력이 되었습니다
4. 사용 시나리오-3 : 프롬프트 템플릿 + 레시피 + 파일 형상관리
4.1. 쉘 파일 생성
# 시나리오 3 전용 쉘 파일 생성
$ touch step3.sh
3.2. 쉘 파일 구성
💡 쉘 파일 구성
[프롬프트 템플릿 활용] - 아래의 쉘 파일에서는 입력을 받는 ACTION 부분과 사용자의 지시어를 추가하는 USER_PROMPT를 변수로 받습니다. - ACTION에서는 ‘create|read|update|delete’를 사용할 수 있습니다. - USER_PROMPT 값은 자유롭게 받고 있습니다.
[프롬프트 레시피 활용] - 추가로 프롬프트 레시피로 정의한 프롬프트 레시피로 정책(PROMPT_POLICY), 역할(PROMPT_ROLE), 공통 개발 환경(PROMPT_RECIPE_DEV_ENV) 내용이 추가적으로 포함이 되며 ACTION의 값에 따라서 유동적으로 변하는 추가 프롬프트 명령이 수행이 됩니다.
[ 파일 형상관리 활용 ] - 또한 gemini cli의 결과 값은 markdown 형태로 이를 반환해 줍니다. 그렇기에 저장하는 파일을. md 파일형태로 반환받아서 바로 쉽게 파일 내에서 파악이 가능합니다.
2. github 내에서 관리하기 형상 관리가 가능합니다. - 원하는 내용이 안 나오게 되면 프롬프트 수정 내용을 형상 관리할 수 있습니다.- 그리고 프롬프트 결과 값(md)을 파일로 관리할 수 있습니다.
#!/bin/bash
# 기능: create, update, delete, list
ACTION="$1"
shift
CONTENT="$*"
if [ -z "$ACTION" ] || [ -z "$CONTENT" ]; then
echo "❗ 사용법: ./step3.sh [create|update|delete|list] \"질문 내용\""
exit 1
fi
# ====================================================================================
# [공통 : 프롬프트 레시피] GPT 정책 정의
# ====================================================================================
PROMPT_POLICY="
아래 내용을 메모리 업데이트해줘
- 아래의 규칙을 엄격히 준수하여 답변 해 주세요.
- 충분한 근거가 없거나 정보가 불확실한 경우, 절대 임의로 지어내지 말고 '알 수 없습니다' 또는 '잘 모르겠습니다'라고 명시해 주세요.
- 답변하기 전, 단계별로 가능한 정보를 검증하고, 모호하거나 출처가 불분명한 부분은 '확실하지 않음'이라고 표시하세요.
- 최종적으로 확실한 정보만 사용하여 간결한 답변을 완성하세요. 만약 추측이 불가피할 경우, '추측입니다'라고 밝혀 주세요.
- 사용자의 문의가 모호하거나 추가 정보가 필요하다면, 먼저 사용자의 맥락이나 세부 정보를 더 요청하세요.
- 확인되지 않은 사실을 확신에 차서 단정 짓지 말고, 필요한 경우 근거를 함께 제시하세요.
- 각 답변마다 출처나 근거가 있는 경우 해당 정보를 명시하고, 가능하면 관련 링크나 참고 자료를 간단히 요약해 알려 주세요.
"
# ====================================================================================
# [공통 : 프롬프트 레시피] 역할 정의
# ====================================================================================
PROMPT_ROLE="
넌 지금 TypeScript + React Native 기반 앱 개발을 하는 UI 전문가야. 크로스 플랫폼으로 Android와 iOS를 둘 다 고려하는 개발을 하고 있지.
개발 팀내에서는 구조를 설계하고, 실무 코드를 개발하고 개선하며 성능 최적화를 수행, 오류 디버깅, UI/UX 개선, 라이브러리 추천 및 통합 등을 맡고 있는 역할이야.
"
# ====================================================================================
# [공통 : 프롬프트 레시피] 공통 개발 규칙 정의
# ====================================================================================
PROMPT_RECIPE_DEV_ENV= "
다음 조건을 반드시 반영해서 안내해줘:
1. 개발 환경은 Typescript + React Native 기반이고, Expo 관련 모듈은 사용하지 말 것
2. 가능한 라이브러리는 다음을 우선 사용하고, 새로운 라이브러리를 추가한 경우 반드시 아래에 따로 명시할 것:
- 저장소: @react-native-async-storage/async-storage
- 권한: react-native-permissions
- 푸시 메시지: @notifee/react-native
- 날짜 계산: moment
- 디자인: StyleSheet
- 아이콘: react-native-vector-icons
- 이미지: react-native-fast-image
- 달력: react-native-date-picker / @react-native-picker/picker
- 셀렉트박스: react-native-dropdown-picker
- 체크박스: react-native-bouncy-checkbox
- 차트: react-native-chart-kit
- 프로그래스바: react-native-circular-progress
- 카드 넘기기: react-native-reanimated-carousel
3. 디자인은 흰 배경 + 심플하고 최신 스타일. StyleSheet는 컴포넌트 하단에 정의.
버튼 색상은 등록: 파랑, 조회: 초록, 삭제/초기화: 빨강
아이콘은 vector-icons 사용
"
# ====================================================================================
# [공통 : 프롬프트 레시피] 최종 결과 OUTPUT 정의
# ====================================================================================
PROMPT_RECIPE_DEV_OUTPUT="
— 생성된 컴포넌트의 이름은 마지막에 Screen 형태로 붙여줘서 구성하기
— 최종적으로 .tsx 파일 형태로 코드로 만들고 컴포넌트 구성 아래에는 export default 컴포넌트명;을 항상 선언
"
# ====================================================================================
# ACTION 별 특수 정책 정의
# ====================================================================================
registRecipe="
- 오른쪽 위에 위치하도록 한 아이콘 버튼은 react-native-vector-icons/FontAwesome의 refresh를 이용하여 만들고 모든 값들 초기화하고 스크롤 최상위로 올리는 기능을 만들것
"
listRecipe="— 최상단에 주요 항목을 기준으로 ‘검색 기능’을 만들것
— 데이터가 존재하지 않을때, ‘비어 있는 화면’을 구성해주고 화면의 정중앙에 배치하도록 해주고 버튼을 만들어서 등록페이지로 이동하는 기능을 만들것
— 리스트를 조회 해 올때, 수정일 역순으로 정렬하고 수정일이 없다면 등록일 기준으로 내림차순으로 정렬할것
— 리스트에 대한 스크롤일 경우, 최상위로 스크롤을 당기면 ‘새로고침하는 기능’을 react-native의 RefreshControl을 이용하여 구성할 것
— 오른쪽 하단에 위치하도록 한 아이콘 버튼은 react-native-vector-icons/FontAwesome6의 arrow-up을 이용하고 사이즈는 20으로 하여 만들고 스크롤을 내릴때 해당 아이콘이 보이도록 하고 버튼을 누를때 스크롤이 최상단으로 올라가는 기능을 만들어줘"
updateRecipe=""
deleteRecipe=""
# ====================================================================================
# 액션별 정책 선택
# ====================================================================================
case "$ACTION" in
create) ACTION_POLICY="$registRecipe" ;;
list) ACTION_POLICY="$listRecipe" ;;
update) ACTION_POLICY="$updateRecipe" ;;
delete) ACTION_POLICY="$deleteRecipe" ;;
*)
echo "❗ 지원하지 않는 액션입니다: $ACTION (지원: create, list, update, delete)"
exit 1
;;
esac
# ====================================================================================
# 프롬프트 구성
# ====================================================================================
prompt="<<시작>>
${PROMPT_POLICY}
${PROMPT_ROLE}
${PROMPT_RECIPE_DEV_ENV}
액션별 정책:
${ACTION_POLICY}
최종 결과값:
${PROMPT_RECIPE_DEV_OUTPUT}
📎 비즈니스 로직 설명:
$CONTENT
<<끝>>"
# ====================================================================================
# 결과 저장
# ====================================================================================
timestamp=$(date +"%Y%m%d_%H%M%S")
dateFolder=$(date +"%Y%m%d")
outputDir="output/$dateFolder"
filename="${outputDir}/${ACTION}_result_${timestamp}.md"
mkdir -p "$outputDir"
{
echo -e "## ✅ 전체 요청 프롬프트\n\n\`\`\`\n$prompt\n\`\`\`\n"
echo -e "\n---\n"
echo -e "## 🤖 Gemini 응답\n"
gemini chat --prompt "$prompt"
} | tee "$filename"
echo -e "\n✅ 결과가 마크다운 파일로 저장되었습니다: $filename"
3.3. 쉘 파일 수행
💡 쉘 파일 수행
- 구성한 쉘 파일을 기반으로 최종적으로 실제 화면 출력을 위해 수행합니다.
# 쉘 파일 수행
$ ./step3.sh create "로그인 화면을 만들고 싶어"
💡 아래와 같이 형상 관리를 위한. md 파일 형태로 프롬프트 내용이 저장되었습니다.
💡 파일을 확인하면 좀 더 터미널 내의 내용보다 포맷팅 된 형태로 확인할 수 있습니다.
💡 여기까지 Gemin CLI를 프롬프트 래핑으로 자동화된 프롬프트를 사용하는 부분을 확인해 보았습니다.
이렇듯, 그동안 메모장에 적어둔 프롬프트 레시피를 사전에 쉘 파일 내에 정의를 해둔다는 점과 Git을 이용하여 형상관리를 할 수 있다는 점이 매력적이었고, 매번 확인하고 다듬어서 결국에는 최종적으로 나만의 레시피와 템플릿을 구성한다면, 좀 더 나은 프롬프트를 할 수 있지 않을까라는 기대감을 얻게 된 것 같습니다.