自定义嵌入
LangChain 与许多第三方嵌入模型集成。在本指南中,我们将向您展示如何创建自定义嵌入类,以防现有的内置嵌入类不存在。嵌入在自然语言处理应用中至关重要,因为它们将文本转换为算法可以理解的数值形式,从而实现广泛的应用,例如相似性搜索、文本分类和聚类。
使用标准 Embeddings 接口实现嵌入,将允许您的嵌入在现有的 LangChain
抽象中使用(例如,作为 VectorStore 的嵌入或使用 CacheBackedEmbeddings 进行缓存)。
接口
LangChain 中当前的 Embeddings
抽象旨在处理文本数据。在此实现中,输入可以是单个字符串或字符串列表,输出是数值数组(向量)列表,其中每个向量表示输入文本在某个 n 维空间中的嵌入。
您的自定义嵌入必须实现以下方法
方法/属性 | 描述 | 必需/可选 |
---|---|---|
embed_documents(texts) | 为字符串列表生成嵌入。 | 必需 |
embed_query(text) | 为单个文本查询生成嵌入。 | 必需 |
aembed_documents(texts) | 异步为字符串列表生成嵌入。 | 可选 |
aembed_query(text) | 异步为单个文本查询生成嵌入。 | 可选 |
这些方法确保您的嵌入模型可以无缝集成到 LangChain 框架中,为可扩展性和性能优化提供同步和异步功能。
Embeddings
目前没有实现 Runnable 接口,也不是 pydantic BaseModel
的实例。
嵌入查询与文档
embed_query
和 embed_documents
方法是必需的。这些方法都对字符串输入进行操作。出于遗留原因,Document.page_content
属性的访问由向量存储使用嵌入模型处理。
embed_query
接受一个字符串,并返回一个嵌入,作为浮点数列表。如果您的模型对于嵌入查询与底层文档具有不同的模式,则可以实现此方法来处理这种情况。
embed_documents
接受一个字符串列表,并返回一个嵌入列表,作为浮点数列表的列表。
embed_documents
接受纯文本列表,而不是 LangChain Document
对象列表。此方法的名称可能会在 LangChain 的未来版本中更改。
实现
作为一个例子,我们将实现一个简单的嵌入模型,它返回一个恒定的向量。此模型仅用于说明目的。
from typing import List
from langchain_core.embeddings import Embeddings
class ParrotLinkEmbeddings(Embeddings):
"""ParrotLink embedding model integration.
# TODO: Populate with relevant params.
Key init args — completion params:
model: str
Name of ParrotLink model to use.
See full list of supported init args and their descriptions in the params section.
# TODO: Replace with relevant init params.
Instantiate:
.. code-block:: python
from langchain_parrot_link import ParrotLinkEmbeddings
embed = ParrotLinkEmbeddings(
model="...",
# api_key="...",
# other params...
)
Embed single text:
.. code-block:: python
input_text = "The meaning of life is 42"
embed.embed_query(input_text)
.. code-block:: python
# TODO: Example output.
# TODO: Delete if token-level streaming isn't supported.
Embed multiple text:
.. code-block:: python
input_texts = ["Document 1...", "Document 2..."]
embed.embed_documents(input_texts)
.. code-block:: python
# TODO: Example output.
# TODO: Delete if native async isn't supported.
Async:
.. code-block:: python
await embed.aembed_query(input_text)
# multiple:
# await embed.aembed_documents(input_texts)
.. code-block:: python
# TODO: Example output.
"""
def __init__(self, model: str):
self.model = model
def embed_documents(self, texts: List[str]) -> List[List[float]]:
"""Embed search docs."""
return [[0.5, 0.6, 0.7] for _ in texts]
def embed_query(self, text: str) -> List[float]:
"""Embed query text."""
return self.embed_documents([text])[0]
# optional: add custom async implementations here
# you can also delete these, and the base class will
# use the default implementation, which calls the sync
# version in an async executor:
# async def aembed_documents(self, texts: List[str]) -> List[List[float]]:
# """Asynchronous Embed search docs."""
# ...
# async def aembed_query(self, text: str) -> List[float]:
# """Asynchronous Embed query text."""
# ...
让我们测试一下 🧪
embeddings = ParrotLinkEmbeddings("test-model")
print(embeddings.embed_documents(["Hello", "world"]))
print(embeddings.embed_query("Hello"))
[[0.5, 0.6, 0.7], [0.5, 0.6, 0.7]]
[0.5, 0.6, 0.7]
贡献
我们欢迎将嵌入模型贡献到 LangChain 代码库。
如果您打算为新的提供商(例如,具有一组新的依赖项或 SDK)贡献嵌入模型,我们鼓励您将您的实现发布在单独的 langchain-*
集成包中。这将使您能够适当地管理依赖项并对您的包进行版本控制。请参阅我们的贡献指南,了解此过程的详细步骤。