Atoti Intelligence Essentials
This is part of the Atoti Intelligence Essentials offer.The timeout guard
atoti.ai.prompt-timeout bounds a whole prompt, whatever the provider does underneath it. When it
expires, the prompt is abandoned, the run reports a timeout, and the partial answer is dropped from
the conversation history so the next prompt does not build on an answer nobody saw.
The LLM retry guard
The provider’s own client re-sends a failed request rather than reporting it immediately. It is the right place for that decision: it backs off between attempts, and it does not retry a request it already knows is hopeless, such as an authentication failure or a malformed request. What it is not is uniform: each provider reads a different property, and counts differently.atoti.ai.max-attempts is the one to reach for. It is a number of attempts, the first one included,
and Atoti translates it into whatever the provider serving the call reads:
Declaring
atoti.ai.max-attempts wins over spring.ai.retry.max-attempts, wherever that is
declared — application.yml, an environment variable, a command-line argument. Leaving it out
hands the decision back: a spring.ai.retry.max-attempts an application declares then stands, so a
deployment already tuned per provider keeps its tuning. With neither declared, the default of 5
attempts applies to every provider, over Spring AI’s own 10.AWS_MAX_ATTEMPTS reaches it, but process-wide. To make that number reachable, Atoti supplies the
two Bedrock runtime clients that Spring AI would otherwise build itself, carrying every
spring.ai.bedrock.aws.* timeout over unchanged. An application that declares a
BedrockRuntimeClient or BedrockRuntimeAsyncClient bean of its own keeps it, and is then
responsible for that client’s retry policy. So does one that excludes Spring AI’s Bedrock
auto-configuration: Atoti’s clients stand down with it, and the SDK’s own default of 3 attempts
applies again.
Whichever provider is configured, the timeout guard bounds the retries too: they all happen inside
one prompt.
Retrying the whole prompt
Above the provider sits the chat’s own loop,atoti.ai.max-retry-attempts. It defaults to 1, so
the prompt is sent once and the retrying is left to the provider, which backs off between attempts
and does not retry a request it already knows is hopeless — neither of which this loop can do.
The no-progress guards
Two guards stop a prompt that is getting nowhere, both by answering the model rather than running the tool: it reads why it was stopped and writes the explanation the user sees.Repeated tool calls
A tool called with the very same arguments, back to back, returns the very same result, so calling it again makes no progress. Pastatoti.ai.max-consecutive-identical-tool-calls times in a
row, the call is not run again: the model is told it was just made and returned the same thing, and
it does something else instead.
Tool errors
A model varying its arguments every round never repeats itself, so the guard above never sees it. What it does collect is failures. Onceatoti.ai.max-tool-errors tool calls have failed in
one prompt, no further tool call is run: the model is told to stop and answer the user with what it
has.
max-retry-attempts retries included. An attempt that
spent it does not get it back by being run again.
The last resort
Refusing a call answers the model, which then decides what to do next. A model may simply ask for the same call again. Because each of those rounds is one more call to the model, a run in whichatoti.ai.max-consecutive-refused-rounds rounds in a row ran no tool at all is ended
outright, and the user is told the question could not be answered.
All five
atoti.ai properties above are validated at startup: prompt-timeout must not be
negative and accepts zero to mean no deadline; max-retry-attempts,
max-consecutive-identical-tool-calls, max-tool-errors and max-consecutive-refused-rounds must
each be at least 1. A value outside those ranges stops the application from starting rather than
surfacing on someone’s first question.Transport timeouts
The transport timeouts sit below every guard above, and bound the retries as well as the first attempt. For Amazon Bedrock they are thespring.ai.bedrock.aws.* properties, timeout above all:
it caps the whole call including its retries. See
Set up Amazon Bedrock in Java.
Atoti Python SDK
AiConfig.max_attempts sits next to the connection rather than inside it, because it applies to
whichever provider the session connects to.