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

# Model Service

> LangChain chat models configured for Aion.

Aion provides helper functions to create LangChain chat models that are automatically configured for
use within the Aion framework.

These helpers handle authentication, endpoint selection, and runtime principal attribution
transparently, so you can focus on your LangGraph logic.

## Overview

```python theme={null}
from aion.langgraph.authoring import aion_chat_model, aion_chat_openai

# Generic approach (auto-detects the provider)
model = aion_chat_model("gpt-4o", temperature=0.7)

# Explicit LangChain ChatOpenAI
model = aion_chat_openai("gpt-4o", temperature=0.7)
```

Both helpers connect to the Aion control-plane model service and work in LangGraph nodes:

```python theme={null}
from langgraph.graph import StateGraph

builder = StateGraph(State, context_schema=AionRuntimeContext)

async def analyze_node(state: dict):
    model = aion_chat_openai("gpt-4o", temperature=0)
    response = await model.ainvoke([HumanMessage(content="Analyze this...")])
    return {"analysis": response.content}

builder.add_node("analyze", analyze_node)
```

## Functions

### `aion_chat_model(...)`

```python theme={null}
aion_chat_model(
    model: str,
    **kwargs: Any,
) -> Any
```

Create a LangChain chat model configured for Aion using `langchain.chat_models.init_chat_model`.

This is the generic approach that auto-detects the provider. For most use cases with Aion, you'll use
OpenAI models, so it behaves the same as `aion_chat_openai`.

**Parameters:**

| Parameter  | Type  | Description                                                                              |
| ---------- | ----- | ---------------------------------------------------------------------------------------- |
| `model`    | `str` | Model ID from the Aion control plane model catalog (e.g., `gpt-4o`, `gpt-4-turbo`)       |
| `**kwargs` | `Any` | Additional behavior options: `temperature`, `max_tokens`, `timeout`, `max_retries`, etc. |

**Note:** Do not pass `api_key`, `base_url`, `default_headers`, `http_async_client`, or
`http_client`. These are managed by Aion.

**Returns:**

A LangChain chat model (typically `ChatOpenAI`) ready to use.

**Raises:**

* `ImportError` — If LangChain is not installed
* `ValueError` — If any reserved parameter is provided

**Example:**

```python theme={null}
from aion.langgraph.authoring import aion_chat_model
from langchain_core.messages import HumanMessage

async def process_node(state: dict):
    # Create model with custom temperature
    model = aion_chat_model("gpt-4o", temperature=0.5)
    
    # Invoke synchronously or asynchronously
    response = await model.ainvoke([
        HumanMessage(content="What is the capital of France?")
    ])
    
    return {"answer": response.content}
```

### `aion_chat_openai(...)`

```python theme={null}
aion_chat_openai(
    model: str,
    **kwargs: Any,
) -> ChatOpenAI
```

Create a `langchain-openai` `ChatOpenAI` model configured for Aion.

Use this when you need explicit control or want to be specific about using OpenAI models.

**Parameters:**

| Parameter  | Type  | Description                                                      |
| ---------- | ----- | ---------------------------------------------------------------- |
| `model`    | `str` | OpenAI model ID (e.g., `gpt-4o`, `gpt-4-turbo`, `gpt-3.5-turbo`) |
| `**kwargs` | `Any` | Additional model options forwarded to `ChatOpenAI`.              |

**Note:** Do not pass `api_key`, `base_url`, `default_headers`, `http_async_client`, or
`http_client`. These are managed by Aion.

**Returns:**

A `ChatOpenAI` instance backed by Aion's model proxy.

**Raises:**

* `ImportError` — If `langchain-openai` is not installed
* `ValueError` — If any reserved parameter is provided

**Example:**

```python theme={null}
from aion.langgraph.authoring import aion_chat_openai
from langchain_core.messages import HumanMessage, SystemMessage

async def reasoning_node(state: dict):
    # Create a model tuned for reasoning
    model = aion_chat_openai(
        "gpt-4o",
        temperature=0.2,
        max_tokens=2000,
    )
    
    messages = [
        SystemMessage(content="You are a logical reasoning assistant."),
        HumanMessage(content="Prove that sqrt(2) is irrational."),
    ]
    
    response = await model.ainvoke(messages)
    return {"proof": response.content}
```

## Usage in LangGraph Nodes

Models are typically created per-node invocation to ensure fresh authentication and principal
context:

```python theme={null}
from aion.langgraph.authoring import aion_chat_openai
from langchain_core.messages import HumanMessage
from langgraph.graph import StateGraph

class State(TypedDict):
    query: str
    response: str

builder = StateGraph(State)

async def answer_node(state: State) -> dict:
    model = aion_chat_openai("gpt-4o", temperature=0.7)
    response = await model.ainvoke([HumanMessage(content=state["query"])])
    return {"response": response.content}

builder.add_node("answer", answer_node)
```

## Streaming

Both helpers return standard LangChain models that support streaming:

```python theme={null}
from aion.langgraph.authoring import aion_chat_openai
from langchain_core.messages import HumanMessage

model = aion_chat_openai("gpt-4o")

async def stream_response():
    async for chunk in model.astream([
        HumanMessage(content="Tell me a story")
    ]):
        # Your code here: process each chunk as it arrives
```

## Related Pages

* [LangGraph Streaming API](/sdk/langgraph/streaming-api)
* [AionRuntimeContext](/sdk/langgraph/api/runtime-context)
