RAG 및 검색을 위한 텍스트 임베딩 - Python, Ollama, OpenAI 호환 API

RAG 임베딩 - Python, Ollama, OpenAI API.

Page content

검색 증강 생성 (RAG)을 공부 중이시라면, 이 섹션에서는 텍스트 임베딩이 무엇인지, 검색 및 검색 (retrieval) 과 어떻게 연관되는지, 그리고 Ollama 또는 OpenAI 호환 HTTP API(많은 llama.cpp 기반 서버에서 제공하는 방식) 를 사용하여 Python에서 두 가지 일반적인 로컬 설정을 호출하는 방법을 쉽게 설명합니다.

Text embeddings and retrieval

Go 클라이언트 및 Ollama SDK 비교에 대해서는 Go SDKs for Ollama — comparison with examples을 참조하세요.

텍스트 임베딩이란 무엇인가요?

텍스트 임베딩임베딩 모델이 생성하는 벡터 (실수 리스트) 입니다. 이 모델은 가변 길이의 텍스트를 고정 차원 공간으로 매핑하여, 의미적으로 유사한 텍스트들이 거리 또는 유사도 측정 (일반적으로 L2 정규화 벡터에 대한 코사인 유사도) 하에서 서로 가까이 위치하도록 합니다.

임베딩은 토큰 ID 와 동일하지 않으며 채팅 완성 (chat completion) 과도 동일하지 않습니다. 이는 검색, 군집화, 중복 제거 및 RAG 에서의 검색을 위해 사용하는 표현 레이어입니다.

일반적인 사용 사례

사용 사례 임베딩의 역할
의미 기반 검색 / RAG 검색 쿼리와 문서 청크를 임베딩한 후 유사도에 따라 순위를 매겨 관련 패시지를 가져옵니다.
임베딩 모델 기반 재순위화 (Reranking) 쿼리와 각 후보를 임베딩한 후 유사도로 쌍을 점수화합니다 (참고: 임베딩 모델 기반 재순위화).
군집화 및 중복 제거 모든 예시를 수동으로 라벨링하지 않고도 임베딩 공간에서 항목을 그룹화하거나 중복을 제거합니다.
분류 스타일 점수 부여 같은 공간 내에서 텍스트를 프로토타입 설명 또는 클래스 이름과 비교합니다 (모델에 따라 패턴이 다름).

멀티모달 설정 (이미지 - 텍스트 및 관련 개념) 에 대해서는 크로스 모달 임베딩을 참조하세요.

RAG 파이프라인 내부의 임베딩

일반적인 오프라인 경로는 다음과 같습니다:

  1. 문서를 청크화합니다 (크기, 겹침, 구조가 중요합니다 — RAG 의 청킹 전략 참조).
  2. 각 청크를 임베딩하고, 선택적으로 메타데이터 (출처 ID, 섹션, ACL) 를 저장합니다.
  3. 벡터를 메모리, 라이브러리 인덱스 또는 벡터 데이터베이스인덱싱합니다 (트레이드오프는 RAG 용 벡터 저장소 비교) 에서 확인 가능).

쿼리 시점:

  1. 사용자 쿼리를 임베딩합니다 (짧은 문자열 하나 또는 작은 배치).
  2. 벡터 검색을 통해 상위 k 개의 유사한 청크를 검색합니다 (선택적으로 키워드/하이브리드 검색 포함).
  3. 검색된 일반 텍스트 청크로 프롬프트를 구성하고 채팅 모델을 호출합니다.

중요한 뉘앙스 — 채팅 API 의 대형 언어 모델은 임의의 임베딩 텐서가 아니라 텍스트 (및 도구) 를 소비합니다. 임베딩은 주입할 텍스트를 선택하는 데 사용됩니다. “미리 계산된 임베딩으로 LLM 에 쿼리한다"는 표현을 보게 되면, 실제로는 임베딩으로 검색한 후 선택된 텍스트를 LLM 으로 전송한다는 의미입니다.

Ollama 를 사용하여 임베딩 가져오기 (Python)

