[PR #5261] add Pydantic model support for ChatPromptTemplate in create_react_agent #4336

Closed
opened 2026-02-20 17:50:02 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langchain-ai/langgraph/pull/5261

State: closed
Merged: No


Problem

ChatPromptTemplate does not work properly with Pydantic models when used in prebuilt agents. The issue occurs because ChatPromptTemplate expects dictionary-like inputs for variable substitution (e.g., {role} placeholders), but Pydantic models are objects with attributes rather than dictionary keys.

Root Cause

When ChatPromptTemplate processes template variables like {role}, it tries to access them as dictionary keys. However, Pydantic models store data as object attributes, making them incompatible with the template's key-based variable substitution mechanism.

Implementation Details

File: libs/prebuilt/langgraph/prebuilt/chat_agent_executor.py

  • Added RunnableLambda import
  • Added conditional logic to detect Pydantic + BasePromptTemplate combination
  • Inserts conversion step in the model_runnable chain: pydantic_to_dict | prompt | model

File: libs/prebuilt/tests/test_react_agent.py

  • Added test_pydantic_prompt_and_state() to verify the fix works
  • Tests Pydantic state with ChatPromptTemplate variable substitution
  • Fixed minor syntax issue: changed return to pass in existing test

Testing

The new test case test_pydantic_prompt_and_state() verifies:

  • Pydantic state schema works with ChatPromptTemplate
  • Template variables are properly substituted from Pydantic model attributes
  • Expected output matches the templated result

Test scenario:

class State(BaseModel):
    messages: Annotated[list[AnyMessage], add_messages]
    role: str
    remaining_steps: RemainingSteps = 25

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant that knows the user's role is {role}"),
    ("placeholder", "{messages}"),
])

Backward Compatibility

This change is fully backward compatible:

  • Only activates when specific conditions are met (Pydantic + BasePromptTemplate)
  • TypedDict schemas continue to work unchanged
  • Non-Pydantic inputs are passed through without modification

Performance Impact

Minimal performance overhead:

  • Conversion only occurs when both conditions are met
  • isinstance() check is fast
  • model_dump() is efficient for Pydantic models

Related Issues

Closes #5230
Related to #3867

**Original Pull Request:** https://github.com/langchain-ai/langgraph/pull/5261 **State:** closed **Merged:** No --- ## Problem ChatPromptTemplate does not work properly with Pydantic models when used in prebuilt agents. The issue occurs because ChatPromptTemplate expects dictionary-like inputs for variable substitution (e.g., `{role}` placeholders), but Pydantic models are objects with attributes rather than dictionary keys. ## Root Cause When ChatPromptTemplate processes template variables like `{role}`, it tries to access them as dictionary keys. However, Pydantic models store data as object attributes, making them incompatible with the template's key-based variable substitution mechanism. ## Implementation Details **File: `libs/prebuilt/langgraph/prebuilt/chat_agent_executor.py`** - Added RunnableLambda import - Added conditional logic to detect Pydantic + BasePromptTemplate combination - Inserts conversion step in the model_runnable chain: `pydantic_to_dict | prompt | model` **File: `libs/prebuilt/tests/test_react_agent.py`** - Added `test_pydantic_prompt_and_state()` to verify the fix works - Tests Pydantic state with ChatPromptTemplate variable substitution - Fixed minor syntax issue: changed `return` to `pass` in existing test ## Testing The new test case `test_pydantic_prompt_and_state()` verifies: - Pydantic state schema works with ChatPromptTemplate - Template variables are properly substituted from Pydantic model attributes - Expected output matches the templated result Test scenario: ```python class State(BaseModel): messages: Annotated[list[AnyMessage], add_messages] role: str remaining_steps: RemainingSteps = 25 prompt = ChatPromptTemplate.from_messages([ ("system", "You are a helpful assistant that knows the user's role is {role}"), ("placeholder", "{messages}"), ]) ``` ## Backward Compatibility This change is fully backward compatible: - Only activates when specific conditions are met (Pydantic + BasePromptTemplate) - TypedDict schemas continue to work unchanged - Non-Pydantic inputs are passed through without modification ## Performance Impact Minimal performance overhead: - Conversion only occurs when both conditions are met - `isinstance()` check is fast - `model_dump()` is efficient for Pydantic models ## Related Issues Closes #5230 Related to #3867
yindo added the pull-request label 2026-02-20 17:50:02 -05:00
yindo closed this issue 2026-02-20 17:50:02 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#4336