Almost every LangGraph app has at least one model-calling node; getting its shape right matters.
A model-calling node is a normal function: read messages from state, call the model, return the reply as a state update.
You can use any client library. With LangChain's chat model interface (from the LangChain lessons) the code is short and provider-independent:
model = init_chat_model("claude-sonnet-4-6")
def chatbot(state: MessagesState):
return {"messages": [model.invoke(state["messages"])]}init_chat_model picks the provider from the model name (or a prefix like "openai:...") and needs that provider's package and API key. Model names change often; check the provider's current list.
Patterns worth knowing:
- System prompt: prepend it at call time,
model.invoke([SystemMessage(...)] + state["messages"]), rather than storing it in state. That keeps state clean and lets you change the prompt without migrating saved threads. - Create the model once, outside the node, so it isn't rebuilt every step.
- Async: in an async app write
async def chatbot(...)and useawait model.ainvoke(...). - Structured decisions: for routing, use
model.with_structured_output(Schema)(it returns a parsed object matching your schema instead of free text) and store the parsed field in state; then a conditional edge reads it.
Token-by-token output works automatically: LangGraph's messages stream mode picks up tokens from LangChain models called inside nodes, as the streaming lesson shows.
Example
from langchain.chat_models import init_chat_model
from langchain_core.messages import SystemMessage
from langgraph.graph import StateGraph, START, END, MessagesState
# pip install langgraph langchain langchain-anthropic; set ANTHROPIC_API_KEY
model = init_chat_model("claude-sonnet-4-6", temperature=0) # names change; check docs
SYSTEM = SystemMessage("You are a concise assistant for a bike shop.")
def chatbot(state: MessagesState) -> dict:
reply = model.invoke([SYSTEM] + state["messages"])
return {"messages": [reply]}
b = StateGraph(MessagesState)
b.add_node(chatbot)
b.add_edge(START, "chatbot")
b.add_edge("chatbot", END)
graph = b.compile()
out = graph.invoke({"messages": [{"role": "user", "content": "Do you fix e-bikes?"}]})
print(out["messages"][-1].content)Remember
- A model node: read state['messages'], call the model, return {'messages': [reply]}
- Create the model once; add the system prompt at call time
- Use with_structured_output for decisions that drive routing
- LangChain models stream tokens through LangGraph automatically