Skip to content

Thinking tags are coming across as "text" responses with nova pro on Bedrock #783

@automaton82

Description

@automaton82

Package

langchain-aws

Checked other resources

  • I added a descriptive title to this issue
  • I searched the LangChain documentation with the integrated search
  • I used the GitHub search to find a similar issue and didn't find it
  • I am sure this is a bug and not a question or request for help

Example Code

# Example:
"""
Minimal reproducible example for AWS Bedrock Nova Pro returning <thinking> tags
when using bind_tools().
"""

from langchain_aws import ChatBedrock
from langchain_core.messages import HumanMessage
from langchain_core.tools import tool

# Configure your AWS credentials
AWS_ACCESS_KEY_ID = "your_access_key"
AWS_SECRET_ACCESS_KEY = "your_secret_key"
AWS_REGION = "us-east-1"  # or your region

# Create a simple tool
@tool
def get_population_data(continent: str) -> str:
    """Get population data for a continent."""
    data = {
        "Asia": "3705.03",
        "Africa": "1200.00",
        "Europe": "750.00"
    }
    return f"Population of {continent}: {data.get(continent, 'Unknown')} million"

# Initialize the model
model = ChatBedrock(
    model_id="us.amazon.nova-pro-v1:0",
    aws_access_key_id=AWS_ACCESS_KEY_ID,
    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
    region=AWS_REGION,
)

# Bind tools to the model
tools = [get_population_data]
llm_with_tools = model.bind_tools(tools)

# Test 1: Without tools (should work fine)
print("=" * 60)
print("Test 1: WITHOUT tools")
print("=" * 60)
response_no_tools = model.invoke([HumanMessage(content="What is the population of Asia?")])
print(f"Response content: {response_no_tools.content}")
print()

# Test 2: With tools bound (will show <thinking> tags in response)
print("=" * 60)
print("Test 2: WITH tools (reproduces the issue)")
print("=" * 60)

messages = [HumanMessage(content="What is the population of Asia? Format as CSV.")]

# First call - may invoke tool
response1 = llm_with_tools.invoke(messages)
print(f"First response - tool_calls: {response1.tool_calls}")
print(f"First response content: {response1.content}")
print()

# If tool was called, execute it and get final response
if response1.tool_calls:
    from langchain_core.messages import ToolMessage
    
    messages.append(response1)
    
    # Execute the tool
    for tool_call in response1.tool_calls:
        tool_result = get_population_data.invoke(tool_call)
        messages.append(ToolMessage(content=str(tool_result), tool_call_id=tool_call["id"]))
    
    # Get final response
    response2 = llm_with_tools.invoke(messages)
    print(f"Final response content:\n{response2.content}")
    print()
    print("ISSUE: Notice the <thinking> tags in the response above ^")
    print()
    
    # Show what the content looks like
    if isinstance(response2.content, list):
        print(f"Content is a list with {len(response2.content)} items:")
        for i, item in enumerate(response2.content):
            print(f"  Item {i}: {type(item)} = {item}")
    else:
        print(f"Content type: {type(response2.content)}")
        print(f"Content value: {response2.content}")

Error Message and Stack Trace (if applicable)

<thinking> The query has been executed and the result is that Asia has the highest total population with 3705.03 million. To format this in CSV, I will use a simple structure with headers "Continent" and "Population (M)". </thinking>

Here is the data in CSV format:
Continent,Population (M)
Asia,3705.03

Description

The issue is the <thinking> tags are not coming in as type:thinking but instead as text which seems wrong. I could write regex to remove them but I think they should be properly categorized.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions