프롬프트란
인간이 인공지능에게 전달하는 지시문으로 모델의 응답을 결정짓는 핵심 입력
역할: LLM에게 무엇을 할지 설명
PromptTemplate: 변수 기반 동적 프롬프트 생성
ChatPromptTemplate: 여러 메시지를 구조화하여 대화 설계
1. PromptTemplate
LangChain에서 프롬프트를 템플릿 형태로 추상화한 클래스
사용자 입력을 동적으로 삽입할 수 있는 문자열 포맷 객체
유동적 템플릿 생성가능, 변수만 바꿔서 다양한 결과 실험 가능
1) PromptTemplate 활용하여 다국어 번역기 만들기
prompt = PromptTemplate(
input_variables=["text", "language"],
template="{language} 언어로 번역해 : {text}"
)
llm = ChatOpenAI(model_name = '' ,temperature = 0)
chain = LLMChain(prompt=prompt, llm=llm)
LLMChain으로 모델과 프롬프트 템플릿 엮기 후 체인으로 실행하기 = > 파이프라인 형태라고 보면
# 실행
print(chain.run({"text": "I love Gen AI", "language": "프랑스어"}))
2) PromptTemplate 활용하여 코드 생성기 만들기
prompt = PromptTemplate(
input_variables=["task", "language"],
template="{language} 프로그래밍 언어로 다음 작업에 대해 코드 작성해 : {task}"
)
llm = ChatOpenAI(model_name = '' ,temperature = 0.2)
chain = LLMChain(prompt=prompt, llm=llm)
print(chain.run({"task": "리스트 안의 숫자 정렬", "language": "C++"}))
C++ 프로그래밍 언어로 리스트 안의 숫자 정렬 예시를 GPT한테 받을 수 있음
2. 답변의 다양성 조정 무작위성 제어
top_k: 확률이 가장 높은 K개 단어만 후보로 제한
top_k=3: 확률 상위 3개 단어만 샘플링 후보
top_p: 누적확률이 p이하가 될 때까지 단어를 모아 후보로 삼음
prompt=PromptTemplate(
input_variables=["product"],
template="다음 제품에 대한 짧고 인상적인 광고 문구 3개만들어줘: \n\n{product}"
)
product = "건강 추적 기능과 ai 코칭이 탑재된 최신 스마트워치"
# 보수적
llm1 =ChatOpenAI(model_name="", temperature=0.1, model_kwargs={"top_p":0.8})
chain1 =LLMChain(prompt=prompt, llm=llm1)
print(chain1.run(product))
#창의적
llm2 = ChatOpenAI(model_name="", temperature=1.5, model_kwargs={"top_p":0.95})
chain2 = LLMChain(prompt=prompt, llm=llm2)
print(chain2.run(product))
3. ChatPromptTemplate
시스템 메시지, 사용자 메시지, AI 메시지 등 역할을 구분
다중 메세지 기반의 프롬프트 흐름을 구성할 수 있도록 도와주는 템플릿
메세지 종류
- SystemMessage: AI에게 역할/성격을 지정
- HumanMessage: 사용자 질문 또는 요청
- AIMessage: AI 응답
1) 역할 부여
s_msg = "너는 친절하고 유머 있는 상담사야."
h_msg = "요즘 너무 지치고 의욕이 없어. 어떻게 하면 좋을까?"
chat_prompt = ChatPromptTemplate.from_messages([
("system", s_msg),
("human", h_msg),
])
llm = ChatOpenAI(model_name = '', temperature=1.1, model_kwargs={"top_p": 0.95})
messages = chat_prompt.format_messages() # 실제 메시지 객체 리스트를 생성
response = llm(messages)
print(response.content)
2) 메시지 흐름 관리
ai에게 예시를 주고 이와 비슷한 다른 메뉴를 추천해달라는 느낌
chat_prompt = ChatPromptTemplate.from_messages([
("system", "너는 요리 전문가야."),
("human", "간단한 점심 추천해줘."),
("ai", "김치볶음밥은 어때? 간단하고 맛있어."),
("human", "좋아! 다른 메뉴도 하나만 더 알려줘.")
])
llm = ChatOpenAI(model_name='', temperature=0.2, model_kwargs={"top_p":0.9})
messages = chat_prompt.format_messages()
response = llm(messages)
print(response.content)
3) 입력변수 사용
s_msg = "너는 {role}야."
h_msg = "요즘 너무 지치고 의욕이 없어. 어떻게 하면 좋을까?"
chat_prompt = ChatPromptTemplate.from_messages([
("system", s_msg),
("human",h_msg),
])
print(chat_prompt)
llm = ChatOpenAI(model_name='', temperature=0.5, model_kwargs={"top_p":0.95})
messages = chat_prompt.format_messages(role="현실적이고 무서운 상담사")
print(messages)
response = llm(messages)
print(response.content)
role을 변수로 놓고 chat_prompt.format_messages에 role을 지정해줘서 편하게 만들기
4. OutputParser
Output Parser
:LLM에서 반환된 자유형 텍스트를 우리가 원하는 형태로 가공해주는 도구
LLM은 기본적으로 자유형 텍스트를 반환하고 하지만 우리가 원하는 건 구조화된 데이터(리스트, 딕셔너리, JSON)이기 때문에
OutputParser를 사용한다
Output Parser 종류
- CommaSeparatedListOutputParser: 쉼표 - > 리스트
- PydanticOutputParser: 텍스트 - > Pydantic 모델로 파싱
- StructuredOutputParser: Json 기반 구조화 파싱
1) CommaSeparatedListOutputParser
쉼표 구분 문자열을 리스트로 변환해주는 파서
LLM이 생성한 문자열 중에서 쉼표로 구분된 항목을 리스트로 변환해준다.
parser = CommaSeparatedListOutputParser()
prompt = ChatPromptTemplate.from_messages([
("system", "너는 사용자 취향을 정리해주는 전문가야."),
("human", "10대 남학생들이 좋아하는 음식 5가지를 콤마로 구분해서 말해줘."),
("system", "{format_instructions}")
])
formatted_messages = prompt.format_messages(
format_instructions=parser.get_format_instructions() #parser 형태의 포맷으로 생성해라
)
llm = ChatOpenAI(model_name = '', temperature=0.5, model_kwargs={"top_p": 0.95})
response = llm.invoke(formatted_messages)
print(parser.parse(response.content))
2) StructuredOutputParser
LLM이 출력하는 내용을 지정된 JSON 구조로 유도하고 그 결고가를 파이션 딕셔너리로 파싱
JSON 기반 구조화 파싱
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
# 1. 출력 스키마 정의 (뉴스 제목, 요약)
schemas = [
ResponseSchema(name="headline", description="뉴스 제목"),
ResponseSchema(name="summary", description="뉴스 내용을 한 문장으로 요약")
]
# 2. 파서 생성
parser = StructuredOutputParser.from_response_schemas(schemas)
# 3. 프롬프트 구성 (메시지 기반)
prompt = ChatPromptTemplate.from_messages([
("system", "너는 뉴스 요약 도우미야."),
("human", "최근 흥미로운 스포츠 뉴스를 하나 소개하고 제목과 요약을 알려줘."),
("system", "{format_instructions}") # 여기서 파서가 제공한 형식 안내문이 들어감
])
# 4. 실제 메시지 포맷팅
messages = prompt.format_messages(
format_instructions=parser.get_format_instructions()
)
# 5. 모델 호출
llm = ChatOpenAI(model_name = 'gpt-4o-mini', temperature=0.5, model_kwargs={"top_p": 0.95})
response = llm.invoke(messages)
# 6. 결과 파싱 (JSON → dict)
result = parser.parse(response.content)
print(result)
이런식으로 제이슨 형태로 만들어주고 파서를 사용하면 딕셔너리 형태로 저장된다.
3) PydanticOutputParser
Pydantic: 데이터를 정의하고 검증 할 수 있는 파이썬 라이브러리
Python 객체처럼 쓰지만 json을 python으로 변환하는 것에 유리
- Pydantic 모델 정의
PydanticOutputParser부분에 오브젝트를 위에 선언했던 Pydantic 클래스로 채우면 그 형태로 저장하게됨
그리고 Human 메세지에 제목과 저자, 출판년도 알려줘 이렇게 명시적으로 받을 객체를 입력해주는 것이 국룰
# 1. Pydantic 모델 정의
class BookInfo(BaseModel):
title: str
author: str
year: int
# 2. 파서 생성
parser = PydanticOutputParser(pydantic_object=BookInfo)
# 3. 프롬프트 구성 (ChatPromptTemplate 사용)
prompt = ChatPromptTemplate.from_messages([
("system", "너는 책 추천 전문가야."),
("human", "좋은 책 하나만 추천해줘. 제목과 저자, 출판년도를 알려줘."),
("system", "{format_instructions}") # 파서가 제공한 응답 형식 가이드
])
# 4. 메시지 생성
messages = prompt.format_messages(
format_instructions=parser.get_format_instructions()
)
# 5. LLM 호출 및 파싱
llm = ChatOpenAI(model_name = 'gpt-4o-mini', temperature=0.5, model_kwargs={"top_p": 0.95})
response = llm.invoke(messages)
book = parser.parse(response.content)
# 6. 결과 출력
print(book)
조지오웰에 '1984'를 추천받았다. 좋은 소설이긴 한가보다
5. 출력 방식
1) invoke: 그냥 다 모아서 출력
2) stream: 실시간으로 ai가 대답하는 것처럼 보이는것
llm = ChatOpenAI(streaming=True)
for chunk in llm.stream(messages):
print(chunk.content, end="", flush=True)
stream 방식이 챗지피티에서 사용되는 것 같다