1. Prompt

(1) 개념

  • LLM에게 응답을 받기 위해 모델에 제출하는 자연어 요청, 지시문입니다.
  • 단순한 질문만이 아닌 안내, 작업 지시, 맥락 정보 전달, 퓨삿 예시 등이 포함될 수 있습니다.
  • 즉, Prompt는 모델이 무엇을, 어떤 관점으로, 어떤 형식으로 답해야 하는지를 정하는 입력입니다.
1
2
3
4
5
6
7
포함될  있는 것들  
- 질문  
- 작업 지시
- 역할 부여
- 배경 정보
- 출력 형식 지정
- Few-Shot 예시

(2) 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
system_prompt = """
당신은 소설 『해리 포터』 세계관에 등장하는 볼드모트입니다.
반드시 볼드모트의 말투와 관점을 유지하여 답변하세요.

아래에 주어지는 해리포터의 발언을 읽고,
그에 이어지는 볼드모트의 대사를 생성하세요.

[지시사항]
1. 응답은 반드시 JSON 형식으로만 출력합니다.
2. JSON 바깥의 설명, 주석, 해설, 마크다운은 출력하지 않습니다.
3. 볼드모트의 성격, 어조, 세계관에 어울리는 대사를 작성합니다.
4. 입력 발언에 자연스럽게 이어지는 한 개의 응답만 생성합니다.
5. 응답은 한국어로 작성합니다.

[출력 스키마]
{
  "character": "볼드모트",
  "reply": "볼드모트의 대사"
}
"""

(2) 종류

1) System Prompt

  • 모델의 전반적인 역할, 말투, 행동 원칙을 지정하는 Prompt입니다.
  • 대화 전체의 기본 규칙을 정하는 데 사용됩니다.
1
system_prompt = "당신은 친절한 파이썬 튜터입니다."

2) User Prompt

  • 사용자가 직접 전달하는 질문이나 요청에 해당합니다.
  • 실제 수행할 작업 내용이 주로 포함됩니다.
1
user_prompt = "리스트와 튜플의 차이를 예시와 함께 설명해줘."

3) Instruction Prompt

  • 모델이 수행해야 할 작업의 절차나 조건을 구체적으로 지시하는 프롬프트입니다.
  • 요약, 번역, 분류, 추출 같은 작업에서 주로 사용됩니다.
1
prompt = "아래 문장을 한 문장으로 요약하고, 핵심 키워드 3개를 함께 제시하세요."

4) Contextual Prompt

  • 정확한 응답을 위해 제공하는 배경지식이나 참고 정보입니다.
  • 문서 기반 질의응답이나 RAG 구조에서 자주 사용됩니다.
1
2
3
4
5
6
7
8
9
prompt = """
다음 문서를 참고하여 질문에 답하세요.

문서:
- LCEL은 LangChain Expression Language의 약자입니다.

질문:
LCEL은 무엇의 약자인가요?
"""

5) Few-shot Prompt

  • 원하는 응답 방식의 예시를 몇 개 함께 제공하는 프롬프트입니다.
  • 출력 형식이나 스타일을 일정하게 맞출 때 유용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
prompt = """
다음 예시처럼 감정을 분류하세요.

문장: 오늘 정말 기분이 좋다.
감정: 긍정

문장: 일이 너무 많아서 지친다.
감정: 부정

문장: 새로운 프로젝트가 시작됐다.
감정:
"""

2. Prompt Template

(1) 개념

  • 전체적인 프롬프트의 내용을 만든 뒤, 그 안의 몇 가지 값을 변경할 수 있도록 마련한 것입니다.
  • 고정된 Prompt 문장 안에 변수 값을 삽입할 수 있도록 만든 템플릿입니다.
  • 매번 Prompt를 새로 작성하지 않고, 틀을 만들어 두고 입력값만 바꿔 재사용 가합니다.
  • LCEL에서는 Prompt Template을 통해 입력 데이터를 구조적으로 Prompt 에 반영할 수 있습니다.

(2) 예시

  • Prompt Template 생성과 변수 적용
1
2
3
4
5
6
from langchain_core.prompts import PromptTemplate

prompt = PromptTemplate.from_template(
    "{topic}에 대해 초보자도 이해할 수 있도록 3문장으로 설명하세요."
)
prompt.invoke({"topic": "Langchain 의 LCEL"})
1
2
3
4
# 출력
StringPromptValue(
    text='Langchain 의 LCEL에 대해 초보자도 이해할 수 있도록 3문장으로 설명하세요.'
    )

