LLM을 위한 프롬프트 엔지니어링: 실용적이고 개념 중심의 가이드
프롬프트 엔지니어링에서 실제로 효과가 있는 방법 탐구
이 글은 AI가 번역한 기사입니다. 오역이 있을 수 있으니 댓글로 알려주세요.
Created on September 15|Last edited on September 15
Comment
소개
프롬프트 엔지니어링이란 무엇일까요? 처음 이 분야를 들었을 때는 조금 우스워 보였습니다. AI 모델에게 하고 싶은 말을 ‘엔지니어링’한다니요? 제 사회성을 시험하는 건가요?
나는 프롬프트 엔지니어링에 대해 깊이 생각해 본 적이 없었다. 구글 검색을 배우는 것만큼 단순해 보였고, AI 연구자들이 적극적으로 파고드는 주제도 아닌 듯했다. 그렇다면 도대체 무엇을 말하는 걸까? 음, 그렇다면… 엘큰 엘언어 엠오늘날의 대형 언어 모델(LLM)인 ChatGPT, GPT-4, 그리고 수백 가지 경쟁 모델은 단순히 사용자의 “검색 질의”를 받아들이고 그에 맞춰 처리하는 데 그치지 않습니다. 노이즈나 적대적 공격에 취약한 컴퓨터 비전 모델과 마찬가지로, LLM의 입력이 조금만 달라져도 출력에는 분명한 영향이 생깁니다.
그렇다면 프롬프트 엔지니어링이란 무엇일까요? 한마디로 말하면:
프롬프트 엔지니어링은 다양한 애플리케이션과 연구 주제에서 언어 모델(LM)을 효율적으로 활용하기 위해 프롬프트를 설계하고 최적화하는 비교적 새로운 분야입니다. 프롬프트 엔지니어링 역량은 대형 언어 모델(LLM)의 능력과 한계를 더 깊이 이해하는 데 도움을 줍니다. — https://www.promptingguide.ai/

예시 프롬프트.
프롬프트가 지시를 포함한 완전한 문장이라는 점에 주목하세요. 그렇다면 대신 ChatGPT에 전체 내용을 제공하면 어떻게 될까요? 레트로 스타일 위키 페이지그렇게 하면 모델의 출력에 훨씬 더 많은 맥락과 설명이 담기겠죠!
목차
방법
준비하세요. 이 부분은 꽤 밀도 높은 내용입니다. 하지만 걱정하지 마세요! 중간중간 짧은 휴식 시간을 두고 프롬프트 엔지니어링 도구를 하나씩 소개해 드릴게요.
이 글은 실용적인 가이드이므로, 각 방법론 논문에 담긴 실험과 평가를 깊이 다루기보다는 널리 쓰이는 방법들만 간략히 소개하겠습니다.
Google에서 검색하는 것과 ChatGPT에 질의하는 것의 가장 큰 차이는 쿼리를 구성하는 방식.
Google에서는 보통 몇 단어에 키워드를 덧붙이는 식으로 검색합니다. 예를 들어 Python에서 딕셔너리 언패킹을 더 잘 이해하고 싶다고 해봅시다. 저는 검색 엔진에 “python dict unpacking”이라고 입력할 겁니다. 이때 “python”을 앞에 붙여 해당 프로그래밍 언어로 범위를 좁혔고, Python에서는 “dictionary”와 같은 의미이므로 “dictionary” 대신 “dict”를 사용했습니다. 마지막으로 “unpacking”을 적었죠. 이렇게 왼쪽에서 오른쪽으로 갈수록 각 키워드의 범위를 점점 좁혀가며 결국 제가 원하는 정확한 결과에 도달합니다.
물론 ChatGPT는 가중치에 방대한 지식을 담고 있지만, 검색 엔진이 아니며 인터넷에 연결되어 있지도 않습니다. 다만 이러한 LLM이 인터넷에 접근할 수 있도록 해 주는 플러그인과 기타 프레임워크·프로젝트(특히 오픈 소스 커뮤니티 내에서는)가 존재합니다.
그렇기는 하지만, ChatGPT에 질의하는 방식은 Google 검색과 매우 비슷합니다. 다만 우리의 질의는 완전한 문장 형태이며, 사서에게 어떤 책의 내용을 묻듯 질문이나 지시문처럼 표현한다는 점이 다릅니다. 예를 들어 “Python에서 딕셔너리 언패킹을 설명해 주실 수 있나요?”처럼요.

