[AI Engineering] 6. RAG and Agents

2026. 1. 16. 18:08·Reference/AI Engineering

책에서는 RAG랑 Agents 두 가지 패턴을 알려주나, 내용이 너무 길어서 RAG만 스터디에서 발표함.

머리 터지는 줄 알았네.

 

  • ML model 엔지니어링과 동일한 목표: "input에 대한 처리를 위한 필수 정보를 model에게 넘겨주자."
    • 많은 이들이 model이 충분히 긴 context를 수용할 수 있으면 RAG의 시대도 끝날 거라 하지만, RAG는 죽지 않았다.
    • context가 길어질 수록 중간의 내용이 손실되기도 하고, cost와 latency도 문제, 그리고 모든 지식을 model에 학습시킬 수도 없음.
  • Retrieval Mechanism vs. Attention Mechanism
    • Anthropic의 Introducting Contextual Retrieval에서 나온 것처럼, knowlege base가 20만 tokens 미만이라면 그냥 프롬프트에 모두 때려넣는 게 도움이 될 수도 있다. (model이 수용할 수 있다는 전제 하에)
    • Attention is All you need(2017) 논문이 발표된 이후 많은 LLM은 transformer 아키텍처를 갖는데, 어지간하면 얘가 알아서 맥락 파악 잘 함. -> 자세히 들어가면 이게 또 엄청 재밌는 내용.
    • retrieval은 model에 input을 넣기 전에 미리 관련된 문서를 조회하는 과정. -> model을 좀 더 효율적으로 써보자. 
  • RAG는 크게 2개 컴포넌트로 구성됨.
    • retrieval: 외부 메모리 소스로부터 정보를 조회
      • 검색(search)이 조회(retrieval)보다 넓은 개념이지만, 책에서는 동등한 개념으로 취급하고 진행
    • generator: 조회한 정보를 기반으로 응답 생성
    • retriever의 quality가 RAG 성공 여부를 결정하기도 하나, 어느정도 선을 넘어서면 model이 output token 생성하는 게 병목일 수도.
  • sparse vs. dense retrieval
    • sparse retrival
      • 각 dimension이 하나의 token의 의미를 표현 (해석 가능, 나머지 dimension은 모두 0)
        • e.g. ["food", "banana", "slug"] vocabulary가 존재하고, 각각 [0, 1, 2]라는 값을 가지면, [[1, 0, 0], [0, 1, 0], [0, 0, 1]] 벡터로 표현
      • TF-IDF, BM25 같은 retrival가 여기 속하는데, documents가 너무 많으면 dimension이 수조 차원으로 넘어갈 수도 있어서 기업 입장에서는 꺼려지는 부분.
    • dense retrieval
      • 모든 dimension이 함께 token의 의미를 표현 (해석 어려움, 0으로 채워진 dimension 거의 없음)
        • e.g. "banana"라는 단어를 768-dim dense vector로 변환한다고 가정
          => [0.023, -0.156, 0.892, 0.034, -0.567, 0.123, ..., 0.045]
      • aboutness(~에 관한 것)을 포착해야 하는 semantic retrieval 시 사용.
        • e.g. "banana" → [0.82, -0.15, 0.45, ...]
          "apple" → [0.79, -0.12, 0.43, ...] ← 비슷한 과일이라 벡터가 유사
          "car" → [-0.56, 0.88, -0.23, ...] ← 완전 다른 개념이라 벡터가 다름
      • 중요한 점
        • embedding model이 매우 중요함. 비슷한 의미를 갖는 token을 비슷한 위치에 놓이도록 fine-tuning 필요할 수도 (heuristic한 영역) -> embedding model이 바뀌면 모든 데이터를 다시 re-embedding해야 하는 미라클 현상. (사실상 불가능)
        • ANN 해도 documents 수가 너무 많으면 의미 없음. 따라서 nearest-neighbor search 어떻게 할 지도 고민 많이 해야 함.
      • 대표적인 예시 BERT(Bidirectional Encoder Representations from Transformers)
        • MLM(Masked Language Model)로 빈칸 채우기 문제 대량 학습 -> token의 meaning을 학습하고 embedding
    • SPLADE(Sparse Lexical and Expansion) = 학습된 sparse embedding
      • 전통적인 sparse embedding의 정밀함과 dense embedding의 의미적 풍부함을 결합한 고급 embedding ("BERT의 지능 + Sparse의 효율성과 해석 가능성", 쉽게 말해서 BERT 기반인데 출력을 spare vector로 변환하는 것)
      • BERT 같은 사전학습 언어 모델이 단어들 간의 연결을 파악
      • 다른 용어들의 관련성에 가중치를 부여하고, term expansion을 가능하게 -> 원본 텍스트에 없던 관련 용어도 식별이 가능함.
      • Efficient Inverted Indexes for Approximate Retrieval over Learned Sparse Representations(2024)에서 SPLADE는 BM25와 다른 통계적 특성을 가져서, 기존 역색인 최적화가 안 먹힌다고 함. -> "어차피 내적의 대부분은 상위 몇 개 차원이 결정한다"는 사실을 이용해, 클러스터링 + summary vector로 새로운 pruning 전략을 만듦
  • Tokenization
    • 문자 기반 토큰화: 텍스트를 개별 문자로 쪼개어 각 문자를 하나의 토큰으로 취급 (e.g. hello = 5 tokens) -> 비용 & 틀릴 확률 증가
      • LLM은 먼저 나올 토큰 생성하면, 그 다음 나올 토큰을 확률적으로 계산하여 생성하는 로직을 가짐. 그런데 문자 기반 토큰화의 토큰이 많아서, 틀린 토큰을 생성할 가능성 증가.
    • 단어 기반 토큰화: 텍스트를 단어 단위로 분리 (e.g. "hello, world!" -> ["hello", ",", "world", "!"]) -> 단어 사전 관리 비효율, 합성어가 의미를 잃어버릴 수 있음 (e.g. hot dog -> hot, dog)
      • OOV (Out of Vocabulary) 문제: ["고양이", "강아지", "먹다", ...]를 학습했는데, "골든리트리버가 사료를 먹는다"가 입력으로 들어오면, "골든리트리버" 의미 해석 불가
      • 근데 요새는 Vocabulary가 워낙 커서 OOV는 예전만큼 고려하지 않는 추세
    • 모든 단어를 저장하는 사전을 만들면? 한 단어에서 나올 수 있는 모든 형태를 가지고 있어야 하는 공간 낭비
    • n-gram을 사용하면? 텍스트를 n개 단위로 쪼갬. (e.g. if n = 2, "hello" -> ["he", "el", "ll", "lo"]) 
    • 서브 워드 기반 토큰화: 작은 문자쌍의 빈도수를 계산하여, 자주 등장하는 쌍을 하나의 token으로 결합. (e.g. "Machine learning" -> ["Ma", "chine", "learn", "ing"])
      • 합성어도 추론 가능 (e.g. "child" + "ish" -> "childish" = 어린아이같은)
  • Term-based retrieval vs. Embedding-based retrieval
    • Term-based retrieval
      • 정확한 검색(Lexical retrieval)할 때 주로 사용.
      • 문자 그대로 검색하는 lexical retrieval을 사용하면?
        • 단점1: 많은 문서에 해당 terms가 포함되어 있을 가능성 높음 -> context overflow -> solution: TF(term frequency) "term가 문서에 많이 포함되어 있을 수록 관련성이 높을 것"
        • 단점2: 모든 terms가 중요하진 않음. to, for, at 같은 전치사는 제외. -> solution: IDF(inverse document frequency) "term이 모든 문서에 등장한다면 유익한(informative) 정보는 아닐 것이다."
      • TF-IDF = TF * IDF = \( \sum_{i+1}^q (IDF(t_i)  * TF(f_i, D)) \)
        • TF: 연관성, term이 문서에 얼마나 포함? (단순 계산, 불린 빈도, 로그 스케일 빈도, 증가 빈도) -> 무식하게 하면 문서 길이가 길거나, 단순히 단어 반복횟수만 많은 것들이 과하게 유리해지니 여러 수식이 존재함.
        • IDF: 유익성, term이 전체 문서 중 얼마나 포함? (IDF = \( \log \frac{(전체 \; 문서 \; 수)}{(term이 \; 등장하는 \; 문서 \; 수)} \)) -> for, the, at 같은 무의미한 token은 걸러내는 작업.
        • TF-IDF가 높다 = term이 문서에 많이 나오고, 다른 문서에는 많이 안 나옴 = 문서를 특징 지을 수 있는 term
      • 두 가지 term-based retrieval solution이 유명
        • Elasticsearch, Opensearch
        • BM25: TF-IDF 개선 버전 (BM25+, BM25F 같은 변형도 존재)
          • TF-IDF 문제점
            • 문제1: TF가 무한 증가 (e.g. "고양이"가 100번 나오면 더 중요? 일정 횟수를 넘어서면 관련성이 크게 증가하지 않을 것이다.)
            • 문제2: 문서 길이 미고려 (e.g. 100단어 문서에서 고양이 5번 등장 = 1,000단어 문서에서 고양이 등장??)
          • 개선점
            • TF 포화 (Saturation): 포화 구간을 넘어서면 증가량 억제
              • \( \frac{tf(t, d) * (k_1 + 1)}{tf(t,d) + k_1} \)
            • 문서 길이 정규화
              • \( k_1 * (1 - b + b * \frac{문서길이}{평균문서길이}) \)
              • b=0이면 문서 길이 무시, b=1이면 문서 길이 완전 반영(가중치). -> 문서 길이가 짧을 수록 패널티가 적어서 점수 유리
            • k1(TF 포화 정도 조절), b(문서 길이 영향도 조절) parameters tuning 가능
    • Embedding-based retrieval
      • semantic retrieval 중점. 의미론적 유사도
      • token을 embedding model 사용해서 vector 좌표계로 변환 (retrieve할 때도 query를 embedding해야 함.)
        • embedding model이 구리면 노답임.
        • 실제 semantic retrieval system은 `reranker`나 `cache`도 등장할 거임.
        • word2vec: Efficient Estimation of Word Representations in Vector Space(2013)
      • vector database
        • vector 검색을 빠르고 효율적으로 하는 방향으로 인덱싱하고 저장 -> 굳이 vector DB여야 할까? 요샌 많은 DB나 Store들도 vector search 기능 확장하는 경우 많음.
      • A nearest-neighbor search problem
        • 어떻게 K개의 가장 가까운 이웃을 찾을 것인가?
        • brute force (k-NN): query를 임베딩하고, DB의 모든 데이터와 유사도 비교 후 rank를 매겨서 k개를 반환
        • ANN(Approximate Nearest Neighbor): "정확도를 조금 포기하고, 속도를 얻자"
          • LSH(locality-sensitive hashing), HNSW(Hierarchical Navigable Small World), Product Ouantization, IVF(inverted file index), Annoy(Approximate Nearest Neighbors Oh Yeah) 등 -> 너무 많아서 그냥 패스..
        • 벡터 검색 알고리즘들은, 유사한 벡터들이 서로 가까이 위치할 가능성을 높이기 위해 사용하는 휴리스틱에 따라 달라진다.
          • e.g. HNSW는 그래프 기반으로 비슷한 벡터들을 그래프 이웃 노드로 연결, IVF는 클러스트 기반이라 비슷한 벡터들을 같은 클러스터에 묶음, LSH는 해시 기반이라 비슷한 벡터가 같은 bucket에 들어가도록 설계 -> 미리 가까이 모아두는 알고리즘이 heuristic한 부분.
  • RAG System Evaluation
    • retrieval
      • 가장 대표적인 평가 요소
        • Context precision : 찾은 문서 중 query와 관련된 비율
        • Context recall: query와 관련된 모든 문서 중 찾아낸 비율
      • 전체 RAG system이 가진 context 자체를 평가할 수도 있음.
      • latency는 전체 system에서 retriever이 차지하는 비중이 그리 높이 않을 수 있음. 보통 output generation이 길어지는 게 latency에 큰 영향을 미치는 경우가 많음.
      • trade-off: indexing vs. querying
        • 많은 정보 저장 -> query 정확도 증가 & 탐색 시간 감소 but, indexing 시간과 memory 사용량 증가 & storage 용량 증가
        • ANN-Benchmarks에서 Recall, QPS(Query per second), Build time, Index size로 ANN algorithm과 복합 datasets을 평가한 것을 참고.
    • ranking
      • NDCG, MAP, MRR 등
    • embedding
      • embedding만 따로 평가가 가능하고, 특수한 작업에 대해 얼마나 잘 처리하는지 평가 가능 (MTEB)
      • embedding할 문서가 많아질 수록 cost는 높아지고, model이나 vector strage 바꿀 때마다 모두 다 다시 embedding하는 게 부담이 될 수 있다.
    • 최소한 retrieval quality, RAG outputs, (vector 검색 하면)embedding은 평가해라.
  • Combining retrieval algorithms
    • hybrid search = term-based retrieval + embedding-based retrieval
      • 방법1. 순차 실행 -> 보통 이거 씀..병렬 실행의 고질적 문제 때문.
      • 방법2. 병렬 실행
        • RRF (Reciprocal Rank Fusion)로 서로 다른 rank가 매겨진 documents를 결합하여 re-rank할 때 사용함.
        • \(RRF(d) = \sum_{q \in Q}^1 {\frac{1}{k + rank_q(d)}}\)
          • d = 점수를 계산할 문서
          • Q: 쿼리 집합 (또는 검색 시스템 집합)
          • k = 순위 상수 (평활화와 순위 간 차이 조절을 고려해 실험적으로 60으로 설정)
        • 고질적인 문제...term-based retrieval와 embedding-based retrieval 각각 조회해서 RRF를 사용했다 치자, {A, B}문서가 각각 {1, 2}, {2, 1}로 rank가 매겨졌다면 둘은 같은 점수를 받는다. -> term-based retrieval과 embedding-based retrieval 중 무엇이 더 높은 평가를 받아야 하는가? 고려 불가능.
  • Chunking strategy
    • 단순하게 고정 길이 chunk
    • 특정 문서는 창의적으로 chunk해볼 수도? (e.g. Q&A 게시판이면 question - answer 쌍으로 나누고, 각 쌍을 chunk로)
    • overlapping 안 하면 중요 정보 손실 가능성 있음. (e.g. "I left my wife a note"를 ["I left my wife", "a note"]로 분리하면, 두 chunk모두 핵심 정보 전달에 실패한다.)
    • unit을 생성형 model가 사용하는 tokenizer의 token 기준으로 chunk를 나눌 수도 
      • 생성형 model을 바꿀 때, 해당 model이 사용하는 tokenizer 기준으로 모두 다시 reindex해야 하는 단점
    • recursive chunking 전략 -> 나라면 이거 쓸 듯? overlapping 고려하는 것도 일임.
      • e.g. section -> section이 너무 길면 paragraphs -> praragraphs도 너무 길면 sentence
      • 관련된 text의 맥락이 끊길 우려를 줄일 수 있다. (text의 의미 구조를 존중하면서 분할하므로, 한 문장이나 한 단락이 두 chunk로 쪼개질 가능성이 줄어듦.)
    • Anthropic의 Contextual retrieval
      • chunk마다 metadata를 추가 (e.g. 이커머스면 상품 정보, 리뷰 등을 함께 저장, 이미지와 비디오면 제목과 캡션을 함께 저장)
      • 기존 문제점: Traditional RAG의 Context 손실
        • 원본 문서: ""ACME Corp의 2023년 Q2 실적 보고서...(중략)......회사의 매출은 전 분기 대비 3% 성장했다."
        • Tranditional Chunking: "회사의 매출은 전 분기 대비 3% 성장했다."
        • Query: "ACME Corp의 Q2 2023 매출 성장률은?" -> "회사 = ACME corp" 정보가 손실된 상태라 알 수 없음
        • Solution: Chunk에 Context를 Prepend (overlap이나 recursive chunking과는 다르게, Contextual Retrieval은 의미적 맥락을 명시적으로 추가)
  • Reranking
    • 언제 사용? model's context size에 맞추기 위해 retrieved documents 수를 줄여야 할 때, input tokens 수를 줄여야 할 때
    • Context reranking도 있는데 중요도는 떨어짐. 일단 documents가 포함되기만 한다면, 순서의 영향은 search ranking에 비해 덜 중요.
  • query rewriting
    • 사용자 query의 모호함을 해결하고 retrieve해야 함.
      • e.g.
        User: When was the last time John Doe bought something from us?
        AI: John last bought a Fruity Fedora hat from us two weeks ago, on January 3, 2030.
        User: How about Emily Doe?
    • 마지막 질문을 “When was the last time Emily Doe bought something from us?”로 보정해주어야 제대로 검색할 것. (chat context를 기반으로 사용자 의도를 재해석)
    • “How about his wife?” -> wife 정보 탐색 -> 없음 -> 해결 불가능한 지식이라는 정보를 포함 -> 환각 & 잘못된 답변을 방지할 수 있을 것.
  • Multimodal RAG
    • multimodal: 텍스트, 이미지, 오디오, 비디오 등 여러 종류의 데이터(양식/모드)를 함께 이해하고 처리하는 기술
    • query에 매칭되는 image를 조회할 때, image에 metadata를 추가할 수 있음.
    • CLIP(Contrastive Language–Image Pre-training)같은 multimodal embedding model을 사용하여 text와 image를 embedding할 수도 있음.
    • Learning Transferable Visual Models From Natural Language Supervision(2021)
      1. 인터넷에서 4억개 이미지와 해당 이미지에 대한 설명 Text를 pair로 두고 학습데이터셋으로 구성한 후, 각각을 인코더로 임베딩하여 같은 pair에 대해 거리를 가깝게하고 다른 pair에 대해 거리가 멀어지도록 텍스트/이미지 인코더를 학습
      2. 학습된 인코더로 Test 이미지와 Test 텍스트 간의 유사도를 계산
      3. 학습시에는 이미지와 텍스트간의 cosine similiary를 계산하고, 같은 Pair간에는 유사도를 최대화하고 다른 Pair간에는 최소화하도록 Cross Entropy Loss를 사용
  • RAG with rabular data
    • 테이블 조회해야 하면, User Query → [Text-to-SQL] → [SQL Execution] → [Generation] → Response 순서로 이루어져야 할 것