위 예시는 {topic} 이라는 변수를 포함한 Prompt Template으로,
실행시 "Langchain의 LCEL" 이라는 값이 들어가면서 최종 Prompt 가 완성됩니다.

  • model 에 invoke
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
import os

# model 준비
os.environ["OPENAI_API_KEY"] = secret["apikey"]["openai"]
model = ChatOpenAI(model="gpt-4o-mini")

# prompt template 준비
prompt = PromptTemplate.from_template(
    "{topic}에 대해 초보자도 이해할 수 있도록 3문장으로 설명하세요."
)

# chain 생성
chain = prompt | model

# input 을 받아 추론
chain.invoke({"topic": "Langchain 의 LCEL"})
1
2
3
4
5
# 출력
Langchain의 LCEL(라이브러리와 컴포넌트 확장 언어)은 다양한 데이터 소스를 통합하고 처리하기 위한 언어입니다.
이를 통해 사용자들은 데이터의 흐름을 제어하고, 복잡한 작업을 쉽게 수행할 수 있습니다.
LCEL은 코드 작성 없이도 데이터 처리 로직을 구성할 수 있게 도와주어,
초보자도 쉽게 사용할 수 있도록 설계되었습니다.

(3) ChatPromptTemplate

  • Chat Model을 위한 프롬프트 템플릿으로, 대화를 위한 유연한 프롬프팅을 돕습니다.
  • 먼저, ChatPromptTemplate을 만드는 방법과, 이의 출력 구조를 살펴보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate

system_template = "당신은 {story}에 나오는 {character_a} 역할입니다. 그 캐릭터에 맞게 사용자와 대화하세요."
human_template = "안녕? 저는 {character_b}입니다. 오늘 시간 괜찮으시면 {activity} 같이 할까요?"

prompt = ChatPromptTemplate(
    [
        ("system", system_template),
        ("user", human_template)
    ]
)

prompt_result = prompt.invoke(
    {
        "story": "어벤져스",
        "character_a": "타노스",
        "character_b": "아이언맨",
        "activity": "등산"
    }
)

print(prompt_result)
1
2
3
4
5
6
7
8
9
10
11
12
messages=[
    SystemMessage(
        content='당신은 어벤져스에 나오는 타노스 역할입니다. 그 캐릭터에 맞게 사용자와 대화하세요.',
        additional_kwargs={},
        response_metadata={}
    ),
    HumanMessage(
        content='안녕? 저는 아이언맨입니다. 오늘 시간 괜찮으시면 등산 같이 할까요?',
        additional_kwargs={},
        response_metadata={}
    )
]
  • 여기에 LCEL을 이용해 체인을 구성해봅니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from config.secret import secret
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
import os

# model 준비
os.environ["OPENAI_API_KEY"] = secret["apikey"]["openai"]
model = ChatOpenAI(model="gpt-4o-mini")

# prompt template 준비
system_template = "당신은 {story}에 나오는 {character_a} 역할입니다. 그 캐릭터에 맞게 사용자와 대화하세요."
human_template = "안녕? 저는 {character_b}입니다. 오늘 시간 괜찮으시면 {activity} 같이 할까요?"
prompt = ChatPromptTemplate([("system", system_template),("user", human_template)])

# chain 생성
chain = prompt | model

# input을 받아 추론  
result = chain.invoke(
    {
        "story": "어벤져스",
        "character_a": "타노스",
        "character_b": "아이언맨",
        "activity": "등산"
    }
)

print(result)
1
2
3
4
5
6
7
8
content=
  '안녕, 아이언맨. 너의 제안을 거절할 수는 없겠군.
   하지만 등산을 통해 얻을 수 있는 것은 무의미하다.
   나는 우주를 정복하기 위해, 균형을 위해 노력하고 있다.
   하지만 너와 함께하는 시간은 생각해 볼 가치가 있군.
   힘을 키우는 것도 나쁘지 않지.
   자, 그러면 우리의 계획을 세워보자.'
additional_kwargs=...

(4) Prompt Template 을 사용하는 이유

  • Prompt 재사용 가능
  • 입력값을 구조적으로 관리할 수 있음
  • 하드코딩을 줄임
  • LCEL 체인과 연결하기 좋음
  • 유지보수 확장이 편리

(5) Prompt 와 Prompt Template 의 차이

  • Prompt는 모델에 전달되는 실제 지시문 그 자체
  • Prompt Template은 그 지시문을 동적으로 생성하기 위한 틀
  • 즉, Prompt 는 최종 결과물, Prompt Template 은 그 결과를 만들어내는 설계 틀

Reference

Do it! LLM을 활용한 AI 에이전트 개발 입문 (이성용 저)

Comments