# LangChain
URL: https://docs.munito.ai/langchain

To use Munito AI in LangChain, create a `ChatOpenAI` model with the Munito AI base URL and your Munito AI key.
Invoke, streaming, tool binding and structured output then work as with any LangChain chat model.

| Package               | Class           | Base URL                             |
| --------------------- | --------------- | ------------------------------------ |
| `langchain-openai`    | `ChatOpenAI`    | `https://api.munito.ai/inference/v1` |
| `langchain-anthropic` | `ChatAnthropic` | `https://api.munito.ai/inference`    |

Both classes use the same Munito AI key. To keep the processing in the EU or the US, use a [regional host](https://docs.munito.ai/regions) in place of `api.munito.ai`.

```bash
export MUNITO_API_KEY="munitoai_..."
```

## ChatOpenAI [#chatopenai]

```bash
pip install langchain-openai
```

This script invokes the model, streams an answer, calls a tool, and gets structured output:

```python
# pip install langchain-openai
import os

from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from pydantic import BaseModel

llm = ChatOpenAI(
    model="qwen/qwen3.8-27b",
    base_url="https://api.munito.ai/inference/v1",
    api_key=os.environ["MUNITO_API_KEY"],
    max_tokens=2048,
    reasoning_effort="low",
)

# 1. Invoke
print(llm.invoke("Name the capital of Portugal in one word.").content.strip())

# 2. Stream
for chunk in llm.stream("Count from 1 to 5, one number on each line."):
    print(chunk.content, end="", flush=True)
print()


# 3. Tools
@tool
def get_weather(city: str) -> str:
    """Return the current weather for a city."""
    return f"It is 18 degrees and sunny in {city}."


message = llm.bind_tools([get_weather]).invoke("What is the weather in Lyon?")
for call in message.tool_calls:
    print(call["name"], call["args"])


# 4. Structured output
class City(BaseModel):
    name: str
    country: str
    population: int


print(llm.with_structured_output(City).invoke("Give the facts for Munich."))
```

The output:

```text
Lisbon
1
2
3
4
5
get_weather {'city': 'Lyon'}
name='Munich' country='Germany' population=1450000
```

`with_structured_output` sends a JSON schema in `response_format`. Choose a model whose [model page](https://docs.munito.ai/models) lists structured output and tools, such as `qwen/qwen3.8-27b`.

## ChatAnthropic [#chatanthropic]

`ChatAnthropic` sends requests to the Munito AI Messages API. Its base URL excludes `/v1`, because the client adds `/v1/messages`.

```bash
pip install langchain-anthropic
```

```python
# pip install langchain-anthropic
import os

from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(
    model="qwen/qwen3.8-27b",
    base_url="https://api.munito.ai/inference",
    api_key=os.environ["MUNITO_API_KEY"],
    max_tokens=2048,
)
print(llm.invoke("Name the capital of Portugal in one word.").text.strip())
for chunk in llm.stream("Count from 1 to 3, one number on each line."):
    print(chunk.text, end="", flush=True)
print()
```

`.text` gives the answer text only. The reasoning of the model comes in separate `thinking` blocks in `.content`.

## Settings [#settings]

- **`max_tokens`.** `qwen/qwen3.8-27b` and `zai-org/glm-5.3-flash` reason before they answer. A small `max_tokens` can end the request before the answer, with empty content. Use a value such as 2048, or set `reasoning_effort="low"` on `ChatOpenAI`.
- **Service tier.** Send the `munito-service-tier` header with `default_headers={"munito-service-tier": "flex"}` on `ChatOpenAI` or `ChatAnthropic`. See [Service tiers](https://docs.munito.ai/service-tiers).
- **Retries.** Both classes retry `429` and `5xx` answers. Set `max_retries` to change the count. See [Production checklist](https://docs.munito.ai/production-checklist).

For retrieval, see [RAG](https://docs.munito.ai/rag). Munito AI has no embeddings endpoint, so take the embeddings from another source.
