Skip to content

Amazon Nova (Bedrock) limitations with tool schema #1623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
2 tasks done
chasewalden opened this issue Apr 30, 2025 · 5 comments
Open
2 tasks done

Amazon Nova (Bedrock) limitations with tool schema #1623

chasewalden opened this issue Apr 30, 2025 · 5 comments
Assignees

Comments

@chasewalden
Copy link
Contributor

Initial Checks

Description

Was trying to use one of the Nova foundation models on Bedrock, but ran into issues with tool-calling and structured output.

The Nova models seem to be a bit more strict (or less capable, depending who you ask) with regards to tool schemas. The top-level schema must be "type": "object" and the only fields allowed are "type", "properties", and "required". All other fields are disallowed and result in a hard API error.

See the second NOTE on the Nova docs page

Its a pretty annoying limitation, but means that many of the fields that Pydantic generates with the JSON Schema are not allowed. Most critically, `"$defs" are not allowed, so the schema would need to be transformed somehow to allow tool calling.

I know Nova is probably low-priority (and I seem to recall reading somewhere that Anthropic Bedrock was the main use-case for now), but there is nothing that would indicate that this wouldn't work. This might need to be called out in the docs and/or generate a warning/error when trying to use tools and structured output with a Nova model.

Example Code

class Something(BaseModel):
   foo: str
   bar: list[int]

class SomethingElse(BaseModel):
    something: Something
    extra: dict[str, str]

agent = Agent(
    model="bedrock:us.amazon.nova-pro-v1:0", 
    # model="bedrock:us.amazon.nova-lite-v1:0",   # or this
    # model="bedrock:us.amazon.nova-micro-v1:0",  # or this
    instructions="You are a helpful assistant.",
    output_type=Something,
)

@agent.tool_plain
def frobnicate(something_else: SomethingElse):
   print({something_else=!r})

_ = agent.run_sync("frobnicate, and then do what you need to do...")

Python, Pydantic AI & LLM client version

`python>=3.13`
`pydantic-ai==0.1.8`
`pydantic==2.11.3`
`boto3==1.38.4` (Bedrock)
@DouweM
Copy link
Contributor

DouweM commented May 1, 2025

We already implement something similar for OpenAI at https://github.com/pydantic/pydantic-ai/blob/main/pydantic_ai_slim/pydantic_ai/models/openai.py#L967 and Gemini at https://github.com/pydantic/pydantic-ai/blob/main/pydantic_ai_slim/pydantic_ai/models/gemini.py#L764, so I'm not surprised other models need something similar.

We'd be open to a PR that performs a similar transformation for Bedrock, without changing the behavior of the schema, as we shouldn't cripple the schema just for Nova if other models do behave fine with the current complete schemas.

If that's not going to be possible since this is very model-specific, you can see if you can use the schema_generator attribute on Tool (and argument to @agent.tool_plain) to point at a custom generator, that can wrap the default GenerateToolJsonSchema. Once #1474 lands, you'd also be able to modify the ToolDefinition's parameters_json_schema in one place. If you don't want to pass schema_generator manually on all agent.tool_plain calls, you could define your own decorator which calls that one with the additional property.

@DouweM DouweM self-assigned this May 1, 2025
@aristideubertas
Copy link

@DouweM I have also experienced this problem, would you be able to give a snippet of your reccomended approach? Or if something could be added to the docs.

This is also model specific, not Bedrock-wide, because Claude works fine.

@chasewalden
Copy link
Contributor Author

@DouweM , overriding the schema generator seems like it'll work fine for tools but will not work for structured output.

@tamir-alltrue-ai
Copy link

tamir-alltrue-ai commented May 5, 2025

Can confirm that this also affects llama models served on bedrock.

With Llama-3.3-70B I'm able to get structured output, but not tool calls.

@DouweM
Copy link
Contributor

DouweM commented May 8, 2025

@aristideubertas @chasewalden @tamir-alltrue-ai I've shared an example of a similar JSON schema modification to make Qwen on Together.ai work with the OpenAIModel at #1659 (comment). Let me know if you're having trouble adjusting it for BedrockModel. You may need to add additional transformations besides everything _OpenAIJsonSchema does + prefer_inlined_defs. I suggest having a look at the classes for OpenAI and Gemini I linked in my previous comment.

If you get something to work, please share it here. As I mentioned in #1649 (comment), it may be time to start having model-specific logic in the BedrockModel class, possibly by separating the concept of the API from that of the underlying model. We've seen a similar need with OpenAIModel, which is used for many different models on OpenAI-compatible APIs, that don't always support exactly the same schemas as OpenAI's models, or features of OpenAI's API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants