# LangChain and LangGraph

Source: https://convergingthought.com/docs/integrations/langchain

> Keep your chain or graph and replace its chat-model connection.



`ChatOpenAI` can point to Internalize's compatible endpoint. Set `use_responses_api=False` so the integration uses Chat Completions.

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

```python
import os
from langchain_openai import ChatOpenAI

model = ChatOpenAI(
    model="glm-5.3",
    base_url="https://convergingthought.com/v1",
    api_key=os.environ["INTERNALIZE_API_KEY"],
    use_responses_api=False,
    max_retries=0,
)
print(model.invoke("Hello!").content)
```

Use this model in your existing LangGraph agent or node. Internalize supplies inference and learning; your graph continues to own tools, conversation state, checkpoints, and application logic.

## Route to a subject [#route-to-a-subject]

For a model instance scoped to an authorized tenant, pass `default_headers={"X-Internalize-Subject": subject_id}` to `ChatOpenAI`. Resolve that ID from your application's authenticated identity, not a model-produced argument. Create a per-subject instance or use a request-scoped configuration; do not change headers on a shared instance during concurrent execution.

Without this header or a `subject_id` extra body field, inference explicitly uses base weights. A subject request resolves the active version when it is admitted. Running requests retain that immutable version.

## Tool messages [#tool-messages]

Use ordinary `bind_tools` function tools. Keep `AIMessage.tool_calls` and matching `ToolMessage` IDs in the conversation, and return all tool results before the next model call. The gateway rejects missing, duplicate, and unknown tool results.

If you expose learning, bind the subject in a server-side handler. Persist the graph run's tool operation identity as the idempotency key. A graph checkpoint can restore the same job receipt rather than submit a replacement call after a process restart.

## Bound the integration [#bound-the-integration]

Set retries to zero until your graph has explicit job recovery. Streams are buffered until final validation. Avoid strict structured-output helpers that request `json_schema`, unsupported multimodal content, or Responses-specific settings. An unknown field returns `422` rather than being ignored.

Learning is asynchronous and may exceed a web handler's lifetime. For long operations, store the job ID in graph state and resume observation from durable work. Check `activated` before assuming future calls can use the learned version.

See [LangChain's official OpenAI integration](https://docs.langchain.com/oss/python/integrations/chat/openai) and [polling and recovery](/docs/sdk-reference/polling).
