What is .ainvoke()?
.ainvoke() is the async counterpart to .invoke() in LangChain's Runnable interface. Every component that implements Runnable — chat models, chains, retrievers, output parsers, tools — automatically exposes .ainvoke(), which returns a coroutine you await inside any async function.
Under the hood, .ainvoke() uses the underlying provider's async HTTP client (for example httpx.AsyncClient via the OpenAI async SDK) rather than a blocking requests session. This means the event loop stays free to handle other coroutines while the network call is in-flight. Calling the synchronous .invoke() inside an async function blocks the event loop entirely and causes latency spikes under concurrent load.
The API surface mirrors .invoke() exactly: pass the same input (string, dict, list of messages, or whatever the Runnable accepts) and an optional config dict for callbacks, tags, and recursion limits. You can fan out multiple .ainvoke() calls simultaneously with asyncio.gather — this is the standard pattern for parallel enrichment, multi-query retrieval, and batch classification. One caveat: you cannot call await model.ainvoke(...) outside an async context. In sync entry points (CLI scripts, Django sync views), wrap with asyncio.run() or switch to .invoke().
Use Cases
- • Async web frameworks
- • Concurrent calls
- • Async/await patterns
- • Non-blocking operations
- • Microservices
- • Event-driven apps
Key Features
- ✓ Asynchronous
- ✓ Awaitable
- ✓ Concurrent-friendly
- ✓ True non-blocking
- ✓ Works with async code
- ✓ Scalable
When NOT to Use
Outside async functions—use invoke(). For sync code.
Notes
Always await — missing it returns a coroutine object
If you forget await, you get a coroutine object back, not the result. Accessing .content on a coroutine raises AttributeError. If your IDE shows a "coroutine was never awaited" warning, that is the same bug.
asyncio.gather for true parallelism
Running await model.ainvoke(q) in a for-loop is still sequential — each awaits before the next starts. Wrap calls in asyncio.gather(*[model.ainvoke(q) for q in questions]) to fire all requests concurrently and cut total latency to roughly the slowest single call.
Pass callbacks via config, not globals
In async code, multiple coroutines share the event loop. A globally attached callback manager can receive events from the wrong coroutine. Always pass config={"callbacks": [handler]} per call to keep callbacks scoped to their invocation.
Cannot be called from sync context without asyncio.run()
Calling asyncio.run(model.ainvoke(...)) works from a sync entry point, but fails if an event loop is already running (e.g., inside Jupyter or an existing async task). In Jupyter, use "await model.ainvoke(...)" directly or install nest_asyncio.
Method Signature
result = await runnable.ainvoke(input, config=None)
Parameters
| Parameter | Type | Required | Purpose |
|---|---|---|---|
| input | Any | Yes | Input data |
| config | RunnableConfig | None | No | Run configuration: callbacks, tags, metadata |
Return Value
Type:
Awaitable[Any]
Description:
Awaitable returning full result
Example Output:
await model.ainvoke([msg])
Code Examples
FastAPI endpoint
@app.post('/ask')
async def ask(message: str):
result = await model.ainvoke([HumanMessage(content=message)])
return result.content
Concurrent calls with asyncio.gather
import asyncio
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
model = ChatOpenAI(model="gpt-4o")
questions = [
"What is RAG?",
"What is an agent?",
"What is LCEL?",
]
async def run_all():
results = await asyncio.gather(
*[model.ainvoke([HumanMessage(content=q)]) for q in questions]
)
for q, r in zip(questions, results):
print(f"{q}: {r.content[:80]}")
asyncio.run(run_all())
Error handling with retry on rate limit
import asyncio
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from openai import RateLimitError, APITimeoutError
model = ChatOpenAI(model="gpt-4o")
async def safe_invoke(text: str):
try:
return await model.ainvoke([HumanMessage(content=text)])
except RateLimitError:
await asyncio.sleep(5)
return await model.ainvoke([HumanMessage(content=text)])
except APITimeoutError as e:
raise RuntimeError(f"Timeout on: {text}") from e
Common Mistakes
❌ result = model.ainvoke(input) # Missing await
✅ result = await model.ainvoke(input)
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 .ainvoke() and the wider framework.
.ainvoke() FAQ
What does .ainvoke() do in LangChain?
Execute Runnable asynchronously and return full result. .ainvoke() is the async counterpart to .invoke() in LangChain's Runnable interface. Every component that implements Runnable — chat models, chains, retrievers, output parsers, tools — automatically exposes .ainvoke(), which returns a coroutine you await inside any async function. Under the hood, .ainvoke() uses the underlying provider's async HTTP client (for example httpx.AsyncClient via the OpenAI async SDK) rather than a blocking requests session. This means the event loo…
Which LangChain classes support .ainvoke()?
.ainvoke() is available on All Runnables. Pin your installed LangChain version and verify the method exists in that release before deploying.
When should I use .ainvoke()?
Use .ainvoke() when your LangChain chains, agents, or pipelines need the behavior described in this guide.
What does .ainvoke() return?
.ainvoke() returns a Awaitable[Any]. Awaitable returning full result
Does .ainvoke() have an async equivalent?
.ainvoke() does not have a documented async variant. Avoid .ainvoke() Outside async functions—use invoke(). For sync code.
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.