> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trycaesar.com/llms.txt
> Use this file to discover all available pages before exploring further.

# LangChain

> Wrap Caesar's Python or TypeScript client as LangChain tools for search and document reading.

Install Caesar beside the framework packages your agent already uses:

<CodeGroup>
  ```bash Python theme={"system"}
  pip install caesar-search langchain-core
  ```

  ```bash TypeScript theme={"system"}
  npm install caesar-search @langchain/core zod
  ```
</CodeGroup>

## Python tools

```python theme={"system"}
from typing import Any

from caesar_search import Caesar
from langchain_core.tools import tool

client = Caesar()  # reads CAESAR_API_KEY


@tool
def web_search(query: str, max_results: int = 5) -> dict[str, Any]:
    """Search the web with Caesar and return compact, citable results."""
    response = client.search(query, max_results=max_results, verbosity="compact")
    return {
        "search_id": response.search_id,
        "results": [
            {
                "rank": result.rank,
                "title": result.title,
                "url": result.canonical_url,
                "doc_id": result.doc_id,
                "snippet": result.snippet,
            }
            for result in response.results or []
        ],
    }


@tool
def web_fetch(target: str, query: str | None = None, max_chars: int | None = None) -> dict[str, Any]:
    """Read a Caesar doc_id or URL as clean markdown."""
    response = client.read(target, query=query, max_chars=max_chars)
    return {
        "doc_id": response.doc.doc_id,
        "url": response.doc.canonical_url,
        "title": response.doc.title,
        "content": response.content.text if response.content else "",
        "truncated": response.content.truncated if response.content else False,
    }


tools = [web_search, web_fetch]
```

Pass `tools` into your agent or graph the same way you pass any other framework tool. Keep search and read separate: the first tool finds candidates cheaply, the second spends context only on the document the agent chooses.

## TypeScript tools

```ts theme={"system"}
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { Caesar } from "caesar-search";

const caesar = new Caesar(); // reads CAESAR_API_KEY

export const caesarSearch = tool(
  async ({ query, max_results }) => {
    const response = await caesar.search(query, {
      maxResults: max_results ?? 5,
      verbosity: "compact",
    });

    return {
      search_id: response.search_id,
      results: (response.results ?? []).map((result) => ({
        rank: result.rank,
        title: result.title,
        url: result.canonical_url,
        doc_id: result.doc_id,
        snippet: result.snippet,
      })),
    };
  },
  {
    name: "web_search",
    description: "Search the web with Caesar and return compact, citable results.",
    schema: z.object({
      query: z.string(),
      max_results: z.number().int().min(1).max(50).optional(),
    }),
  },
);

export const caesarRead = tool(
  async ({ target, query, max_chars }) => {
    const response = await caesar.read(target, {
      query,
      maxChars: max_chars,
    });

    return {
      doc_id: response.doc?.doc_id,
      url: response.doc?.canonical_url,
      title: response.doc?.title,
      content: response.content?.text ?? "",
      truncated: response.content?.truncated ?? false,
    };
  },
  {
    name: "web_fetch",
    description: "Read a Caesar doc_id or URL as clean markdown.",
    schema: z.object({
      target: z.string(),
      query: z.string().optional(),
      max_chars: z.number().int().min(1).max(50000).optional(),
    }),
  },
);

export const tools = [caesarSearch, caesarRead];
```

## Feedback

Framework tool loops usually do not call feedback automatically. After the agent uses a result, call the SDK directly with the `search_id` and `doc_id` you retained from the search response:

```python theme={"system"}
client.feedback("result_helpful", search_id=search_id, doc_id=doc_id)
```

## For agents

* Use `web_search` first with `compact` results, then call `web_fetch` only for the `doc_id` you actually need.
* Preserve `doc_id` and `search_id` exactly. They are opaque IDs, not strings to shorten or reconstruct.
* Do not merge search and read into one giant tool. Two smaller tools give the agent better control over context cost.
* If your runtime supports MCP, the [remote MCP server](/clients/mcp/remote) exposes `web_search` and `web_fetch` without custom code.
