> This page is for version v1 API.
> For other versions, use one of these documentation indexes:
> - v2 API (default): https://docs.cohere.com/v2/llms.txt
> - v1 API: https://docs.cohere.com/v1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.cohere.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.cohere.com/_mcp/server.

# Cohere Tools on LangChain (Integration Guide)

> Explore code examples for multi-step and single-step tool usage in chatbots, harnessing internet search and vector storage.

Cohere supports various integrations with LangChain, a large language model (LLM) framework which allows you to quickly create applications based on Cohere's models. This doc will guide you through how to leverage [Cohere tools](../docs/tool-use) with LangChain.

## Prerequisites

Running Cohere tools with LangChain doesn't require many prerequisites, consult the [top-level document](../docs/cohere-and-langchain) for more information.

## Multi-Step Tool Use

The idiomatic way to build a multi-step agent with LangChain v1 is [`create_agent`](https://docs.langchain.com/oss/python/langchain/agents) from `langchain.agents` (it ships with `langchain`, so no extra install is needed). The agent can call tools repeatedly, reasoning across multiple steps before returning a final answer. Here we give it an internet search tool (Tavily); install it with `pip install langchain-tavily`, set a `TAVILY_API_KEY` environment variable to run it, and swap in any other LangChain tool you like. You can steer the agent's behavior with a system instruction by passing it to `create_agent` via the `system_prompt` argument.

**`PYTHON`**

```python PYTHON
import os

from langchain.agents import create_agent
from langchain_cohere import ChatCohere
from langchain_tavily import TavilySearch

# Internet search tool. Replace the placeholder with your Tavily API key.
os.environ["TAVILY_API_KEY"] = "TAVILY_API_KEY"

internet_search = TavilySearch()

# Define the Cohere LLM
llm = ChatCohere(
    cohere_api_key="COHERE_API_KEY",
    model="command-a-03-2025",
    temperature=0,
)

# System instruction for the agent
system_prompt = """
You are an expert who answers the user's question by searching the internet for the most relevant, up-to-date information.
"""

# Create a multi-step agent, passing the instruction via `system_prompt`
agent = create_agent(
    llm, tools=[internet_search], system_prompt=system_prompt
)

# The agent can search multiple times to answer the question
result = agent.invoke(
    {
        "messages": [
            ("user", "Who is the mayor of the capital of Ontario?")
        ]
    }
)

print(result["messages"][-1].content)
```

## Single-Step Tool Use

Single-step tool use lets the model decide which tools to call for a query without executing them. Bind your tools to the model and read the chosen tool calls from the response's `.tool_calls` attribute. Provide the routing instruction as a `SystemMessage` at the start of the conversation.

**`PYTHON`**

```python PYTHON
from langchain_cohere import ChatCohere
from langchain_core.messages import HumanMessage, SystemMessage
from pydantic import BaseModel, Field


# Data model
class web_search(BaseModel):
    """
    The internet. Use web_search for questions that are related to anything else than agents, prompt engineering, and adversarial attacks.
    """

    query: str = Field(
        description="The query to use when searching the internet."
    )


class vectorstore(BaseModel):
    """
    A vectorstore containing documents related to agents, prompt engineering, and adversarial attacks. Use the vectorstore for questions on these topics.
    """

    query: str = Field(
        description="The query to use when searching the vectorstore."
    )


# System instruction that tells the model how to route
system_message = SystemMessage(
    content="""You are an expert at routing a user question to a vectorstore or web search.
The vectorstore contains documents related to agents, prompt engineering, and adversarial attacks.
Use the vectorstore for questions on these topics. Otherwise, use web-search."""
)

# Define the Cohere LLM
llm = ChatCohere(
    cohere_api_key="COHERE_API_KEY", model="command-a-03-2025"
)

# Bind the tools to the model
llm_with_tools = llm.bind_tools(tools=[web_search, vectorstore])

# The model routes this question to web search
messages = [
    system_message,
    HumanMessage("Who will the Bears draft first in the NFL draft?"),
]
response = llm_with_tools.invoke(messages)
print(response.tool_calls)

# The model routes this question to the vectorstore
messages = [
    system_message,
    HumanMessage("What are the types of agent memory?"),
]
response = llm_with_tools.invoke(messages)
print(response.tool_calls)

# When no tool is needed, `.tool_calls` is an empty list
messages = [system_message, HumanMessage("Hi, how are you?")]
response = llm_with_tools.invoke(messages)
print(response.tool_calls)
```

## SQL Agent

You can build an agent that interacts with a SQL database by giving `create_agent` the tools from LangChain's `SQLDatabaseToolkit`.

**`PYTHON`**

```python PYTHON
from langchain.agents import create_agent
from langchain_cohere import ChatCohere
from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain_community.utilities import SQLDatabase
import urllib.request

# Download the Chinook SQLite database
url = "https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite"
urllib.request.urlretrieve(url, "Chinook.db")
print("Chinook database downloaded successfully.")

db = SQLDatabase.from_uri("sqlite:///Chinook.db")
print(db.dialect)
print(db.get_usable_table_names())
db.run("SELECT * FROM Artist LIMIT 10;")

# Define the Cohere LLM
llm = ChatCohere(
    cohere_api_key="COHERE_API_KEY",
    model="command-a-03-2025",
    temperature=0,
)

# Build a SQL agent from the database toolkit's tools
toolkit = SQLDatabaseToolkit(db=db, llm=llm)
agent_executor = create_agent(llm, tools=toolkit.get_tools())

result = agent_executor.invoke(
    {
        "messages": [
            ("user", "Show me the first 5 rows of the Album table.")
        ]
    }
)
print(result["messages"][-1].content)
```

## CSV Agent

You can build an agent that answers questions about a CSV file by loading it into a pandas dataframe and giving `create_agent` a Python REPL tool with the dataframe in scope, so the agent can answer arbitrary questions about the data by writing and running pandas code (install `pip install langchain-experimental pandas`).

> **Note**
>
> The Python REPL tool runs model-generated code, so only use it with data and queries you trust.

**`PYTHON`**

```python PYTHON
from langchain.agents import create_agent
from langchain_cohere import ChatCohere
from langchain_experimental.tools import PythonAstREPLTool
import pandas as pd
import urllib.request

# Download the Titanic CSV and load it into a dataframe
url = "https://raw.githubusercontent.com/pandas-dev/pandas/main/doc/data/titanic.csv"
urllib.request.urlretrieve(url, "titanic.csv")
df = pd.read_csv("titanic.csv")

# Give the agent a Python REPL with the dataframe (`df`) in scope so it can
# answer arbitrary questions about the CSV by writing pandas code.
python_tool = PythonAstREPLTool(locals={"df": df})

# Define the Cohere LLM
llm = ChatCohere(
    cohere_api_key="COHERE_API_KEY",
    model="command-a-03-2025",
    temperature=0,
)

# Give the model the dataframe's columns and a preview so it knows the schema
# before it writes any pandas code.
system_prompt = (
    "You are a data analyst working with a pandas dataframe named `df`.\n"
    f"The dataframe columns are: {list(df.columns)}.\n"
    f"Here is `df.head()`:\n{df.head().to_string()}\n\n"
    "Answer the user's question by writing pandas code against `df` and running "
    "it with the Python tool, then report the result."
)

agent_executor = create_agent(
    llm, tools=[python_tool], system_prompt=system_prompt
)

result = agent_executor.invoke(
    {"messages": [("user", "How many people were on the titanic?")]}
)
print(result["messages"][-1].content)
```

## Streaming for Tool Calling

When tools are called in a streaming context, message chunks will be populated with tool call chunk objects in a list via the `.tool_call_chunks` attribute.

**`PYTHON`**

```python PYTHON
from langchain_core.tools import tool
from langchain_cohere import ChatCohere


@tool
def add(a: int, b: int) -> int:
    """Adds a and b."""
    return a + b


@tool
def multiply(a: int, b: int) -> int:
    """Multiplies a and b."""
    return a * b


tools = [add, multiply]

# Define the Cohere LLM
llm = ChatCohere(
    cohere_api_key="COHERE_API_KEY",
    model="command-a-03-2025",
    temperature=0,
)

llm_with_tools = llm.bind_tools(tools)

query = "What is 3 * 12? Also, what is 11 + 49?"

for chunk in llm_with_tools.stream(query):
    if chunk.tool_call_chunks:
        print(chunk.tool_call_chunks)
```

## LangGraph Agents

LangGraph is a stateful, orchestration framework that brings added control to agent workflows.

To use LangGraph with Cohere, you need to install the LangGraph package. To install it, run `pip install langgraph`.

### Basic Chatbot

This simple chatbot example will illustrate the core concepts of building with LangGraph.

**`PYTHON`**

```python PYTHON
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langchain_cohere import ChatCohere


# Create a state graph
class State(TypedDict):
    messages: Annotated[list, add_messages]


graph_builder = StateGraph(State)

# Define the Cohere LLM
llm = ChatCohere(
    cohere_api_key="COHERE_API_KEY", model="command-a-03-2025"
)


# Add nodes
def chatbot(state: State):
    return {"messages": [llm.invoke(state["messages"])]}


graph_builder.add_node("chatbot", chatbot)
graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)

# Compile the graph
graph = graph_builder.compile()

# Run the chatbot
while True:
    user_input = input("User: ")
    print("User: " + user_input)
    if user_input.lower() in ["quit", "exit", "q"]:
        print("Goodbye!")
        break
    for event in graph.stream({"messages": ("user", user_input)}):
        for value in event.values():
            print("Assistant:", value["messages"][-1].content)
```

### Enhancing the Chatbot with Tools

To handle queries our chatbot can't answer "from memory", we'll integrate a web search tool. Our bot can use this tool to find relevant information and provide better responses.

**`PYTHON`**

```python PYTHON
from langchain_tavily import TavilySearch
from langchain_cohere import ChatCohere
from langgraph.graph import StateGraph, START
from langgraph.graph.message import add_messages
from langchain_core.messages import ToolMessage
from langchain_core.messages import BaseMessage
from typing import Annotated, Literal
from typing_extensions import TypedDict
import json

# Create a tool
tool = TavilySearch(max_results=2)
tools = [tool]


# Create a state graph
class State(TypedDict):
    messages: Annotated[list, add_messages]


graph_builder = StateGraph(State)

# Define the LLM
llm = ChatCohere(
    cohere_api_key="COHERE_API_KEY", model="command-a-03-2025"
)

# Bind the tools to the LLM
llm_with_tools = llm.bind_tools(tools)


# Add nodes
def chatbot(state: State):
    return {"messages": [llm_with_tools.invoke(state["messages"])]}


graph_builder.add_node("chatbot", chatbot)


class BasicToolNode:
    """A node that runs the tools requested in the last AIMessage."""

    def __init__(self, tools: list) -> None:
        self.tools_by_name = {tool.name: tool for tool in tools}

    def __call__(self, inputs: dict):
        if messages := inputs.get("messages", []):
            message = messages[-1]
        else:
            raise ValueError("No message found in input")
        outputs = []
        for tool_call in message.tool_calls:
            tool_result = self.tools_by_name[
                tool_call["name"]
            ].invoke(tool_call["args"])
            outputs.append(
                ToolMessage(
                    content=json.dumps(tool_result),
                    name=tool_call["name"],
                    tool_call_id=tool_call["id"],
                )
            )
        return {"messages": outputs}


tool_node = BasicToolNode(tools=[tool])
graph_builder.add_node("tools", tool_node)


def route_tools(
    state: State,
) -> Literal["tools", "__end__"]:
    """
    Use in the conditional_edge to route to the ToolNode if the last message
    has tool calls. Otherwise, route to the end.
    """
    if isinstance(state, list):
        ai_message = state[-1]
    elif messages := state.get("messages", []):
        ai_message = messages[-1]
    else:
        raise ValueError(
            f"No messages found in input state to tool_edge: {state}"
        )
    if (
        hasattr(ai_message, "tool_calls")
        and len(ai_message.tool_calls) > 0
    ):
        return "tools"
    return "__end__"


graph_builder.add_conditional_edges(
    "chatbot",
    route_tools,
    {"tools": "tools", "__end__": "__end__"},
)
graph_builder.add_edge("tools", "chatbot")
graph_builder.add_edge(START, "chatbot")

# Compile the graph
graph = graph_builder.compile()

# Run the chatbot
while True:
    user_input = input("User: ")
    if user_input.lower() in ["quit", "exit", "q"]:
        print("Goodbye!")
        break
    for event in graph.stream({"messages": [("user", user_input)]}):
        for value in event.values():
            if isinstance(value["messages"][-1], BaseMessage):
                print("Assistant:", value["messages"][-1].content)
```