김진중(골빈해커)님의 '최고의 프롬프트 엔지니어링 강의'를 읽고 정리한 글입니다.
모델을 선택할 때 고려해야 할 것들
성능이 높은 모델일수록 속도는 떨어진다. 즉, 성능이 낮은 모델일수록 속도는 빨라짐
->비용과 성능은 비례하지만 성능이 올라가는 것에 비해서는 비용이 훨씬 더 크게 높아지는 편
입력 토큰(프롬프트)에 대한 가격보다 결과물로 생성한 토큰 가격이 보통 두세 배 정도 비싸기 때문에 답변이 길어야하는 작업이라면 더 큰 비용이 발생하므로 주의 필요
비용을 최대한 정확하게 예측해야 할 경우에는 샘플 결과를 모아 토크나이저로 먼저 계산해보면 됨
성능(추론 능력)
여러 기관에서 제공하는 LLM 모델의 성능 순위 리더 보드를 참조해 성능 비교 가능
- 벤치마크 점수가 높아도 실제 사례에서는 원하는 만큼 성능이 안나올 수 있으니 깊게 신뢰하지는 않는게 좋음
경향성
Claude 모델은 결과를 구어체로 생성하는 경향이 있고, GPT-4 모델은 격식을 갖춘 어느 정도 구조화된 리포트 형태로 생성하는 경향이 있다.
생성 결과의 안전성
LLM API를 사용한다면 API를 제공하는 회사가 폭력적이거나 비윤리적인 답변을 못하게 막는 장치를 제공하는지 확인할 필요
→ OpenAI나 MS Azure는 Moderations API를 제공
API 서버 안전성
새로운 모델이 업데이트되는 초반에는 MS나 구글도 안전성이 급격히 떨어질 수 있다.
LLM API를 사용하면 기본적으로 안정성이 낮을 것을 염두에 두고 문제가 생겼을 때는 여러 번 다시 시도하거나 에러 상황 발생에 잘 대비하는 것이 좋다.
프롬프트 작성 도움받기
LLM에게 도움을 받으면 더 좋은 프롬프트를 만들 수 있다.
프롬프트 초안 생성
프롬프트 예시
유튜브나 블로그의 제목을 다듬는 프롬프트를 만들려고 해. 제목은 다음과 같이 개선을 하는 것이 목적이야.
- --
원문: 스벨트가... 리액트보다 좋다는 놈들이 있는데
개선: 스벨트가 리액트보다 좋다는 사람이 있는데
원문: 웹 포트폴리오에 간지나게 3D 모델을 추가해보자
개선: 웹 포트폴리오에 멋지게 3D 모델을 추가해보자
원문: 제대로 배우는 프롬프트 엔지니어링
개선: 제대로 배우는 프롬프트 엔지니어링
- --
원문을 개선한 제목으로 바꾸는 프롬프트를 만들어줘. 예시의 개선을 모두 할 수 있는 하나의 프롬프트를 만들어줘.
프롬프트 평가 및 개선
해당 프롬프트가 태스크를 잘 수행할 수 있는지 LLM이 잘 이해하고 명령을 수행할 수 있는지를 평가하고 개선해달라고 이야기하자
앞서 작성한 프롬프트 초안을 그대로 사용하고, 원하는 목적에 맞는 프롬프트인지를 확인하고 개선해 달라는 요청을 추가한다.
- --
이 작업을 위해 다음의 프롬프트를 사용하려고 해. 다음의 프롬프트가 목적에 잘 맞는지, 의미는 명확한지,
GPT가 잘 이해하고 명령을 수행할 수 있을지 평가하고 개선해 줘.
프롬프트 다듬기
프롬프트를 다듬을 때는 명확하고 구체적으로 지시문을 작성해야.
앞서 만들었던 프롬프트를 넣은 다음 상세하게 작성한 개선 규칙에 따라 바꿔달라고 이야기한다.
→ 개선된 프롬프트 의 내용과 개선된 프롬프트로 실행한 결과를 확인한 후 개선 규칙을 계속 추가하거나 수정하면서 의도에 맞는 충분한 품질의 결과가 나올 때까지 반복
프롬프트 개선 규칙
- GPT가 보다 정확한 답변을 제공할 수 있도록 주제나 지시를 명확하게 세분화하고 구체적으로 작성하세요.
- GPT가 이해하기 쉬운 단어와 문장 구조를 사용해 주세요. 복잡한 어휘나 전문 용어의 사용은 가능한 한 줄여주세요.
- GPT가 당신의 의도를 정확하게 파악할 수 있도록 간단하고 명확한 언어를 사용하여 작성하세요.
- 객관적이고 균형 잡힌 답변을 얻기 위해 지시를 중립적이고 구체적인 방식으로 제시하세요.
- 충분한 문맥과 명확성을 제공할 만큼의 길이로 프롬프트를 작성하세요. 이전 정보가 다음 질문의 맥락에 중요한 경우 이를 명확하게 전달하세요.
- 혼란이나 집중력의 손실을 방지하기 위해 간결하게 작성하세요.
- 감정적인 측면보다 결과에 초점을 맞추어 사실과 결과에 기반한 지시를 하세요.
- GPT가 보다 정확하고 유용한 답변을 제공하기 위해 주관적인 질문을 피하고 보편적인 질문으로 재구성하십시오.
프롬프트 번역하기
영어에 비해 한국어 성능이 비교적 떨어지고 토큰 수도 상대적으로 많기 때문에 가능하면 영어로 작성하는 편이 이득
다음은 GPT에게 지시할 프롬프트입니다. 프롬프트를 영어로 번역해서 작성해주세요.
프롬프트
"
내용
"
프롬프트를 영어로 작성하되, 고유명사나 한국어로 명시하는 것이 좋은 부분만 한국어로 작성하면 영어 혹은 한국어만으로 작성하는 것보다 좋은 결과를 얻을 수 있다.
환각 줄이기
LLM에서 환각은 모델이 생성한 텍스트가 사실과 다른 내용이나 주어진 정보에 없는 내용, 즉 실제로는 존재하지 않는 정보를 생성하는 것
→ LLM은 어떻게든 적절한 답변을 생성하려고 노력하기 때문에 잠꼬대처럼 상상한 답변도 내놓을 수 있다.
환각을 최소화하는 추가적인 방법
- 제공한 정보를 바탕으로 답변하도록 명시적으로 지시
- 주어진 문서에서 질문의 답과 관련한 내용을 인용하도록 지시. 이때 문서 요약과 함께 제공하면 조금 더 정확한 결과를 얻을 수 있음
- 모른다는 답을 허용하도록 명시
- 프롬프트를 출력할 때 사고와 답변을 분리하여 스스로 생각하게 만듦
- 각각 다른 방법으로 여러 개의 출력을 생성한 후 각각의 답변이 일관성이 있는지 답변하도록 지시 (Self-Consistency)
외부 지식 주입하기
그라운딩과 RAG
그라운딩: LLM에게 검색 등을 통해 문맥에 더 적합한 정보를 제공하거나 계산기 등을 사용해 정확한 계산 결과를 제공하는 방법
→ 환각 현상을 줄이고, 모델 학습에 사용한 데이터 이후에 나오는 최신 정보를 이용한 결과도 생성 가능
RAG(Retrieval-Augmented Generation, 검색 증강 생성): 정보를 검색한 결과를 기반으로 텍스트를 생성하는 방법
임베딩 모델 선택하기
임베딩 모델: 텍스트를 숫자로 바꾸는 머신러닝 모델
임베딩: 숫자의 집합(배열)으로 단어나 문장, 문단같은 텍스트의 조각이 어떤 의미 공간에 있는지를 알려 주는 기술
임베딩 모델의 성능을 비교하는 리더보드도 다양하게 존재
→ 어떤 모델을 선택할지 고민할 때는 RAG를 고려하여 Retrieval 성능을 확인하는 것이 좋음
Retrieval: 모델이 필요한 정보를 검색 엔진이나 데이터베이스로부터 효율적으로 찾아내는 과정
→ 텍스트 조각들을 벡터화한 대량의 자료 뭉치에서 답변에 필요한 정보를 정확히 잘 찾아낼 수 있는지에 대한 성능
리더 보드가 일반적인 성능 테스트 결과라고 해도 자신이 가지고 있는 데이터셋과 잘 맞지 않을수도
→ 실제 사용할 데이터로 사전 테스트를 거친 후 가장 적합한 모델을 선택해야
벡터 DB
벡터 서치를 본격적으로 사용하려면 벡터 DB를 사용하는 것이 일반적
벡터 서치를 위해 사용하는 기본적인 라이브러리들은 벡터 DB에서 찾아온 벡터 값만 보여줄 뿐 그 벡터가 어떤 텍스트와 관련된 것인지는 알려주지 않음
→ 벡터 DB는 벡터 서치를 통해 가장 가까운 벡터를 찾은 다음 그것이 어떤 문서의 벡터인지를 알 수 있도록 문서 제목이나 내용 등의 메타 정보를 함께 반환
벡터 DB가 제공하는 편의 기능
- 메타 데이터와 함께 결과 반환
- 키워드 필터링 등을 이용한 하이브리드 검색
- 실시간 인덱싱을 통한 대규모 벡터 정보 검색
- 다양한 인덱싱 방법 및 검색 알고리즘 제공
- 높은 확장성 및 개발자 편의 기능
벡터 DB로 유명한 서비스
파인콘을 제외하고는 전부 오픈 소스이지만 파인콘이 가장 기능이 다양하고 개발자 경험이 좋아 많이 사용 중
(크로마도 인기가 높아지고 있음)
Pinecone, Chroma, Milvus, Redis, Weaviate, Elasticsearch, Qdrant, PostgreSQL
벡터 DB가 LLM 애플리케이션의 핵심 컴포넌트로 떠오르면서 거의 모든 데이터베이스가 벡터 서치를 지원하기 시작해 점점 더 선택권이 넓어질 것으로 예상
간단한 서비스라면 Chroma를, 본격적인 서비스라면 레퍼런스가 풍부한 Pinecone을, 온프라미스로 직접 구축하고 싶다면 Qdrant(쿼드란트라고 읽음)를 추천
벡터 서치가 계속해서 좋아지고 있지만, 성능이 잘 따라오지 못하는 경우가 종종 있음 → 하이브리드 서치 사용
하이브리드 서치
하이브리드 서치: 검색 정확도를 높이기 위해 키워드 필터링이나 Dense 벡터, Sparse 벡터 등을 조합해 검색하는 방식
Dense 벡터: 대부분의 요소가 0이 아닌 값을 가지는 베터 (’밀집’)
Sparse 벡터: 대부분의 요소가 0이고 소수의 비-0 값만을 가지는 벡터 (’희소’)
전체 문서에서 먼저 키워드 검색으로 일부 문서를 선택한 다음 그 문서들 중에서 벡터 서치를 통해 가장 유사한 문서를 찾는 것
리랭크
1차로 벡터 서치나 키워드 서치 등에서 가져온 결과에서 한 번 더 필터링을 거치는 방법
벡터 서치나 키워드 서치를 통해 가져온 문서를 벡터 서치에 사용한 모델이 아닌 다른 임베딩 모델이나 프롬프트를 사용해 다시 적은 숫자로 추림
→ 다른 임베딩 모델을 사용해 순서를 재정렬하거나, 검색해 온 문서들을 프롬프트에 넣은 다음 이 중에서 사용자가 요청한 내용과 가장 유사한 것을 일부 선택해 재정렬하라고 하는 것
관련 범위가 넓은 다수의 데이터를 먼저 가져온 뒤, 저렴하고 작은 모델을 이용해 관련이 높은 적은 수의 데이터로 추리는 것
→ 비용을 크게 늘리지 않으면서 답변의 정확성을 높일 수 있음
청킹
텍스트를 적절한 길이로 자르는 방법
임베딩 모델에는 최대 토큰 수가 제한되어 있기 때문에 이를 넘는 텍스트는 잘라서 사용해야
→ 텍스트를 여러 개의 작은 부분으로 나누고 각 부분을 독립적으로 임베딩할 수 있게 하면 텍스트의 특징을 더욱 잘 표현하면서 더욱 정교한 검색이나 분석이 가능
오버랩: 텍스트를 나눌 때 각 청크가 일부 공통된 데이터를 포함하도록 하는 기법
슬라이딩: 텍스트를 일정한 길이의 작은 단어 조각으로 순차적으로 이동하며 데이터의 청크를 캡처하는 방법
슬라이딩 윈도우: 슬라이드할 토큰의 길이
'AI' 카테고리의 다른 글
[프롬프트 엔지니어링] 함수 호출, 프롬프트 평가, LLM 보안, Autonomous Agent에 대하여 (1) | 2024.12.29 |
---|---|
[프롬프트 엔지니어링] 프롬프트 엔지니어링 기법들에 대하여 (4) | 2024.11.25 |
[프롬프트 엔지니어링] AI와 LLM에 대하여 (2) | 2024.11.24 |