← Обзор / ai-search / agent-sdks
LangChain
LangChain ↗ представляет собой фреймворк для создания приложений с большими языковыми моделями. langchain-cloudflare ↗ пакет предоставляет CloudflareAISearchRetriever, стандартный retriever LangChain на основе AI Search.
Ретривер только выполняет поиск. Чтобы создать экземпляр и загрузить в него контент, используйте его вместе с Cloudflare Python SDK ↗. В этом руководстве с помощью Python SDK создаётся экземпляр AI Search с включённым гибридным поиском и индексируется файл, а затем для поиска по нему в качестве инструмента используется ретривер LangChain.
Предварительные требования
- Python ↗ 3.10 или новее
- Ваш ID аккаунта
- Токен API с обоими AI Search:Edit и AI Search:Run разрешения
Чтобы создать токен, следуйте Создание API-токена и добавьте оба разрешения. Изменить подготавливает экземпляр и загружает файлы; Запуск выполняет поиск.
1. Установите пакеты
Создайте каталог проекта и виртуальное окружение, чтобы изолировать зависимости.
mkdir ai-search-langchain && cd ai-search-langchain
python3 -m venv .venv
source .venv/bin/activateВ Windows активируйте виртуальное окружение с помощью .venv\Scripts\activate взамен.
Установите оба пакета:
pip install -U langchain-cloudflare cloudflare cloudflare SDK создаёт экземпляр и загружает файлы. langchain-cloudflare пакет предоставляет retriever и вспомогательные функции для RAG и агентных инструментов. Установка langchain-cloudflare также устанавливает langchain-core, поэтому вам не нужно устанавливать langchain отдельно.
2. Настройте учётные данные
Экспортируйте идентификатор аккаунта и токен API. Cloudflare SDK считывает их автоматически.
export CLOUDFLARE_ACCOUNT_ID="<ACCOUNT_ID>"
export CLOUDFLARE_API_TOKEN="<API_TOKEN>"3. Создайте экземпляр с гибридным поиском
Создайте файл с именем main.py. Следующий код создаёт экземпляр с гибридный поиск включается при установке index_method для индексирования как векторов, так и ключевых слов. Поскольку источник данных не подключён, инстанс использует встроенное хранилище.
Создание экземпляра, который уже существует, завершается ошибкой, поэтому код сначала проверяет его наличие и создаёт экземпляр, только если он отсутствует.
import os
from cloudflare import Cloudflare, NotFoundError
ACCOUNT_ID = os.environ["CLOUDFLARE_ACCOUNT_ID"]
API_TOKEN = os.environ["CLOUDFLARE_API_TOKEN"]
NAMESPACE = "default"
INSTANCE_ID = "knowledge-base"
# The SDK authenticates with this token; the account ID is passed on each call.
client = Cloudflare(api_token=API_TOKEN)
# create() fails if the instance already exists, so check for it with read()
# first and only create it when read() raises NotFoundError.
try:
client.aisearch.namespaces.instances.read(
INSTANCE_ID, account_id=ACCOUNT_ID, name=NAMESPACE
)
print(f"Instance '{INSTANCE_ID}' already exists.")
except NotFoundError:
client.aisearch.namespaces.instances.create(
name=NAMESPACE,
account_id=ACCOUNT_ID,
id=INSTANCE_ID,
# Index both vectors and keywords to enable hybrid search.
index_method={"vector": True, "keyword": True},
)
print(f"Created instance '{INSTANCE_ID}'.")Первый позиционный аргумент для create() это имя пространства имён. Если вы ранее создали чисто векторный экземпляр, включите на нём гибридный поиск с помощью client.aisearch.namespaces.instances.update(...) взамен.
4. Загрузите и проиндексируйте файл
Добавьте следующее в main.py для загрузки документа во встроенное хранилище. Настройка wait_for_completion к True внутри file ждёт завершения индексирования файла и только потом возвращает результат.
item = client.aisearch.namespaces.instances.items.upload(
id=INSTANCE_ID,
account_id=ACCOUNT_ID,
name=NAMESPACE,
file={
# (filename, file bytes, content type)
"file": (
"workers-ai.md",
b"To configure Workers AI, add an [ai] binding and call env.AI.run().",
"text/markdown",
),
# Block until indexing finishes so the file is searchable right away.
"wait_for_completion": True,
},
)
print(f"Uploaded '{item.key}' (status: {item.status}).")Если индексация ещё не завершена, item.status может быть running; файл продолжает индексироваться в фоновом режиме и вскоре становится доступным для поиска.
5. Запросите свой экземпляр
Использовать экземпляр в LangChain можно тремя способами. Выберите тот, который подходит вашему приложению:
- Поиск напрямую возвращает соответствующие документы.
- Использование AI Search в качестве инструмента агента даёт агенту возможность искать по вашему содержимому.
- Создайте цепочку RAG формирует ответ на основе найденных документов.
Все три используют один и тот же CloudflareAISearchRetriever, который создаёт первый вариант.
Поиск напрямую
Направьте CloudflareAISearchRetriever на уровне экземпляра. Задайте retrieval_type к hybrid для использования векторного индекса и индекса по ключевым словам, которые вы включили.
from langchain_cloudflare import CloudflareAISearchRetriever
retriever = CloudflareAISearchRetriever(
account_id=ACCOUNT_ID,
api_token=API_TOKEN,
instance_name=INSTANCE_ID,
namespace=NAMESPACE,
retrieval_type="hybrid", # query both the vector and keyword indexes
k=5, # maximum number of results to return (capped at 50)
)
# invoke() runs a search and returns standard LangChain Documents.
docs = retriever.invoke("How do I configure Workers AI?")
for doc in docs:
# Each document carries its relevance score and source filename in metadata.
print(doc.metadata["score"], doc.metadata["filename"])
print(doc.page_content) k параметр задаёт максимальное количество результатов и соответствует max_num_results и ограничено 50.
Использование AI Search в качестве инструмента агента
Оберните retriever с помощью create_retriever_tool и таким образом дать агенту возможность искать по вашему содержимому. Это рекомендуемый способ использования AI Search из агента LangChain.
from langchain_core.tools import create_retriever_tool
# create_retriever_tool wraps the retriever as a standard LangChain tool. The
# name and description are what the agent's model sees when deciding to call it.
search_tool = create_retriever_tool(
retriever,
name="cloudflare_ai_search",
description="Search the knowledge base for relevant passages.",
)
print(search_tool.invoke({"query": "How do I configure Workers AI?"}))search_tool является стандартным инструментом LangChain. Передайте его любому агенту LangChain или LangGraph вместе с остальными инструментами.
Создайте цепочку RAG
Чтобы отвечать на вопросы по найденному контенту, объедините ретривер с моделью. В этом примере используется ChatCloudflareWorkersAI, который входит в тот же пакет. Передайте ID аккаунта и токен так же, как для ретривера.
Поскольку эта опция вызывает Workers AI для генерации ответа, поэтому переданный здесь токен также должен иметь разрешение Workers AI разрешение. Добавьте его в токен, который вы уже создали, или передайте отдельный токен.
from langchain_cloudflare import ChatCloudflareWorkersAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
llm = ChatCloudflareWorkersAI(
account_id=ACCOUNT_ID,
api_token=API_TOKEN,
model="@cf/zai-org/glm-5.2",
)
prompt = ChatPromptTemplate.from_template(
"Answer the question using only the context below.\n\n"
"Context:\n{context}\n\n"
"Question: {question}"
)
# Join the retrieved documents into a single context string for the prompt.
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
# LCEL chain: retrieve context and pass the question through, fill the prompt,
# call the model, then parse the response down to a plain string.
chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
print(chain.invoke("How do I configure Workers AI?"))Использовать внутри Python Worker
Внутри Python Worker, передайте привязку Worker вместо учётных данных REST API. Путь через привязку асинхронный, поэтому используйте ainvoke.
from workers import WorkerEntrypoint, Response
from langchain_cloudflare import CloudflareAISearchRetriever
class Default(WorkerEntrypoint):
async def fetch(self, request):
# Pass a Worker binding instead of REST credentials.
retriever = CloudflareAISearchRetriever(binding=self.env.MY_SEARCH)
# The binding path is asynchronous, so use ainvoke.
docs = await retriever.ainvoke("How do I configure Workers AI?")
return Response.json({"matches": [doc.page_content for doc in docs]})self.env.MY_SEARCH представляет собой выделенный ai_search привязку, а не привязку Workers AI (self.env.AI). Для привязка пространства имён, передайте self.env.<NAMESPACE>.get("my-instance").