프롬프트 엔지니어링
프롬프트라는 용어는, AI에서는 AI를 작동시키기 위해 사용자가 언어 모델을 설정하거나 입력하는 모든 텍스트를 말하게 된다. 그래서 시스템 프롬프트부터 사용자의 명령까지 모두 프롬프트라고 할 수 있다. 그리고 AI가 좀 더 잘 동작하게 프롬프트를 개선하는 작업을 프롬프트 엔지니어링이라고 한다. 인공지능 모델이 답변을 할 때, 사용자가 원하는 답변을 할 수 있게 유도하는 것이다.
프롬프트 엔지니어링말고도 답변을 유도하는 방법은 여러 가지가 있을 것이다. 대표적으로 RAG 기법이 있다. 이 기법들은 상호 보완적으로 사용될 수 있는 구조이기 때문에, 우리는 전반적인 지식을 익혀야 한다.
프롬프트 엔지니어링과 System, Assistant, User 역할 적용하기
프롬프트 엔지니어링을 할 때, System, Assistant, User를 모두 사용할 수 있다.
첫 번째로 User는 LLM과 대화하는 주체다. 명확한 요청을 포함할 수록 명확한 응답이 온다. Assistant는 GPT의 답변이다. 마치 대화를 한 것처럼 Assistant를 조작함으로써, 사용자가 마치 정보를 전달한 것처럼 유도할 수 있다. 이 때는 Assistant는 본인이 답변했다고 생각하게 된다. System은 대화의 기본 규칙과 Assistant의 성격 등 혹은 대화 전반에 미치는 지침을 전달한다.
프롬프트 엔지니어링에서 주의할 점
최대한 명확하고 구체적으로 프롬프트를 작성해햐 한다. 맥락을 유지하는 것도 굉장히 중요하다. 우리가 ChatGPT를 일회성으로 사용하는 것보다, 대화를 유지하면서 점점 개선해 나가는 게 훨씬 더 좋은 결과를 얻을 수 있을 것이다. 그래서 일관적으로 명령을 하는 게 중요하다. System 설정을 통해, ChatGPT가 좋은 성격을 갖도록 유도할 수 있다.
이번에는 프롬프트 엔지니어링의 기본 원칙에 대해 배울 것이다. 대부분의 프롬프트 기법들이 이 원칙을 좀 더 잘 따르기 위해 고안된 것들이다.
명확하게 요청 사항을 전달해야 한다. GPT는 굉장히 많은 답안지를 갖고 있고 그 상황에 대한 정보는 없다고 이해하면 될 것이다. 그러니 구체적이고 명확한 요청을 진행해야 된다는 것이다.
또, 정보를 제공해야 한다. LLM은 최신 정보나 학습되지 않은 데이터는 모른다. 정보를 제공하는 여러 가지 방법이 있다. Assistant에 넣어도 되고, User가 직접 전달해도 되며, System에 넣어도 된다. Assistant에 전달하는 경우에는, 마치 GPT가 본인이 대화를 한 것처럼 간주한다. User를 통해 전달했을 때는, User가 정보를 자체적으로 전달한다고 생각하면 된다. System에 넣으면, 그 정보가 대화 전체에 영향을 미치게 된다.
제약 조건을 줘야 한다. 이 부분은 사실, 구체적인 지침과 동일하다고 생각하면 된다. 제약이, 답변이 나오는 범위를 줄이는 거기 때문이다.
복잡한 작업은 분할하자. GPT는 일반적으로 논리적인 추론을 잘 못한다. 예를 들면, 수학 문제를 풀게 하거나, 복잡한 수수께끼같은 것을 푸는 것이다. 그러나 이 경우, 복잡한 작업을 분할하면 좋은 성능을 낸다.
Shot 계열의 프롬프팅 기법
Shot 계열의 프롬프팅 기법은 예제를 주는 프롬프팅 기법을 말한다. Zero-Shot은 예제를 주지 않고 지침만 전달하는데, 활용폭이 넓을 수 있다. One-Shot은 예제를 하나만 주기 때문에 유도하는 힘이 다소 약하지만, 유도도 할 수 있고, 예제도 많이 필요하지 않다. 예제가 많은 경우, Few-Shot 프롬프팅을 통해 인공지능이 원하는 답을 하도록 최대한 유도할 수 있다.
Act As 류의 프롬프팅 기법
Act As 류의 프롬프팅 기법은 인공지능에게 다양한 역할과 성격을 부여하는 방법이다. 페르소나 기법이라고도 한다. 이렇게 인공지능에게 특정한 직업이나 성격을 부여하면, 정체성을 가진 대답을 유도할 수 있다.
CoT ( Chain of Thought, 생각의 사슬 ) 기법
CoT는 생각의 사슬이라는 기법인데, GPT가 일반적으로 잘 하지 못하는 논리적인 추론을, 좀 더 잘하게 하는 방법이다. 간단히 말해서, 단계별로 GPT가 답을 내리기 전에 스스로 생각하는 단계를 넣어주는 것이다.
직접 중간 과정을 넣어줘도 된다. 어려운 문제나 논리적인 문제를 풀 때, 그 단계를 직접 서술해주면, 그 단계대로 GPT가 문제를 풀게 된다. 이 방법은 Shot 계열의 기법을 CoT와 함께 결합한 것이다.
대화를 활용한 프롬프팅 기법
여기에는 정보 제공하기와 대화로 개선하기가 있다. 이는 RAG 기법의 핵심이 되는 내용이다. GPT에는 정보를 제공하는 방법이 다양하게 있다. System에는 대화 전체에 넣을 수 있는 정보를 넣어주면 된다. Assistant에, 정보 혹은 본인이 원하는 내용을 넣을 경우, 대화를 유도할 수 있다. User의 경우, 본인이 가공할 정보를 넣는 게 일반적이다.
형식 지정 기법
LLM이 잘 이해할 수 있는 형식이 있다고 한다. 형식은 Markdown, JSON, Symbol 등이 있다.
Markdown은 문법이다. 문서를 작성하는 언어인데, 글을 쉽게 구조화할 수 있다는 장점이 있다. LLM은 구조화된 정보를 더 잘 이해한다고 한다. 그래서 구조화할 수 있는 문서 작성 언어인 Markdown 언어로 프롬프트를 작성하면, GPT가 좀 더 잘 이해한다고 한다. JSON은 데이터를 키-값 쌍으로 표현하는 방식이다. 다음과 같이 데이터 처리나 시스템과의 연동이 필요한 경우, JSON 형식을 사용하면 좋다. Symbol은 일반적으로, 중요한 부분을 강조할 때 사용하는데, 리스트, 혹은 각종 더하기, 빼기 기호나 중괄호 등을 사용하면, 해당 부분이 강조돼서 GPT한테 들어가게 된다. 우리는 기본적으로 #을 많이 활용하게 될텐데, 말투나 역할, 출력 형태 등 프롬프트의 주제에 따라서 구분한다고 생각하면 된다고 한다.
LLM을 실무에서 활용할 때는 고려사항이 많다. 첫 번째로 보안 문제다. 대화형 AI인 LLM은, 사용자가 입력한 내용을 바탕으로 서비스를 개선할 수도 있고, 그 데이터를 바탕으로 다시 학습할 수도 있어서, 만일 의료, 법률적인 상담 등 개인 정보가 포함될 수 있거나 회사의 기밀이 오갈 수 있는 내용을 입력으로 받을 수 있는 경우, 반드시 필터링이 필요하다. 그리고 그러한 데이터가 들어왔을 때, 그 데이터를 학습 데이터로 사용하지 않는 게 중요하다. 뿐만 아니라, 데이터의 통신을 통해 이러한 입력을 LLM에 전달하기 때문에, 통신 과정에 대한 보안도 신경써줘야 한다. 보안을 강화하는 방법으로는 민감 정보 필터링, 암호화, 접근 통제, 데이터 저장 최소화가 있다.
벡터 DB와 LangChain 활용하기
LLM의 한계를 극복하기 위해서 벡터 DB와 LangChain라는 기술을 사용할 수 있다. 간단히 말해서 벡터 DB는 이미지나 텍스트같이, 숫자가 아닌 데이터를 숫자로 바꾼다면, 이걸 저장하고 유사한 데이터끼리 찾을 수 있는 기능을 제공하는 데이터베이스다. LangChain은 LLM에 있어서, 많은 요소들이 결합돼서 하나의 서비스를 만들게 되는데, LLM 모델 사용만을 넘어서 벡터 DB나 RAG와 같은 서비스들을 쉽게 통합해주는 라이브러리 중 하나다. 이 기법들은 LLM의 사용에 있어서, 무조건 있어야만 쓸 수 있다기 보다는, 알아야 훌륭한 LLM 서비스를 만들 수 있다에 가깝다.
RAG ( Retrieval-Augmented Generation )
LLM과 검색 시스템을 결합한 개념이다. LLM의 기본 한계는, 학습되지 않은 데이터에 대해서는 답변을 생성해줄 수 없다는 것이었다. 그런데, 학습되지 않은 데이터라고 할지라도, LLM은 입력된 데이터를 바탕으로 확률적으로 단어를 생성하기 때문에 입력으로 들어온 정보는 활용할 수 있다. 그러면, 검색 시스템을 결합해서, 기존에 학습되지 않은 데이터라도, 입력으로 넣어준다면, 충분히 좋은 성능을 발휘할 수 있다. 그게 바로 RAG다.
동작 원리를 살펴보자. 검색 단계와 생성 단계가 있다. 먼저 Retrieval (검색) 단계를 살펴보자. 사용자가 질의를 하면, Vector DB에서 질문과 유사한 문서나 데이터를 검색한다. 이때 임베딩 모델을 사용한다. 임베딩 데이터를 검색해야 하기 때문에, 질의 자체도 벡터로 변환해야 한다. 다음으로 Generation (생성) 단계다. 이 단계에서는, 검색된 문서를 LLM에 전달하고, 이를 바탕으로 자연스러운 답변을 생성하는 것을 목표로 한다. 검색된 문서를 참조해서, 최신 정보를 포함하거나 학습되지 않은 정보를 포함한 정확한 답변을 생성할 수 있게 된다. 학습 자체에는 데이터가 이미 있다고 하더라도, 사용하기 힘든 데이터가 존재할 수 있다. 특히 개인 유저와 관련된 정보라면 특히 그러할 것이다. 이 경우, RAG 시스템을 사용하면, LLM의 한계도 극복하고, 개인정보 문제도 피하는 방법으로 시스템을 구축할 수 있다.
Vector DB를 사용하려면, 항상 RAG가 결합돼야 하는 것은 아니며, 그 반대도 마찬가지다. 그러나, 이 둘을 결합해서 사용하면, 매우 강력한 효과를 낼 수 있다. Vector DB는 유사한 문서를 검색해주고, RAG는 검색된 문서를 바탕으로 정확한 답변을 생성하는 것이다.
강의 외부에서 추가로 알게 된 내용
- 프레임워크와 라이브러리
프레임워크와 라이브러리는 소프트웨어 개발을 쉽게 하기 위해 제공되는 도구이지만, 기능과 사용 방식에서 중요한 차이가 있다.
프레임워크 (Framework)
프레임워크는 소프트웨어 개발의 기본 구조를 제공하는 일종의 뼈대다. 개발자는 이 뼈대 안에서 코드를 작성해 기능을 추가한다. 프레임워크는 전체적인 흐름을 통제하면서 개발자가 작성한 코드를 호출한다. 예를 들면, Django(웹 개발), React(프론트엔드 개발), Spring(자바 기반 애플리케이션 개발) 등이 있다. 특징은 제어 역전과 고정된 구조다. 제어 역전 (Inversion of Control)을 알아보자. 프레임워크는 실행 흐름을 자체적으로 관리하며, 개발자가 작성한 코드를 특정 시점에 호출한다. 개발자가 코드의 흐름을 직접 제어하지 않는다는 점이 큰 특징이다. 다음으로 고정된 구조를 알아보자. 프레임워크는 일정한 구조와 규칙을 제공한다. 개발자는 이 구조를 기반으로 코드의 일부만 작성해도 애플리케이션을 쉽게 개발할 수 있다.
라이브러리 (Library)
라이브러리는 특정 기능을 수행하는 코드 모음집이다. 개발자는 필요할 때마다 원하는 라이브러리를 호출해서 사용할 수 있다. 예를 들면, NumPy(과학 계산), Pandas(데이터 분석), Matplotlib(데이터 시각화) 등이 있다. 특징으로는 함수 호출 기반, 유연한 사용이 있다. 먼저 함수 호출 기반을 알아보자. 라이브러리는 함수나 클래스를 모아놓은 일종의 도구 상자처럼, 특정 기능이 필요할 때 개발자가 직접 호출해서 사용한다. 다음으로 유연한 사용을 알아보자. 개발자가 필요한 기능만을 선택적으로 사용할 수 있으며, 코드의 흐름을 직접 제어한다.
프레임워크와 라이브러리의 차이점
제어 흐름과 사용 방식, 확장성의 차이가 있다.
먼저 제어 흐름의 차이점을 알아보자. 프레임워크는 전체 흐름을 제어하고, 개발자가 작성한 코드를 특정 시점에 호출한다. 반면, 라이브러리는 개발자가 필요한 시점에 선택적으로 호출해 사용하는 방식이다.
다음으로 사용 방식의 차이점을 알아보자. 프레임워크는 코드 구조와 규칙을 제시하지만, 라이브러리는 사용에 대한 고정된 규칙이 적고 자유롭게 호출할 수 있다.
마지막으로 확장성의 차이점을 알아보자. 프레임워크는 특정한 아키텍처를 제공해 구조화된 개발을 돕지만, 라이브러리는 단순히 필요한 기능을 추가하는 데 중점을 둔다.
결론적으로, 프레임워크는 개발의 뼈대를 제공하고 제어 흐름을 관리하며, 라이브러리는 특정 기능을 수행하는 도구로서 유연하게 호출해 사용하는 차이가 있다.
'AI 부트캠프 > 챕터3(11.08~12.04)' 카테고리의 다른 글
TIL 38 개인 과제 (3) | 2024.11.14 |
---|---|
TIL 37 (1) | 2024.11.13 |
TIL 35 (2) | 2024.11.11 |
TIL 34 (1) | 2024.11.10 |
TIL 33 (2) | 2024.11.09 |