TL;DR LangChain v0.1.5의 Milvus 회귀

Feb 13, 20243 min read

LangChain 0.1.5와 Milvus 통합을 수정하기 위한 PR이 제출되었습니다: https://github.com/langchain-ai/langchain/pull/17021

문제

Langchain v0.1.5를 사용하여 Milvus에 연결할 때 "KeyError: 'pk'" 오류가 발생합니다. 이 오류는 최근 Milvus 회귀로 인해 "pk" 필드(기본 키) 값이 자동으로 생성되지 않기 때문에 발생합니다. Milvus는 각 문서에 기본 키 필드를 요구하지만, LangChain 텍스트 스플리터에는 해당 필드가 포함되어 있지 않으므로 Milvus insert() 메서드는 "KeyError: 'pk'"가 누락되었다는 오류를 발생시킵니다.

임시 해결책(다운그레이드):

수정 사항이 공식적으로 병합될 때까지 Langchain 버전을 <= v0.1.4로 다운그레이드하세요.

영구 해결책(수정):

insert() 중에 "pk"가 없는 경우를 처리하도록 Langchain-Milvus 통합을 업데이트할 공식 수정 사항을 기다리세요.

기술적 세부 사항:

  • Milvus는 각 문서에 기본 키 필드를 요구합니다.

  • LangChain의 "MilvusVectorstore" 스키마는 "pk" 필드를 기본 키로 사용합니다.

  • LangChain의 text_splitter.split_documents()는 기본적으로 "pk" 필드를 추가하지 않습니다.

  • LangChain v0.1.5 및 Milvus와 함께 기본 LangChain 체인을 사용하면 Milvus insert() 메서드 호출 중에 "pk"를 찾을 수 없다는 오류가 발생합니다.

  • Langchain <= v0.1.4로 다운그레이드하면 일시적으로 충돌을 피할 수 있습니다.

  • Langchain v0.1.5의 예정된 수정 사항은 이 문제를 영구적으로 해결할 것입니다.

배경:

최근 Milvus는 LangChain v0.1.5와의 통합에서 회귀를 도입했으며, 이로 인해 기본값 = "False"인 MilvusVectorstore의 새 매개변수 "auto_id"가 추가되었습니다. auto_id가 False이므로 사용자는 insert() 메서드를 호출할 때마다 기본 키 값을 제공해야 합니다. LangChain에서 기본 스키마는 "pk"를 기본 키로 정의하지만, text_splitter.split_documents()에서 생성된 문서에는 삽입에 필요한 "pk" 필드가 없습니다.

수정 PR이 병합될 때까지 langchain 버전을 <=v0.1.4로 다운그레이드하여 충돌을 일시적으로 피할 수 있습니다.

Langchain v0.1.5의 예정된 수정 사항은 이 문제를 영구적으로 해결하여 삽입할 데이터에서 "pk" 필드를 찾을 수 없는 경우 해당 필드가 자동으로 생성되도록 보장할 것입니다.

수정 전까지 Langchain >= 0.1.5에서는 다음과 같은 오류가 표시될 수 있습니다:

File "/Library/Python/3.9/site-packages/langchain_community/vectorstores/milvus.py", line 586, in <listcomp> insert_list = [insert_dict[x][i:end] for x in self.fields] KeyError: 'pk'

아래 코드 샘플은 Langchain이 텍스트 문서 임베딩 및 저장을 위해 Milvus와 상호 작용하는 방법을 보여줍니다:

# Load text data
loader = TextLoader("result.txt")
documents = loader.load()

# Split documents into chunks
text_splitter = CharacterTextSplitter(chunk_size=1024, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

# Create embeddings
embeddings = HuggingFaceEmbeddings()

# Connect to Milvus
connection_args = {
    'uri': ZILLIZ_CLOUD_URI,
    'token': ZILLIZ_CLOUD_API_KEY
}
vector_db = Milvus(
    embedding_function=embeddings,
    connection_args=connection_args,
    collection_name='abc',
).from_documents(
    docs,
    embedding=embeddings,
    collection_name='abc',
    connection_args=connection_args,
)

# LangChain v0.1.5 code will fail before reaching this step.
# Perform a similarity search
query = "test"
docs2 = vector_db.similarity_search(query)

추가 참고 사항:

LangChain의 Milvus.from_documents() 메서드는 두 가지 작업을 수행합니다:

  1. 임베딩 메서드를 호출하여 텍스트를 임베딩으로 변환합니다.

  2. Milvus collection.insert() 메서드를 호출하여 문서의 pk, vector 및 metadata 필드를 포함한 데이터를 milvus에 삽입합니다.

Milvus.from_documents()는 Langchain의 VectorStore 클래스의 메서드입니다: https://github.com/langchain-ai/langchain/blob/22d90800c86799a3a385b73ba09608c9b6565e0a/libs/core/langchain_core/vectorstores.py#L499

class VectorStore(ABC):
  def from_documents(
        cls: Type[VST],
        documents: List[Document],
        embedding: Embeddings,
        **kwargs: Any,
    ) 

모든 벡터 데이터베이스 어댑터(Milvus 포함)는 이 클래스에서 파생되며 이 메서드를 구현합니다.

"Embeddings"는 임베딩 모델의 인터페이스를 통합하기 위한 추상 클래스입니다: https://github.com/langchain-ai/langchain/blob/master/libs/core/langchain_core/embeddings.py

class Embeddings(ABC):
    """Interface for embedding models."""

    @abstractmethod
    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        """Embed search docs."""

    @abstractmethod
    def embed_query(self, text: str) -> List[float]:
        """Embed query text.""" 

사용자 지정 임베딩 모델을 래핑하려면, 이 두 메서드를 구현하는 클래스를 선언할 수 있습니다.

Milvus LangChain 통합에 대한 더 많은 글 읽기:

https://milvus.io/docs/integrate_with_langchain.md

Jul 09, 2026에 업데이트됨