以编程方式使用文档

语义搜索让你的代理能够通过含义而非精确措辞来回忆存储的记忆和文档。例如,搜索"UI偏好"可以找到一条写为"用户偏好深色界面"的记忆。本指南向你展示如何为部署的跨线程 存储 启用语义搜索,这样你的代理就能在对话之间保留上下文,并根据先前的交互个性化响应。

前提条件

步骤

  1. 更新你的 langgraph.json 配置文件 以包含存储配置:
    {
        ...
        "store": {
            "index": {
                "embed": "openai:text-embedding-3-small",
                "dims": 1536,
                "fields": ["$"]
            }
        }
    }
    

此配置:

  • - 使用OpenAI的text-embedding-3-small模型生成嵌入。
  • - 将嵌入维度设置为1536(与模型输出匹配)。
  • - 为存储数据中的所有字段建立索引(["$"] 表示索引所有内容,或指定特定字段如 ["text", "metadata.title"]).

  1. 要使用字符串嵌入格式,请确保你的依赖项包含 langchain >= 0.3.8:
    # In pyproject.toml
    [project]
    dependencies = [
        "langchain>=0.3.8"
    ]
    

或者,如果使用 requirements.txt:

    langchain>=0.3.8
    

用法

配置完成后,你可以在你的 节点中使用语义搜索。存储需要一个命名空间元组来组织记忆:

async def search_memory(state: State, *, store: BaseStore):
    # Search the store using semantic similarity
    # The namespace tuple helps organize different types of memories
    # e.g., ("user_facts", "preferences") or ("conversation", "summaries")
    results = await store.asearch(
        namespace=("memory", "facts"),  # Organize memories by type
        query="your search query",
        limit=3  # number of results to return
    )
    return results

每个结果都是一个 SearchItem (继承自 Item 并带有额外的 score 字段)。配置语义搜索后, score 包含相似度分数:

results[0].key       # "07e0caf4-1631-47b7-b15f-65515d4c1843"
results[0].value     # {"text": "User prefers dark mode"}
results[0].namespace # ("memory", "facts")
results[0].score     # 0.92 (similarity score, present when semantic search is configured)

更改你的嵌入模型

自定义嵌入

如果你想使用自定义嵌入,可以传递自定义嵌入函数的路径:

{
    ...
    "store": {
        "index": {
            "embed": "path/to/embedding_function.py:embed",
            "dims": 1536,
            "fields": ["$"]
        }
    }
}

部署会在指定路径中查找函数。该函数必须是异步的并接受字符串列表:

# path/to/embedding_function.py
from openai import AsyncOpenAI

client = AsyncOpenAI()

async def aembed_texts(texts: list[str]) -> list[list[float]]:
    """Custom embedding function that must:
    1. Be async
    2. Accept a list of strings
    3. Return a list of float arrays (embeddings)
    """
    response = await client.embeddings.create(
        model="text-embedding-3-small",
        input=texts
    )
    return [e.embedding for e in response.data]

通过API查询

你也可以使用 LangGraph SDK查询存储。由于SDK使用异步操作:

from langgraph_sdk import get_client

async def search_store():
    client = get_client()
    results = await client.store.search_items(
        ("memory", "facts"),
        query="your search query",
        limit=3  # number of results to return
    )
    return results

# Use in an async context
results = await search_store()

配置语义搜索后,每个结果项都包含一个 score 字段:

results["items"][0]["key"]       # "07e0caf4-1631-47b7-b15f-65515d4c1843"
results["items"][0]["value"]     # {"text": "User prefers dark mode"}
results["items"][0]["namespace"] # ["memory", "facts"]
results["items"][0]["score"]     # 0.92 (similarity score)