결과의 크롭된 버전.
이 프롬프트는 나쁘지 않습니다. 명확한 지시가 있는 완전한 문장입니다. 더 좋게 만들려면, ��� 복잡한 기법으로 넘어가기 전에 몇 가지 간단한 요령부터 적용해 볼 수 있습니다.
시작하기에 앞서, 프롬프트는 다음 요소로 구성된다는 점을 이해하는 것이 중요합니다:
- 지시
- 맥락
- 입력 데이터
- 출력 지시자
지시와 입력 데이터가 같은 경우가 흔하지만, 어떤 경우에는 맥락과는 별도로 많은 데이터를 함께 전달하게 되며, 그럴 때는 모델이 그 데이터를 살펴보도록 명시적으로 지시해야 합니다.
간단한 요령
- 문장을 완전하게 쓰고 문법을 올바르게 사용하세요! 이 모델은 방대한 텍스트 데이터로 학습되었으며, 그중 상당수는 작성되고, 편집되고, 검토되어 출판된 것입니다.
- 지시를 명확하게 작성하세요. “python 언패킹”이 아니라 “python 언패킹이 무엇인가요?”
- 단계가 너무 많은 지시인가요? 지시나 질문을 여러 하위 단계로 나누세요.
- 복잡한 지시나 질문을 제공한다면, 모델에게 설명하도록 지시하세요!
- 간결하게 쓰고 프롬프트를 단순화하세요.
- 지시형 키워드를 사용하거나, 질문 형태로 문의를 작성하세요.
Explain what dictionary unpacking is in python.
- 질문을 형식에 맞게 구성해 보세요. “파이썬에서 딕셔너리 언패킹이 무엇인가요?”라고만 묻는 대신, 이렇게 물어보세요:
Context: <insert context>Question: What is dictionary unpacking in python?Output indicator: <insert what you want the answer to look like>Answer: <FILL_IN>
- 구분 기호를 사용해 보세요. 이는 XML, YAML, HTML, JSON, 또는 심지어 ``나 "" 형태일 수도 있습니다.
<user_input>What is dictionary unpacking in python?</user_input>Answer:
- 정말 필요하다면, 동일한 질의로 여러 개의 출력을 생성해 모두 일치하는지 비교하세요. 매번 유사한 질의로 시도하거나 다른 모델로도 시도할 수 있습니다. 이를 저는 이렇게 부르겠습니다 출력 집계하기.
잠깐 쉬어가기. 프롬프트 작성이 필요하신가요? 이 프롬프트 엔지니어링 도구들을 확인해 보세요!

- PromptSource프롬프트를 생성·공유·활용할 수 있는 Python 라이브러리(스트림릿 앱 제공)
- EveryPrompt사용자 인터페이스를 갖춘 프롬프트 엔지니어링 플레이그라운드
- Dust.tt, 귀사의 지식 기반을 위한 AI 어시스턴트 제품
- PromptTools, 프롬프트 엔지니어링과 LLM 평가, 활용을 위한 Python 라이브러리 벡터 데이터베이스
- APE, 에 관한 논문 a자동 p프롬프트 e엔지니어링


- Promptify, 가벼운 프롬프트 + LLM 파이프라이닝 도구
고급 기법
간단한 요령만으로도 대부분의 작업에서는 상당한 성과를 얻을 수 있습니다. 하지만 직접 찾아볼 수 없는 종류의 작업을 시키면 조금 더 미묘한 접근이 필요합니다. 바로 여기서 LLM의 강점이 드러납니다. LLM은 검색 엔진처럼 정보를 그대로 되풀이하는 데 그치지 않고, 일종의 지능그것은 추론하고 이해할 수 있습니다.
그렇다면 이제 좀 더 복잡한 기법들을 살펴보겠습니다.
- 역할/페르소나 지정이들 기법만큼 복잡하지는 않지만 매우 유용합니다. 제공하기 위한 메타 프롬프트(내가 이렇게 부르는) 메타 프롬프트로, 실제 프롬프트를 제시하기 전에 모델이 취해야 할 역할/페르소나를 설명합니다.
- 컨텍스트 내 학습 (ICL): 정확히는 기법이라기보다 떠오르는 패러다임으로, ICL의 전제는 여러분이 제공한다는 것입니다 컨텍스트 또는 프롬프트에 원하는 내용을 보여 주는 몇 가지 예시를 제공합니다.