Ollama 는 HTTP API 를 노출합니다. 임베딩을 호출하려면 Ollama 호스트 (기본 http://127.0.0.1:11434) 에서 **POST /api/embed**을 호출하세요. JSON 본문에는 model 이름과 input(문자열 또는 문자열 리스트) 이 포함됩니다. 응답에는 입력과 정렬된 벡터 리스트인 **embeddings**가 포함됩니다.

httpx 를 설치하거나 (**requests**를 같은 방식으로 사용) 하세요.

import httpx

OLLAMA = "http://127.0.0.1:11434"
MODEL = "nomic-embed-text"  # pull 한 임베딩 모델로 교체

def embed_ollama(texts: list[str]) -> list[list[float]]:
    r = httpx.post(
        f"{OLLAMA}/api/embed",
        json={"model": MODEL, "input": texts},
        timeout=120.0,
    )
    r.raise_for_status()
    data = r.json()
    return data["embeddings"]

if __name__ == "__main__":
    q = "What is retrieval-augmented generation?"
    chunks = [
        "RAG combines retrieval with generation.",
        "Embeddings map text into vector space for similarity search.",
    ]
    qv = embed_ollama([q])[0]
    doc_vs = embed_ollama(chunks)
    print(len(qv), len(doc_vs), len(doc_vs[0]))

운영 노트

OpenAI 호환 서버를 사용하여 임베딩 가져오기 (Python)

많은 로컬 서버 (일반적인 llama.cpp HTTP 설정 포함) 는 OpenAI 호환 루트인 POST /v1/embeddings 등을 노출합니다. 공식 openai Python 패키지를 사용하고 **base_url**을 서버의 …/v1 루트로 설정할 수 있습니다.

from openai import OpenAI

# 예시 — 호스트, 포트, 모델 ID 를 서버 값으로 교체
client = OpenAI(
    base_url="http://127.0.0.1:8080/v1",
    api_key="not-needed",  # 많은 로컬 서버는 이를 무시함
)

def embed_openai_compatible(text: str, model: str) -> list[float]:
    r = client.embeddings.create(model=model, input=text)
    return r.data[0].embedding

if __name__ == "__main__":
    v = embed_openai_compatible("hello from llama.cpp", "your-embedding-model-id")
    print(len(v))

왜 두 가지 패턴을 하나의 페이지에 보관해야 하나요? 개념 (청크, 임베딩, 인덱싱, 쿼리, 텍스트 검색) 은 동일하며, 오직 HTTP 표면만 다릅니다. 워크숍 스타일의 기사는 두 URL 아래에서 동일한 서술을 중복하지 않도록 합니다.

벡터 저장 및 쿼리

최소한 각 청크마다 세 가지를 저장해야 합니다 — 벡터, 텍스트, 메타데이터 (출처 ID, 오프셋, ACL). 빠른 프로토타입을 위해 모든 것을 Python 리스트에 보관하고 NumPy 또는 scikit-learn을 사용하여 코사인 유사도를 사용할 수 있습니다. 성장하는 데이터의 경우 벡터 데이터베이스 또는 라이브러리 인덱스(FAISS 등) 를 사용하세요 — 제품 수준의 트레이드오프는 RAG 용 벡터 저장소 비교를 참조하세요.

개념적 쿼리 루프:

  1. query_vec = embed(query)
  2. neighbors = index.search(query_vec, k)
  3. context = "\n\n".join(chunk.text for chunk in neighbors)
  4. context 와 사용자 질문을 채팅 API 로 전송합니다.

검색 후 재순위화 (Reranking)

리랭커(일반적으로 크로스 인코더 또는 두 번째 스코어링 모델) 는 벡터 검색 후 상위 후보의 순서를 다시 정렬할 수 있습니다. 이 사이트에는 임베딩 모델 기반 재순위화Ollama 와 Qwen3 임베딩을 사용한 Go 재순위화를 포함한 PythonGo 예제가 있습니다.

이 사이트의 관련 글

주제
전체 RAG 아키텍처 RAG 튜토리얼 — 아키텍처, 구현, 프로덕션
임베딩 전 청킹 RAG 의 청킹 전략
벡터 DB 선택 RAG 용 벡터 저장소 비교
Ollama 의 Qwen3 Ollama 의 Qwen3 임베딩 및 리랭커
크로스 모달 크로스 모달 임베딩
Ollama CLI 및 팁 Ollama 치트시트
Go + Ollama Go 에서 Ollama 사용 — SDK 비교

유용한 링크