---
description: Use AI Search from LangChain to create an instance, index content, and search it with the CloudflareAISearchRetriever.
title: LangChain
image: https://developers.cloudflare.com/og-docs.png
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-search/llms.txt  
> Use this file to discover all available pages before exploring further.

# LangChain

Last updated Aug 24, 2026|Copy as Markdown|[View as Markdown](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/ai-search/agent-sdks/langchain/index.md)|[Agent setup](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/agent-setup/)

[LangChain ↗](https://python.langchain.com/) is a framework for building applications with large language models. The [langchain-cloudflare ↗](https://pypi.org/project/langchain-cloudflare/) package provides `CloudflareAISearchRetriever`, a standard LangChain retriever backed by AI Search.

The retriever only searches. To create an instance and upload content, pair it with the [Cloudflare Python SDK ↗](https://github.com/cloudflare/cloudflare-python). This guide uses the Python SDK to create an AI Search instance with hybrid search enabled and index a file, then uses the LangChain retriever to search it as a tool.

## Prerequisites

* [Python ↗](https://www.python.org/downloads/) 3.10 or later
* Your [account ID](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/)
* An API token with both the **AI Search:Edit** and **AI Search:Run** permissions

To create the token, follow [Create an API token](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/ai-search/get-started/api/#1-create-an-api-token) and add both permissions. **Edit** provisions the instance and uploads files; **Run** performs the search.

## 1\. Install the packages

Create a project directory and a virtual environment to isolate your dependencies.

```sh
mkdir ai-search-langchain && cd ai-search-langchain
python3 -m venv .venv
source .venv/bin/activate
```

On Windows, activate the virtual environment with `.venv\Scripts\activate` instead.

Install both packages:

```sh
pip install -U langchain-cloudflare cloudflare
```

The `cloudflare` SDK creates the instance and uploads files. The `langchain-cloudflare` package provides the retriever and the RAG and agent-tool helpers. Installing `langchain-cloudflare` also installs `langchain-core`, so you do not need to install `langchain` separately.

## 2\. Set your credentials

Export your account ID and API token. The Cloudflare SDK reads these automatically.

```sh
export CLOUDFLARE_ACCOUNT_ID="<ACCOUNT_ID>"
export CLOUDFLARE_API_TOKEN="<API_TOKEN>"
```

## 3\. Create an instance with hybrid search

Create a file named `main.py`. The following code creates an instance with [hybrid search](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/ai-search/configuration/indexing/hybrid-search/) enabled by setting `index_method` to index both vectors and keywords. Because no data source is connected, the instance uses [built-in storage](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/ai-search/configuration/data-source/built-in-storage/).

Creating an instance that already exists fails, so the code checks for it first and creates it only if it is missing.

```python
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}'.")
```

The first positional argument to `create()` is the namespace name. If you created a vector-only instance earlier, enable hybrid search on it with `client.aisearch.namespaces.instances.update(...)` instead.

## 4\. Upload and index a file

Add the following to `main.py` to upload a document to built-in storage. Setting `wait_for_completion` to `True` inside the `file` argument waits until the file is indexed before returning.

```python
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}).")
```

If indexing is still finishing, `item.status` may be `running`; the file continues indexing in the background and becomes searchable shortly after.

## 5\. Query your instance

There are three ways to use your instance from LangChain. Pick the one that fits your application:

* [Search directly](#search-directly) returns the matching documents.
* [Use AI Search as an agent tool](#use-ai-search-as-an-agent-tool) gives an agent the ability to search your content.
* [Build a RAG chain](#build-a-rag-chain) generates an answer from the retrieved documents.

All three use the same `CloudflareAISearchRetriever`, which the first option creates.

### Search directly

Point a `CloudflareAISearchRetriever` at the instance. Set `retrieval_type` to `hybrid` to use the vector and keyword indexes you enabled.

```python
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)
```

The `k` parameter sets the maximum number of results, mapped to `max_num_results` and capped at 50.

### Use AI Search as an agent tool

Wrap the retriever with `create_retriever_tool` to give an agent the ability to search your content. This is the recommended way to use AI Search from a LangChain agent.

```python
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` is a standard LangChain tool. Pass it to any LangChain or LangGraph agent alongside your other tools.

### Build a RAG chain

To answer questions from the retrieved content, combine the retriever with a model. This example uses `ChatCloudflareWorkersAI`, which is included in the same package. Pass your account ID and token the same way you did for the retriever.

Because this option calls [Workers AI](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/workers-ai/) to generate the answer, the token you pass here also needs the **Workers AI** permission. Add it to the token you already created, or pass a separate token.

```python
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?"))
```

## Use inside a Python Worker

Inside a [Python Worker](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/workers/languages/python/), pass a Worker binding instead of REST credentials. The binding path is asynchronous, so use `ainvoke`.

```python
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` is a dedicated `ai_search` binding, not the Workers AI binding (`self.env.AI`). For a [namespace binding](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/ai-search/concepts/namespaces/), pass `self.env.<NAMESPACE>.get("my-instance")`.

## Next steps

### [Hybrid search](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/ai-search/configuration/indexing/hybrid-search/)

Combine vector and keyword search with configurable fusion.

### [Python SDK quickstart](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/ai-search/get-started/python/)

Create and manage AI Search instances from Python.

### [Retrieval configuration](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/ai-search/configuration/retrieval/)

Tune filtering, reranking, query rewriting, and caching.

Was this helpful?

YesNo

## On this page

[![](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/ai-search/agent-sdks/langchain/#page","headline":"LangChain · Cloudflare AI Search docs","description":"Use AI Search from LangChain to create an instance, index content, and search it with the CloudflareAISearchRetriever.","url":"https://developers.cloudflare.com/ai-search/agent-sdks/langchain/","inLanguage":"en","image":"https://developers.cloudflare.com/og-docs.png","dateModified":"2026-08-24","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```