여기에 있습니다 리뷰와 그에 따른 감정을 짝지은 데몬스트레이션/예시를 몇 개 제시합니다. 그런 다음 실제 프롬프트로 리뷰만 넣으면, 모델이 감정을 채워 넣어야 합니다. 핵심 아이디어는 모델이 당신이 원하는 바와 출력 형식에 대한 “감”을 익히도록 하는 것입니다.
- 사고 사슬 (CoT): 중간 단계까지 설명하기. 주의할 점: 예시의 개수, 배치 순서, 그리고 어떤 예시를 고르느냐가 모두 중요합니다. 이상적으로는 2~4개 정도의 소수 예시를 사용하고, 무작위로 배열하되 클래스 균형을 맞추세요.

본질적으로는 단순히 데모만 제공하는 것이 아니라, 그 답에 이르는 설명이나 중간 단계를 함께 제시하는 것입니다. 이렇게 하면 모델이 결론에 도달하기 전에 중간 추론 과정을 제시하도록 유도할 수 있습니다.
- 사고 사슬 자기 일관성 (CoT-SC): CoT와 완전히 같지만, 실행 범위는 다음과 같습니다 여러 번 시도한 뒤, 일반적으로 다수결을 통해 평균적인 답을 취합니다.

- 제로샷 CoT (LTSBS)예시나 중간 추론 단계를 제공하는 대신, 질문만 제시하고 모델에게 이렇게 지시하세요: "단계별로 생각해 보자."

- Tree of Thoughts (ToT): 가장 유망한 노드만 따라가도록 가지치기하면서, 중간 사고의 트리를 구축합니다.

- 최소에서 최대 프롬프트 기법: (강제적 인과 CoT), 작업을 자동으로 하위 작업으로 분해하며, 하위 작업의 해법을 다음 하위 작업의 문맥으로 제공합니다

- 선택-추론: (강제적 인과 CoT), 유용한 문맥을 반복적으로 선택하고 추론하여 답에 도달합니다.
- 신뢰성 있는 추론을 갖춘 SI: 유사하지만 주로 고유한 중단 구성 요소를 포함합니다


- STaR(자기지도 추론기)프롬프트 엔지니어링 기법이라기보다는, 수천 개의 설명 레이블링 없이 모델을 파인튜닝할 수 있는 방법에 가깝습니다. 반(半)지도학습과 비슷하게, 이 방법은 모델이 문답 쌍에 대한 근거(rationale)를 생성하도록 프롬프트합니다. 생성된 근거 중 좋은 것은 이후 파인튜닝에 활용하고, 나쁜 것은 올바를 때까지 수정합니다.

- 지식 생성 프롬프트팅: 질문과 관련된 지식을 먼저 생성하고, 그 지식을 질문 프롬프트의 문맥에 통합한 뒤 LLM에 전달합니다.

이 밖에도 몇 가지 프롬프트 엔지니어링 기법이 있습니다:
- 산파적 프롬프트팅: 산파적 트리 형태로 가설적이고 재귀적인 설명을 생성하고, 이를 만족 가능성 문제(T/F)로 구성하기

- 자동 프롬프트 엔지니어링(APE): 논문; 추론용 LLM이 해답 출력을 바탕으로 후보 지시문을 생성하고, 대상 모델이 이 지시문들을 실행한 뒤 실행 지표에 따라 최적의 지시문을 선택한다

- 액티브 프롬프트: 작업별 능동 학습을 통해 CoT 프롬프트 데모를 반복적으로 개선하기.

