What is .invoke()?
.invoke() is the synchronous entry point for any object that implements LangChain's Runnable interface — chat models, LLMs, chains, retrievers, output parsers, agents, tools, and LangGraph graphs all expose it. You pass an input (string, list of messages, dict, or whatever the Runnable's expected type is) and the method blocks until the full result is ready, then returns it. The return type mirrors the Runnable: a ChatModel returns an AIMessage, an output parser returns whatever Python type it parses, an LCEL chain returns the output of its last step.
The optional config argument accepts a RunnableConfig dict. Useful keys include tags (list of strings attached to all LangSmith traces for that call), metadata (arbitrary dict also attached to traces), callbacks (a list of callback handlers), and max_concurrency (for chains that fan out internally). You rarely need config in scripts and tests but it becomes essential in production when you want per-request trace metadata.
Under the hood, .invoke() calls the Runnable's _call or _generate method on the current thread and propagates any exception directly — there is no hidden retry or timeout. In async contexts (FastAPI, Django async views, asyncio tasks), calling .invoke() blocks the event loop. Use .ainvoke() instead. For multiple inputs, .batch() is more efficient than a for-loop of .invoke() calls because it dispatches inputs concurrently via a threadpool.
Use Cases
- • Script execution
- • Testing
- • Single input processing
- • Batch loops
- • Database operations
- • Synchronous code
Key Features
- ✓ Synchronous
- ✓ Full result
- ✓ Error propagation
- ✓ Config support
- ✓ Universal
- ✓ Composable
When NOT to Use
In web servers—use ainvoke(). For streaming, use stream().
Notes
Input type must match what the Runnable expects
ChatModels require a list of BaseMessage objects (or a string which LangChain auto-wraps). Chains built with ChatPromptTemplate expect a dict matching the template's input variables. Passing the wrong type raises a validation error at runtime — check the Runnable's expected_input_types or input_schema property if unsure.
Blocks the event loop in async contexts
Calling model.invoke() inside an async function blocks the event loop for the duration of the network request. Under FastAPI or asyncio, this stalls all other coroutines. Swap to await model.ainvoke() in any async context to keep the event loop free.
config carries per-call metadata to LangSmith
Every invoke() call generates a LangSmith run if LANGSMITH_TRACING=true. Pass config={"tags": ["my-feature"], "metadata": {"user": "alice"}} to attach searchable labels to that run — useful for filtering traces by feature flag, A/B variant, or user segment.
For multiple inputs, batch() is faster than a loop
Calling invoke() in a for-loop is sequential: each call waits for the previous to finish. model.batch(inputs) dispatches all inputs concurrently in a threadpool and returns results in input order. Speedup is roughly proportional to the number of inputs up to your API rate limit.
Method Signature
result = runnable.invoke(input, config=None)
Parameters
| Parameter | Type | Required | Purpose |
|---|---|---|---|
| input | Any | Yes | Input data (string, dict, message) |
Return Value
Type:
Any
Description:
Full result
Example Output:
AIMessage(content='Hi')
Code Examples
Basic chat model invocation
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
model = ChatOpenAI(model="gpt-4o-mini")
result = model.invoke([HumanMessage(content='Hi')])
print(result.content)
LCEL chain invocation
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
chain = ChatPromptTemplate.from_template("Summarize: {text}") | ChatOpenAI() | StrOutputParser()
result = chain.invoke({'text': 'LangChain is a framework...'})
print(result)
Invoke with trace metadata via config
from langsmith.run_helpers import get_current_run_tree
result = model.invoke(
[HumanMessage(content='Classify this email')],
config={'tags': ['email-classifier'], 'metadata': {'user_id': 'u123'}}
)
Common Mistakes
❌ llm.invoke('hello') # String not wrapped
✅ llm.invoke([HumanMessage(content='hello')])
Related LangChain References
Browse the full LangChain API reference index to explore more classes, methods, and decorators, or start with the LangChain introduction tutorial for end-to-end context on building with .invoke() and the wider framework.
.invoke() FAQ
What does .invoke() do in LangChain?
Execute Runnable synchronously and return full result. .invoke() is the synchronous entry point for any object that implements LangChain's Runnable interface — chat models, LLMs, chains, retrievers, output parsers, agents, tools, and LangGraph graphs all expose it. You pass an input (string, list of messages, dict, or whatever the Runnable's expected type is) and the method blocks until the full result is ready, then returns it. The return type mirrors the Runnable: a ChatModel returns an AIMessage, an output parser returns whate…
Which LangChain classes support .invoke()?
.invoke() is available on All Runnables. Pin your installed LangChain version and verify the method exists in that release before deploying.
When should I use .invoke()?
Use .invoke() when your LangChain chains, agents, or pipelines need the behavior described in this guide.
What does .invoke() return?
.invoke() returns a Any. Full result
Does .invoke() have an async equivalent?
Yes — use ainvoke() for async contexts such as FastAPI handlers or asyncio-based pipelines. It is the non-blocking counterpart to .invoke().
Where can I explore more LangChain API reference pages?
Open the LangChain API reference index on DevShelfHub to browse classes, methods, and decorators, each with runnable examples, parameters, common mistakes, and cross-links.