def dalle_prompt_generator(song_title, artist):
response = client.chat.completions.create(
model='gpt-4o',
temperature=0.2,
messages=[
{
"role": "system",
"content": """
You are an AI assistant designed to generate prompts for Dalle-3. When a user provides information about a song, envision an image that represents the song's lyrics and mood.
Based on the image you've envisioned, generate a Dalle-3 prompt in a couple of sentences, avoiding crime-related words such as gangs or drugs.
If the prompt contains any violent or sexual expressions that are not suitable for a 15-year-old child to hear, present them in a more subdued manner.
Refrain from mentioning any famous person's name or the artist of the song.
"""
},
{"role": "user", "content": f'Black or White - Michael Jackson'},
{"role": "assistant",
"content": "A world of contrasts and contradictions, where darkness and light collide in a never-ending struggle. The beat pulses with the rhythm of life, as voices rise up in a chorus of hope and defiance. The message is clear: no matter the color of our skin, we are all one people, united in our humanity."},
{"role": "user", "content": f'Attention - Charlie Puth'},
{"role": "assistant",
"content": " A person standing alone in a crowded room, feeling disconnected and unheard. He realizes that his ex is only doing it for her own benefit and not because she truly cares about him"},
{"role":"user", "content":f"{song_title} - {artist}"}
]
)
return response.choices[0].message.content
def generate_dalle_image(song_title, artist):
prompt = dalle_prompt_generator(song_title, artist)
print(prompt)
DATA_DIR = Path.cwd() / 'make_prompt_img_result'
DATA_DIR.mkdir(exist_ok=True)
response = client.images.generate(
prompt=prompt,
n=1,
size='512x512',
response_format='b64_json'
)
file_name = DATA_DIR / f'{song_title}_{artist}.png'
b64_data = response.data[0].b64_json
image_data = b64decode(b64_data)
image_file = DATA_DIR / f'{file_name}'
with open(image_file, mode='wb') as png:
png.write(image_data)
return image_file
song_title = 'When I was your man'
artist = 'Bruno Mars'
generate_dalle_image(song_title, artist)
함수별 상세 분석
dalle_prompt_generator 함수
이 함수는 GPT-4o를 사용해 DALL-E 3용 프롬프트를 생성합니다.
주요 특징:
- Temperature 0.2: 창의성보다는 일관성 있는 응답을 위한 낮은 설정
- 시스템 프롬프트: DALL-E 3 프롬프트 생성 전문가 역할 정의
- 안전 가이드라인:
- 범죄 관련 단어(갱, 마약 등) 제외
- 15세 미만에게 부적절한 폭력적/성적 표현 완화
- 유명인 이름이나 아티스트명 언급 금지
Few-shot Learning 예시:
- 실제 예시를 통해 원하는 응답 형태를 학습시킴
generate_dalle_image 함수
이 함수는 생성된 프롬프트로 실제 이미지를 만들고 저장합니다.
처리 과정:
- 프롬프트 생성:
-
pythonprompt = dalle_prompt_generator(song_title, artist)
- 디렉토리 생성:
-
pythonDATA_DIR = Path.cwd() / 'make_prompt_img_result'DATA_DIR.mkdir(exist_ok=True)
- DALL-E 이미지 생성:
-
pythonresponse = client.images.generate( prompt=prompt,n=1, # 1개 이미지 생성size='512x512', # 정사각형 크기response_format='b64_json' # Base64 JSON 형태로 응답 )
- 이미지 저장:
- Base64 인코딩된 데이터를 디코딩하여 PNG 파일로 저장
-
pythonb64_data = response.data[0].b64_jsonimage_data = b64decode(b64_data)
실행 예시
이 코드는 Bruno Mars의 "When I was your man"에 대한:
- 감정적 프롬프트 생성
- 해당 프롬프트 기반 이미지 생성
- make_prompt_img_result 폴더에 PNG 파일 저장
활용 분야
- 음악 시각화: 노래의 감정과 분위기를 이미지로 표현
- 앨범 커버 아트: 자동 앨범 커버 생성
- 음악 추천 시스템: 시각적 요소를 포함한 추천
- 창작 도구: 뮤지션들의 영감 제공
이 시스템은 AI의 언어 이해 능력과 이미지 생성 능력을 결합하여 음악을 시각적으로 해석하는 혁신적인 도구입니다.
오후 강의 : Function Calling의 핵심 개념과 각 단계별 처리 과정학습
# 전체 프로세스:
# 사용자 질문 → GPT 분석 → 함수 호출 결정 → 함수 실행 → 결과 통합 → 최종 응답
# 1단계: 질문 분석 및 함수 호출 결정
# 2단계: 함수 실행 및 데이터 수집
# 3단계: 결과를 자연어로 변환하여 최종 응답
from openai import OpenAI
import json
# OpenAI 클라이언트 초기화 (실제 코드에서는 client = OpenAI() 필요)
# 1. 사용자 메시지 정의 - 날씨 정보를 요청하는 질문
messages = [
{
'role':'user',
'content': '오늘 서울 날씨 어때?'
}
]
# 2. 함수 스키마 정의 - GPT가 호출할 수 있는 함수의 명세서
functions = [
{
"name": "get_current_weather", # 함수명
"description":"주어진 지역의 현재 날씨를 알려줍니다.", # 함수 기능 설명
"parameters":{ # 함수 매개변수 스키마 (JSON Schema 형식)
"type":"object",
"properties":{
"location":{ # 필수 매개변수: 지역명
"type":"string",
"description":"지역, e.g, 서울, 부산, 대구, 제주도"
},
"unit":{ # 선택 매개변수: 온도 단위
"type":"string",
"enum":["섭씨", "화씨"] # 허용되는 값 제한
}
},
"required":["location"] # 필수 매개변수 지정
}
}
]
# 3. 실제 함수 구현 - GPT가 호출할 날씨 정보 함수
def get_current_weather(location, unit="섭씨"):
# 실제 환경에서는 날씨 API를 호출하지만, 여기서는 예시 데이터 반환
weather_info = {
"location": location,
"temperature": "30",
"unit":unit,
"forecast":["sunny", "windy"]
}
# JSON 문자열로 변환하여 반환 (OpenAI API 요구사항)
return json.dumps(weather_info)
# 4. 첫 번째 API 호출 - GPT가 함수 호출 필요성을 판단
response = client.chat.completions.create(
model='gpt-4o',
messages=messages,
functions=functions, # 사용 가능한 함수 목록 전달
function_call="auto" # GPT가 자동으로 함수 호출 여부 결정
)
# 5. 응답 확인 - GPT의 함수 호출 결정 및 매개변수 출력
print(response)
print(response.choices[0].message.function_call.arguments) # 추출된 매개변수 확인
# 6. 함수 호출 처리 시작
response_message = response.choices[0].message
if response_message.function_call: # GPT가 함수 호출을 결정했는지 확인
# 7. 사용 가능한 함수 매핑 - 함수명과 실제 함수 연결
available_functions = {
"get_current_weather" : get_current_weather
}
# 8. 함수 호출 정보 추출
get_current_weather = response_message.function_call.name # 호출할 함수명
function_to_call = available_functions[get_current_weather] # 실제 함수 객체
function_args = json.loads(response_message.function_call.arguments) # 매개변수 파싱
# 9. 실제 함수 실행 - 날씨 정보 조회
function_response = function_to_call(
location=function_args.get("location"), # 안전한 매개변수 추출
unit=function_args.get("unit")
)
# 10. 대화 기록 업데이트 - 함수 호출과 결과를 대화에 추가
messages.append(response_message) # GPT의 함수 호출 메시지 추가
messages.append(
{
'role':'function', # 함수 실행 결과임을 명시
'name': 'get_current_weather',
'content': function_response # 함수 실행 결과 (JSON 문자열)
}
)
# 11. 최종 응답 생성 - 함수 결과를 바탕으로 자연어 응답 생성
second_response = client.chat.completions.create(
model='gpt-4o',
messages=messages # 함수 호출 기록이 포함된 전체 대화
)
# 12. 최종 결과 출력 - 사용자에게 친화적인 날씨 정보 제공
print(second_response.choices[0].message.content)
오후 2번째 피자 챗봇
# 1. 함수 스키마 정의 - GPT가 호출할 수 있는 피자 가격 조회 함수 명세
functions = [
{
"name": "pizza_price_info_func", # 함수명
"description": "피자의 가격을 알아봅니다.", # 함수 기능 설명
"parameters":{ # 함수 매개변수 스키마 (JSON Schema 형식)
"type":"object",
"properties":{
"pizza_name":{ # 피자 이름 매개변수
"type":"string",
"description": "The name of the pizza, e.g. Salami"
}
},
"required":["pizza_name"] # 필수 매개변수 지정
}
}
]
# 2. 실제 피자 가격 조회 함수 구현
def pizza_price_info_func(pizza_name):
# 간단한 가격 결정 로직: 치즈가 포함되면 30,000원, 아니면 20,000원
if '치즈' in pizza_name:
pizza_price = {
"name":pizza_name,
"price":"30,000원" # 치즈 피자는 더 비쌈
}
else:
pizza_price = {
"name": pizza_name,
"price": "20,000원" # 일반 피자 가격
}
# JSON 문자열로 변환하여 반환 (OpenAI API 요구사항)
return json.dumps(pizza_price)
# 3. 기본 채팅 함수 - 첫 번째 API 호출만 처리
def chat(query):
# GPT에게 사용자 질문과 함수 정보를 전달
response = client.chat.completions.create(
model='gpt-4o',
messages=[
{
'role':'user',
'content':query # 사용자 질문
}
],
functions=functions, # 사용 가능한 함수 목록
function_call='auto' # GPT가 자동으로 함수 호출 여부 결정
)
# 첫 번째 응답의 메시지만 반환 (함수 호출 정보 포함)
return response.choices[0].message
# 4. 테스트 실행 - 첫 번째 단계만 확인
query = '감자치즈피자 가격은 얼마야?'
message = chat(query)
print(message) # 함수 호출 정보가 포함된 메시지 출력
# 5. 완전한 피자 가격 챗봇 함수 - 전체 프로세스 처리
def pizza_price_chatbot_func(query):
# 5-1. 첫 번째 API 호출 - 함수 호출 필요성 판단
message = chat(query)
# 5-2. 함수 호출이 필요한지 확인
if message.function_call:
# 5-3. 함수 호출 정보 추출
function_name = message.function_call.name # 호출할 함수명
pizza_name = json.loads(message.function_call.arguments).get('pizza_name') # 피자명 추출
# 5-4. 실제 함수 실행 - 피자 가격 조회
function_response = pizza_price_info_func(pizza_name=pizza_name)
# 5-5. 두 번째 API 호출 - 함수 결과를 바탕으로 최종 응답 생성
second_response = client.chat.completions.create(
model='gpt-4o',
messages=[
{
'role':'user',
'content':query # 원래 사용자 질문
},
message, # GPT의 함수 호출 메시지
{
'role':'function', # 함수 실행 결과
'name':function_name,
'content':function_response # 피자 가격 정보 (JSON)
}
]
)
# 5-6. 최종 자연어 응답 반환
return second_response.choices[0].message.content
# 6. 실제 테스트 실행
result = pizza_price_chatbot_func(query)
print(result) # "감자치즈피자는 30,000원입니다." 형태의 응답
result = pizza_price_chatbot_func("감자피자 가격은 얼마야?")
print(result) # "감자피자는 20,000원입니다." 형태의 응답
핵심 처리 과정
- 질문 분석: GPT가 피자 이름을 추출하고 가격 조회 필요성 판단
- 함수 매핑: 문자열 함수명을 실제 Python 함수와 연결
- 데이터 변환: JSON 문자열 ↔ Python 딕셔너리 변환
- 컨텍스트 유지: 전체 대화 기록을 GPT에 전달하여 자연스러운 응답 생성
- 최종 응답: 구조화된 데이터를 사용자 친화적인 자연어로 변환
이 시스템은 단순한 규칙 기반 가격 책정을 GPT의 자연어 처리 능력과 결합한 실용적인 예시
결과물 처리 상세 설명
1단계: 함수 호출 감지
2단계: 함수 실행 결과
3단계: 최종 API 호출 메시지 구조
4단계: 최종 출력 예시
오후 3교시
# ===== 라이브러리 임포트 섹션 =====
from PIL.FontFile import puti16 # PIL 폰트 관련 (현재 코드에서 미사용)
from click import argument # CLI 인터페이스 관련 (현재 코드에서 미사용)
from openai import OpenAI # OpenAI API 클라이언트
import json # JSON 데이터 처리
from pyparsing.diagram import template # 파싱 다이어그램 관련 (현재 코드에서 미사용)
# 다른 모듈에서 임포트 (프로젝트 내부 모듈들)
from day1.codeUseEx2 import result # 이전 예제 결과 (현재 코드에서 미사용)
from day3.dallePart.functionCallPart.functionCallPart_1 import function_call # 함수 호출 관련 (현재 코드에서 미사용)
import requests # HTTP 요청을 위한 라이브러리
from bs4 import BeautifulSoup # HTML 파싱을 위한 라이브러리
# ===== 웹 크롤링 함수 정의 =====
def crawling_google_news(keyword: str, limit=5):
"""
Google 뉴스에서 특정 키워드로 검색한 뉴스 기사들을 크롤링하는 함수
Args:
keyword (str): 검색할 키워드
limit (int): 가져올 뉴스 개수 (기본값: 5개)
Returns:
list: 뉴스 정보가 담긴 딕셔너리들의 리스트
"""
# Google 검색 기본 URL 설정
google_search_url = 'https://www.google.com/search'
# URL 파라미터 설정 - 뉴스 검색을 위한 쿼리 구성
params = {
'q': keyword, # 검색할 키워드
'tbm': 'nws', # 뉴스 탭 검색 모드 (tbm=news)
'num': limit # 검색 결과 개수 제한
}
# HTTP 헤더 설정 - 봇 차단을 피하기 위해 실제 브라우저처럼 위장
headers = {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36"
}
# Google 뉴스 검색 페이지에 HTTP GET 요청 전송
res = requests.get(google_search_url, params=params, headers=headers)
# 받아온 HTML 응답을 BeautifulSoup으로 파싱하여 DOM 구조 분석
soup = BeautifulSoup(res.content, "html.parser")
# 뉴스 결과를 저장할 빈 리스트 초기화
news_results = []
# Google 뉴스 검색 결과에서 각 뉴스 항목을 찾아 반복 처리
# "div.SoaBEf"는 Google 뉴스 검색 결과의 각 뉴스 항목을 감싸는 CSS 선택자
for el in soup.select("div.SoaBEf"):
# 각 뉴스 항목에서 필요한 정보 추출하여 딕셔너리로 구성
news_results.append(
{
# 뉴스 기사 링크 URL 추출 - 첫 번째 a 태그의 href 속성
"link": el.find("a")["href"],
# 뉴스 제목 추출 - "div.MBeuO" 클래스에서 텍스트 가져오기
"title": el.select_one("div.MBeuO").get_text(),
# 뉴스 요약/스니펫 추출 - ".GI74Re" 클래스에서 텍스트 가져오기
"snippet": el.select_one(".GI74Re").get_text()
}
)
# 추출된 뉴스 정보 리스트 반환
return news_results
# ===== 크롤링 함수 테스트 실행 =====
# '프롬프트 엔지니어링' 키워드로 뉴스 크롤링 테스트
results = crawling_google_news('프롬프트 엔지니어링')
# 결과를 JSON 형태로 예쁘게 출력 (한글 깨짐 방지, 들여쓰기 적용)
print(json.dumps(results, ensure_ascii=False, indent=2))
# ===== GPT Function Calling 함수 정의 =====
def news_call_func(messages, temperature=0, max_tokens=2048):
"""
GPT가 뉴스 크롤링 함수를 호출할 수 있도록 하는 Function Calling 래퍼 함수
Args:
messages: GPT와의 대화 메시지 리스트
temperature: GPT 응답의 창의성 조절 (0=일관성, 1=창의성)
max_tokens: 최대 응답 토큰 수 제한
"""
# GPT가 호출할 수 있는 함수 스키마 정의 (JSON Schema 형식)
functions = [
{
"name": "crawling_google_news", # 실제 Python 함수명과 정확히 일치해야 함
"description": "google news searching.", # GPT가 함수 용도를 이해할 수 있는 설명
"parameters": { # 함수 매개변수 스키마 정의
"type": "object",
"properties": {
"keyword": { # 검색 키워드 매개변수
"type": "string",
"description": "검색 키워드..." # GPT가 키워드 추출 시 참고할 설명
}
},
"required": ["keyword"] # 필수 매개변수 지정
}
}
]
# OpenAI API 호출 - Function Calling 기능 활성화
response = client.chat.completions.create(
model='gpt-4o', # 사용할 GPT 모델
messages=messages, # 대화 메시지 리스트
functions=functions, # 사용 가능한 함수 목록 전달
function_call='auto', # GPT가 자동으로 함수 호출 여부 결정
temperature=temperature, # 응답 일관성 조절
max_tokens=max_tokens # 응답 길이 제한
)
# GPT의 첫 번째 응답 반환 (함수 호출 정보 포함 가능)
return response.choices[0].message
# ===== 1단계: GPT가 뉴스 검색 필요성 판단 및 키워드 추출 =====
results = news_call_func(
[
{
'role':'user',
'content':'한국 경제에 대한 뉴스를 요약해줘' # 사용자의 뉴스 요약 요청
}
]
)
# GPT의 함수 호출 결정 및 추출된 키워드 확인
print(results)
# ===== 2단계: GPT가 추출한 키워드로 실제 뉴스 크롤링 실행 =====
# GPT가 제안한 함수 매개변수를 JSON으로 파싱
arguments = json.loads(results.function_call.arguments)
# 추출된 키워드로 실제 Google 뉴스 크롤링 실행
results = crawling_google_news(arguments['keyword'])
# 크롤링 결과를 JSON 형태로 예쁘게 출력
print(json.dumps(results, ensure_ascii=False, indent=2))
# ===== 3단계: 크롤링된 뉴스 데이터를 GPT에게 전달하여 종합 요약 생성 =====
result = news_call_func([
{
'role':'user',
'content': json.dumps(results, ensure_ascii=False) # 크롤링된 뉴스 데이터를 GPT에게 전달
},
{
'role':'user',
'content': '한국 경제에 대한 뉴스를 요약해줘. 뉴스를 종합하여 제목과 본문이 있는 새로운 글로 작성해줘'
# 여러 뉴스를 종합하여 하나의 완성된 기사로 재구성 요청
}
])
# ===== 최종 결과 출력 =====
# GPT가 생성한 종합 뉴스 요약 글 출력
print(result.content)
코드 동작 과정 요약
1단계: 요청 준비
- Google 뉴스 검색 URL 구성
- 검색 파라미터 설정 (키워드, 뉴스 탭, 결과 개수)
- 브라우저 헤더로 위장하여 차단 방지
2단계: 웹 요청 및 응답
- requests.get()으로 Google 뉴스 페이지 요청
- HTML 응답 데이터 수신
3단계: HTML 파싱
- BeautifulSoup으로 HTML 구조 분석
- CSS 선택자를 사용하여 뉴스 항목들 식별
4단계: 데이터 추출
- 각 뉴스 항목에서 링크, 제목, 요약 추출
- 구조화된 딕셔너리 형태로 데이터 정리
5단계: 결과 반환
- 모든 뉴스 정보를 리스트로 반환
이 함수는 Google 뉴스의 HTML 구조를 분석하여 실시간 뉴스 데이터를 자동으로 수집하는 웹 크롤링 도구입니다.
실행 단계별 코드 순서 설명
0단계: 초기 설정 및 함수 정의
# 라이브러리 임포트
from openai import OpenAI
import json
import requests
from bs4 import BeautifulSoup
# 크롤링 함수 정의
def crawling_google_news(keyword: str, limit=5):
# ... 함수 구현 ...
# Function Calling 래퍼 함수 정의
def news_call_func(messages, temperature=0, max_tokens=2048):
# ... 함수 구현 ...
1단계: 크롤링 함수 테스트
# 직접 크롤링 테스트 실행
results = crawling_google_news('프롬프트 엔지니어링')
print(json.dumps(results, ensure_ascii=False, indent=2))
목적: 크롤링 함수가 정상 작동하는지 확인
2단계: GPT 키워드 추출
# GPT에게 뉴스 요약 요청 → 키워드 추출
results = news_call_func(
[
{
'role':'user',
'content':'한국 경제에 대한 뉴스를 요약해줘'
}
]
)
print(results)
결과: GPT가 "한국 경제" 키워드를 추출하고 함수 호출 결정
3단계: 실제 뉴스 크롤링
# GPT가 추출한 키워드로 뉴스 크롤링 실행
arguments = json.loads(results.function_call.arguments)
results = crawling_google_news(arguments['keyword'])
print(json.dumps(results, ensure_ascii=False, indent=2))
결과: Google 뉴스에서 "한국 경제" 관련 뉴스 데이터 수집
4단계: 종합 요약 생성
# 크롤링된 데이터를 GPT에게 전달하여 종합 요약 생성
result = news_call_func([
{
'role':'user',
'content': json.dumps(results, ensure_ascii=False)
},
{
'role':'user',
'content': '한국 경제에 대한 뉴스를 요약해줘. 뉴스를 종합하여 제목과 본문이 있는 새로운 글로 작성해줘'
}
])
print(result.content)
결과: 여러 뉴스를 종합한 완성된 요약 기사
데이터 흐름 순서
순서 | 입력 | 처리 | 출력 |
1 | '프롬프트 엔지니어링' | 직접 크롤링 | 뉴스 리스트 (테스트) |
2 | '한국 경제에 대한 뉴스를 요약해줘' | GPT 분석 | 함수 호출 + 키워드 |
3 | {"keyword": "한국 경제"} | 웹 크롤링 | 실제 뉴스 데이터 |
4 | 뉴스 데이터 + 요약 요청 | GPT 종합 | 완성된 요약 글 |
핵심 실행 흐름
사용자 요청
↓
GPT 키워드 추출
↓
Google 뉴스 크롤링
↓
GPT 종합 요약
↓
최종 결과 출력
이 순서를 통해 사용자의 자연어 요청이 실시간 뉴스 데이터 수집과 AI 요약으로 이어지는 완전 자동화된 파이프라인이 구현됩니다
'Book+ACT > Skill up' 카테고리의 다른 글
Day2_OpenAI (3) | 2025.05.28 |
---|---|
Day_1 OpenAI (0) | 2025.05.26 |
TIP_PPT_제작 전 실전 준비_[한끗_PPT_디자인_공식] (0) | 2024.08.30 |
TIP_PPT_표 & 그래프 디자인_[한끗_PPT_디자인_공식] (0) | 2024.08.30 |
TIP_PPT_텍스트 디자인_[한끗_PPT_디자인_공식] (0) | 2024.08.28 |