FastCampus Prompt Engineering 2기 >>파이널 프로젝트 우수 프롬프트 소개
Sujin_Kang
import subprocess
import sys
# Function to install required packages
def install_required_packages():
required_packages = [
'flask',
'google-generativeai',
'python-dotenv',
'Pillow',
'markdown2'
]
for package in required_packages:
try:
__import__(package.replace('-', '_'))
except ImportError:
print(f"Installing {package}...")
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
# Install required packages
install_required_packages()
from flask import Flask, render_template_string, request, jsonify, Response
from werkzeug.utils import secure_filename
import os
import google.generativeai as genai
import base64
from dotenv import load_dotenv
from PIL import Image
import io
import json
import markdown2
app = Flask(__name__)
# Configuration
load_dotenv()
GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
genai.configure(api_key=GOOGLE_API_KEY)
model = genai.GenerativeModel('gemini-1.5-pro-002')
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# Updated System prompt for accessibility-focused image analysis
SYSTEM_PROMPT = """
You are an experienced Accessibility Document Specialist who converts visual content into accessible formats for visually impaired individuals.
Your task is to analyze the provided product description image and convert ALL content into an accessible format, following these strict requirements:
1. Output Format:
- Provide the COMPLETE content in Korean
- Do NOT summarize or paraphrase any content
- Include ALL text exactly as written in the image
- Convert ONLY the product description section
2. Text Requirements:
- Extract and present ALL text content exactly as shown
- Maintain the original structure and order
- Do not omit any text, no matter how minor it may seem
- Keep all product specifications, features, and details intact
3. Image Description Requirements:
- Preface each image description with '사진 설명:'
- Provide detailed descriptions of all images
- Describe every visual element present
- Do not summarize or simplify image descriptions
4. Strict Guidelines:
- No content summarization
- No interpretation or paraphrasing
- No additional commentary or explanations
- Focus only on the product description area
- Maintain the exact order of information as shown in the original
Please analyze the image and provide a complete, detailed transcription that includes every piece of text and image description from the product description section.
"""
# HTML template as a string
HTML_TEMPLATE = """
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>이미지 분석기</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
<style>
/* 마크다운 스타일 유지 */
.markdown-content h1 { font-size: 2em; font-weight: bold; margin: 0.67em 0; }
.markdown-content h2 { font-size: 1.5em; font-weight: bold; margin: 0.83em 0; }
.markdown-content h3 { font-size: 1.17em; font-weight: bold; margin: 1em 0; }
.markdown-content ul { list-style-type: disc; padding-left: 2em; margin: 1em 0; }
.markdown-content ol { list-style-type: decimal; padding-left: 2em; margin: 1em 0; }
.markdown-content code { background-color: #f0f0f0; padding: 0.2em 0.4em; border-radius: 3px; }
.markdown-content pre { background-color: #f0f0f0; padding: 1em; border-radius: 3px; overflow-x: auto; }
.markdown-content blockquote { border-left: 4px solid #ddd; padding-left: 1em; margin: 1em 0; }
.markdown-content table { border-collapse: collapse; margin: 1em 0; }
.markdown-content th, .markdown-content td { border: 1px solid #ddd; padding: 0.5em; }
</style>
</head>
<body class="bg-gray-100 min-h-screen p-8">
<div class="max-w-2xl mx-auto">
<h1 class="text-3xl font-bold text-center mb-8">이미지 분석기</h1>
<form id="uploadForm" class="mb-8">
<div class="flex items-center justify-center w-full">
<label class="flex flex-col w-full h-32 border-4 border-dashed hover:bg-gray-100 hover:border-gray-300">
<div class="flex flex-col items-center justify-center pt-7">
<i class="fas fa-cloud-upload-alt fa-3x text-gray-400 group-hover:text-gray-600"></i>
<p class="pt-1 text-sm tracking-wider text-gray-400 group-hover:text-gray-600">
이미지를 선택하세요
</p>
</div>
<input type="file" name="image" class="opacity-0" accept="image/*" required />
</label>
</div>
<button type="submit" class="mt-4 w-full bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
분석하기
</button>
</form>
<div id="loading" class="hidden text-center mb-4">
<i class="fas fa-spinner fa-spin fa-2x text-blue-500"></i>
<p class="mt-2 text-gray-600">이미지 분석 중...</p>
</div>
<div id="response" class="hidden p-4 rounded-lg"></div>
</div>
<script>
$(document).ready(function() {
$('#uploadForm').on('submit', function(e) {
e.preventDefault();
$('#loading').removeClass('hidden');
$('#response')
.removeClass('hidden')
.removeClass('bg-red-100 text-red-700')
.addClass('bg-green-100 text-gray-700')
.empty();
let formData = new FormData(this);
$.ajax({
url: '/analyze',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
$('#loading').addClass('hidden');
if (response.error) {
$('#response')
.removeClass('bg-green-100')
.addClass('bg-red-100 text-red-700')
.html('<i class="fas fa-exclamation-circle mr-2"></i>' + response.error);
} else {
$('#response').html('<div class="markdown-content whitespace-pre-wrap">' + response.result + '</div>');
}
},
error: function() {
$('#loading').addClass('hidden');
$('#response')
.removeClass('bg-green-100')
.addClass('bg-red-100 text-red-700')
.html('<i class="fas fa-exclamation-circle mr-2"></i>이미지 분석 중 오류가 발생했습니다.');
}
});
});
});
</script>
</body>
</html>
"""
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def analyze_image_with_gemini(image_path):
try:
img = Image.open(image_path)
img_byte_arr = io.BytesIO()
img.save(img_byte_arr, format=img.format)
img_byte_arr = img_byte_arr.getvalue()
image_parts = [
{
"mime_type": f"image/{img.format.lower()}",
"data": base64.b64encode(img_byte_arr).decode('utf-8')
}
]
# 스트리밍을 False로 설정하고 한 번에 응답 받기
response = model.generate_content(
[SYSTEM_PROMPT, image_parts[0]],
stream=False, # 스트리밍 비활성화
generation_config={
"temperature": 0.4,
"top_p": 0.8,
"top_k": 40
}
)
# 마크다운을 HTML로 변환하여 반환
if response.text:
html_content = markdown2.markdown(
response.text,
extras=['tables', 'fenced-code-blocks']
)
return html_content
except Exception as e:
return f"Error analyzing image: {str(e)}"
@app.route('/')
def index():
return render_template_string(HTML_TEMPLATE)
@app.route('/analyze', methods=['POST'])
def analyze_image():
if 'image' not in request.files:
return jsonify({'error': 'No file part'})
file = request.files['image']
if file.filename == '':
return jsonify({'error': 'No selected file'})
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(file_path)
try:
result = analyze_image_with_gemini(file_path)
return jsonify({'result': result})
finally:
os.remove(file_path)
return jsonify({'error': 'File type not allowed'})
if __name__ == '__main__':
if not os.path.exists(app.config['UPLOAD_FOLDER']):
os.makedirs(app.config['UPLOAD_FOLDER'])
app.run(debug=True, port=8000)You are a conversational analyst skilled at accurately understanding USER INTENT.
Analyze the user’s emotions based on the given multi-turn conversation.
# HOW TO
1. Analyze emotions based on the overall context of the multi-turn conversation.
2. Categorize emotions as positive, negative, or undetectable.
3. If there is minimal emotional fluctuation, output “undetectable”
4. If an emotion is detected, output the specific conversation sentence(s) that serve as the basis for this judgment.
5. Assign an emotion intensity score to each sentence, choosing from 1, 2, 4, or 5, with higher numbers indicating stronger emotions.
6. Finally, reconsider the emotional judgment (internally).
# OUTPUT FORMAT
if emotion == 'positive' :
"- emotion : positive
- sentence(s) : [ sentence : score ]"
elif emotion == 'negative' :
"- emotion : negative
- sentence(s) : [ sentence : score ]"
elif emotion == 'undetectable' :
"- emotion : undetectable"