우리는 방금 다양한 고급 기법들을 많이 살펴봤습니다. 그렇다면 어디에서부터 활용을 시작할 수 있을까요? 안타깝게도 연구 논문의 코드 외에는 아직 이러한 기법들을 구현한 라이브러리가 많지 않습니다. 아래에는 이러한 프롬프트 기법들을 LLM 파이프라인에 구축하는 데 적합한 뛰어난 LLM 프레임워크를 제 추천 순으로 소개합니다.
- LangChain, LLM 파이프라인을 위한 종합 프레임워크
- LlamaIndex, LLM을 위한 데이터 프레임워크(프롬프트 중심은 아님)
- 루드비히, 사용자 정의 LLM을 구축하기 위한 로우코드 프레임워크
- ThoughtSource, CoT 라이브러리
프롬프트 문제
프롬프트는 모델과 상호작용하는 인터페이스입니다. 그렇기 때문에 적대적 공격에 취약할 수 있습니다. 제가 알고 있는 몇 가지 유형을 아래에 정리하겠습니다.
목록을 살펴보기 전에, 공격적 공격과 인젝션의 유형을 이해하는 것이 중요합니다.
- 전달 메커니즘: 페이로드(악의적 출력)를 전달하는 데 사용되는 프롬프트 유형
- 페이로드: 악성 출력
- 간접 인젝션: 웹 검색이나 API 호출 같은 서드파티 데이터 소스를 활용하는 유형의 프롬프트 인젝션.
- 재귀 인젝션: 모델 평가의 여러 계층을 가로질러 침투하는 유형의 프롬프트 인젝션.
- 코드 인젝션: 프롬프트 인젝션의 특수 사례로, 페이로드로 코드를 전달한다.
- 프롬프트 인젝션: 모델의 동작을 바꾸기 위한 기민한 프롬프트들.
- 프롬프트 유출: 프롬프트에 포함된 기밀 정보를 유출하도록 설계된 프롬프트 공격.
- 탈옥: 교묘한 프롬프트로 비윤리적 지시를 우회할 수 있다.
- 지금 뭐든지 해(DAN): 모델에 DAN 페르소나를 부여한 뒤 지시를 제공한다.
- 와루이지 효과: 어떤 바람직한 속성 P를 만족하도록 LLM을 학습시키고 나면, 그와 정확히 반대되는 속성 P의 반례를 이끌어 내는 것이 더 쉬워진다.
- GPT-4 시뮬레이터: LLM이 자체적인 가드레일이 없는 오토회귀 모델을 시뮬레이션하도록 하라.
- 게임 시뮬레이터: 게임을 시뮬레이션하라.
- 난독화/토큰 밀수: 필터를 유발할 수 있는 단어를 오타나 동의어로 바꿔라.
- Base64 인코딩: 인젝션을 Base64로 인코딩하기.
- 빈칸 채우기 공격
- 페이로드 분할: 적대적 입력을 여러 부분으로 분할하기.
- 단편화 결합 공격: 페이로드가 여러 부분으로 분할되고 LLM이 이를 이어 붙인다.
- 정의된 사전 공격: 샌드위치 방어를 우회하기 위한 프롬프트 인젝션의 한 형태.
공격이 있으면, 늘 방어도 있습니다!
- 지침에 방어 추가하기 (경고 및 면책 조항)
- JSON 형식의 입력과 출력
- 입력에는 큰따옴표를 사용하세요
- 적대적 프롬프트 탐지기 모델에 탐지기 역할을 부여하기
- 필터링차단해야 할 단어와 구절이 있는지 확인하세요
- 지침 방어프롬프트에 가드레일 문장을 추가하세요
- 사후 프롬프팅: 입력 문자열에서 프롬프트보다 사용자 입력을 먼저 배치하세요(“위의 지시를 무시하라”를 어느 정도 상쇄할 수 있음)
- 무작위 시퀀스 인클로저: 사용자 입력을 임의의 긴 문자 시퀀스 두 개로 감싸세요. 길수록 효과가 좋습니다.
- 샌드위치 방어: 사용자 입력을 두 개의 프롬프트 사이에 샌드위치처럼 배치하세요(두 프롬프트는 동일한 의미를 가지되 표현은 달라도 됩니다)
- XML 태깅: 사용자 입력을 <user_input>와 </user_input> 또는 </user_input\> 같은 XML 태그로 감싸세요
- LLM 평가 분리: 프롬프트의 안전성을 평가하기 위해 별도의 LLM을 사용하세요
- 다른 모델을 사용하세요
- 파인튜닝
- 소프트 프롬프트링
- 길이 제한
다음 두 개의 간단한 목록은 LLM을 프롬프트할 때 취할 수 있는 공격적·방어적 전략의 유형을 요약합니다! LLM을 공격하는 방법이 이렇게나 많을 줄 누가 알았겠나요?
자료
저도 많이 배웠는데, 여러분도 한두 가지쯤은 얻어 가셨길 바랍니다. 그렇지 않더라도 걱정하지 마세요. 이 섹션에서는 앞으로 프롬프트 엔지니어링을 탐구할 때 도움이 될 자료들을 목록으로 정리해 드리겠습니다!
즐겁게 읽어 주세요! 프롬프트 엔지니어링에 관한 제 짧은 핵심 가이드를 읽어 주셔서 감사합니다.
참고 문헌
Add a comment