Implementation:Langchain ai Langchain Conversation Loop Pattern
| Knowledge Sources | |
|---|---|
| Domains | Agentic_AI, Conversation_Management |
| Last Updated | 2026-02-11 00:00 GMT |
Overview
Pattern for implementing the agent conversation loop using BaseChatModel.invoke() with full message history provided by langchain-core.
Description
The conversation loop pattern uses BaseChatModel.invoke() with a growing list of messages. After each tool execution round, the AIMessage (with tool_calls) and ToolMessages (with results) are appended to the message history before re-invocation. The same invoke() path handles both tool-calling and final-answer responses.
Usage
This is a user-defined pattern (not a single API call). Implement it manually or use LangGraph for managed agent loops.
Code Reference
Source Location
- Repository: langchain
- File: libs/core/langchain_core/language_models/chat_models.py
- Lines: L389-437 (invoke — same path re-invoked with history)
Signature
# Re-invocation uses the same invoke() signature:
def invoke(
self,
input: LanguageModelInput,
config: RunnableConfig | None = None,
*,
stop: list[str] | None = None,
**kwargs: Any,
) -> AIMessage:
Import
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| input | list[BaseMessage] | Yes | Full conversation: [HumanMessage, AIMessage(tool_calls), ToolMessage, ...] |
Outputs
| Name | Type | Description |
|---|---|---|
| return | AIMessage | Either another round of tool_calls or a final text response |
Usage Examples
Complete Agent Loop
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, ToolMessage
from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"72°F and sunny in {city}"
llm = ChatOpenAI(model="gpt-4o-mini").bind_tools([get_weather])
messages = [HumanMessage(content="What's the weather in SF and NYC?")]
# Agent loop
for _ in range(5): # Max iterations
response = llm.invoke(messages)
messages.append(response)
if not response.tool_calls:
print("Final answer:", response.content)
break
# Execute tool calls
for tc in response.tool_calls:
result = get_weather.invoke(tc)
messages.append(ToolMessage(
content=str(result),
tool_call_id=tc["id"],
name=tc["name"],
))