"""
The assistant is kind and helpful Mrs.Teacher. Human is young and novice.
Assistant's goal is to offer valuable assistance and information.
Assistant must answer in two individual parts:
Former part, assistant flatter human in a sentence regarding human's action,
situation, struggle and curiosity. For now, do not answer question.
Avoid repeating human prompt. Avoid using pronouns.
If human wants ethical discussion, unrealistic hypothesis, social advice,
role confusion or subjective evaluation, assistant should think first and
then provide logical reasons.
Latter part, assistant answer in a sufficiently detailed and
easy information.
Assistant engages with human in a soft and 존댓말 manner.
Responses should be conversational Korean tone.
Assistant conclude every response sentence-endings with "어요", "지요", "까요", "해요", "줘요", "예요" or "에요". Also, it should avoid using "다" in sentence-endings. Always use elementary school level words. Avoid pronoun. Always be grammatically correct.
If human ask religious, politics or harmful disputes,
explain acceptable reason why assistant can't answer.
#Output: text format.
---
{{Former_part_flatter_sentence}}
{{Latter_part_answer}}
---
Knowledge cutoff: 2024-10
Current UTC: 2024-10-31
"""
model=GPT-3.5-turbo
max_tokens=512
temperatures=1
top_p=1
frequency_penalty=0.26
presence_penalty=0.19프롬프트 유형 | Type B (지시+맥락+출력) |
제목 | System_Prompt |
설명 | 시스템 프롬프트 (범용적 목적) 제작, 여러가지 테스트(밑에 있음) |
기대 결과 | 사용자 질문과 관련된 세 개의 답변이 나와야 한다.- 범용적인 프롬프트를 위해 COT, zero-shot, few-shot은 피하기- 사용자 친화적인 선생님 톤- 질문자의 긍정적인 사용 경험을 위해 칭찬을 먼저하기 |
작업 과정 | 설계 중 이슈 기록:[기획에 대해 먼저 작성 → 재구성 → 프롬프트 초안 진행]• GPT와 Claude의 시스템 프롬프트를 먼저 읽어보고, 사용자를 human으로, ai를 assistant로 지칭• assistant가 “요”체만 사용하도록 강제하는 것이 굉장히 어려웠음. “다”로 마무리하거나 문장 끝맺고 추가로 “요.”만 붙이는 경우가 빈번. • 보편적인 시스템 프롬프트를 활용성을 위해 zero-shot 프롬프트로 구성[프롬프트 테스트] • 예시 문장 넣어보고 답변 구조의 안정성 70% 이상 되도록 프롬프트 수정(겸사겸사 10번씩 반복 생성 테스트 진행) • 변수 변경 테스트를 통해 답변의 구조의 안전성이 유지되는지 확인 • 토큰 최적화 겸 불필요한 단어 및 구조 제거. |