저작자표시 비영리 (새창열림)
'Reference/AI Engineering' 카테고리의 다른 글
  • [AI Engineering] 7. Finetuning
  • [AI Engineering] 5. Prompt Engineering
  • [AI Engineering] 4. Evaluate AI Systems
나죽못고나강뿐
나죽못고나강뿐
싱클레어, 대부분의 사람들이 가는 길은 쉽고, 우리가 가는 길은 어려워요. 우리 함께 이 길을 가봅시다.
  • 나죽못고나강뿐
    코드를 찢다
    나죽못고나강뿐
  • 전체
    오늘
    어제
    • 분류 전체보기 (490)
      • Computer Science (61)
        • Git & Github (4)
        • Network (17)
        • Computer Structure & OS (13)
        • Software Engineering (5)
        • Database (9)
        • Security (5)
        • Concept (8)
      • Frontend (22)
        • React (14)
        • Android (4)
        • iOS (4)
      • Backend (85)
        • Spring Boot & JPA (53)
        • Django REST Framework (14)
        • MySQL (10)
        • Nginx (1)
        • FastAPI (4)
        • kotlin (2)
        • OpenSearch (1)
      • DevOps (24)
        • Docker & Kubernetes (11)
        • Naver Cloud Platform (1)
        • AWS (2)
        • Linux (6)
        • Jenkins (0)
        • GoCD (3)
      • Coding Test (112)
        • Solution (104)
        • Algorithm (7)
        • Data structure (0)
      • Reference (144)
        • Effective-Java (90)
        • Pragmatic Programmer (0)
        • CleanCode (11)
        • Clean Architecture (5)
        • Test-Driven Development (4)
        • Relational Data Modeling No.. (0)
        • Microservice Architecture (2)
        • 알고리즘 문제 해결 전략 (9)
        • Modern Java in Action (0)
        • Spring in Action (0)
        • DDD start (0)
        • Design Pattern (6)
        • 대규모 시스템 설계 (7)
        • JVM 밑바닥까지 파헤치기 (4)
        • The Pragmatic Programmer (1)
        • AI Engineering (4)
        • LLM을 활용한 실전 AI 애플리케이션 개발 (1)
      • Service Planning (2)
      • Side Project (5)
      • AI (1)
      • MATLAB & Math Concept & Pro.. (2)
      • Review (25)
      • Interview (4)
      • IT News (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃
  • 공지사항

    • 요새 하고 있는 것
    • 한동안 포스팅은 어려울 것 같습니다. 🥲
    • N Tech Service 풀스택 신입 개발자가 되었습니다⋯
    • 취업 전 계획 재조정
    • 취업 전까지 공부 계획
  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
나죽못고나강뿐
[AI Engineering] 6. RAG and Agents
상단으로

티스토리툴바