-
Notifications
You must be signed in to change notification settings - Fork 1.7k
ToolCallingChatOptions support internalToolExecutionMaxIterations, to limit the maximum number of tool calls and prevent infinite recursive calls to LLM in special cases #3380
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
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
thanks, one comment is that we need to preserve api compatability and
would need to be an overload vs adding a new method parameter. |
Signed-off-by: lambochen <lambochen@yeah.net>
Your suggestion is great, I'll optimize it, thanks |
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
Hi, @markpollack @tzolov , the PR is ready, please review it, thank you. If there are any issues or if additional content is needed, please to comment, and I will promptly correct or supplement it. thank you |
...-ai-model/src/main/java/org/springframework/ai/model/tool/DefaultToolCallingChatOptions.java
Outdated
Show resolved
Hide resolved
/** | ||
* No limit for tool execution attempts. | ||
*/ | ||
int TOOL_EXECUTION_NO_LIMIT = Integer.MAX_VALUE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say it's a mistake that no limit was set in the original implementation. I would consider having a lower value as the default limit. We should think of a good default value here that avoids infinite loops.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree with your point. To ensure downward compatibility, I have used Integer.MAX_VALUE (a very large number) to indicate no limit.
I tend to prefer setting a smaller value to limit the number of executions and the scope of impact on the program, but I don't have specific comparative data. If you have suggestions, please feel free to share them. Thank you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tzolov what do you think? Should we keep it unbounded (i.e infinite loop) or find a good default value?
spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolCallingChatOptions.java
Outdated
Show resolved
Hide resolved
Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
@ThomasVitale Hi, I have optimized the code and replied to your suggestion. Please re-review this PR. Thank you for your hard work. |
Thank you @lambochen for picking this up. This would be a very helpful change with tool calling. |
Signed-off-by: lambochen <lambochen@yeah.net>
Thanks @lambochen! I agreed on handling the infinite loop risk, but, IMO, should consider:
@lambochen , @ThomasVitale what do you think? |
Thanks! @tzolov
I agree, should we also consider other strategies?
That's great, introducing ToolExecutionRequest will make the logic much cleaner. |
I don't think we need this flexibility right now. I can't see a use case where "silently return the last tool response" would be helpful. Also, this change needs to work with Let's save strategy support for a future PR if we find compelling reasons for it. |
I'll have a look tomorrow at the updated PR and share my comments then. Thanks! |
@tzolov Thank you for your reply, I agree with your point, I will optimize the code and resubmit, thank you |
…tool calling Signed-off-by: lambochen <lambochen@yeah.net>
Hi, @tzolov |
…Checker#isLimitExceeded Signed-off-by: lambochen <lambochen@yeah.net>
spring-ai-model/src/main/java/org/springframework/ai/model/tool/ToolCallingChatOptions.java
Outdated
Show resolved
Hide resolved
* @param toolExecutionIterations The number of toolExecutionIterations | ||
* @return true if the tool execution limit has been exceeded, false otherwise | ||
*/ | ||
default boolean isLimitExceeded(ChatOptions promptOptions, int toolExecutionIterations) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a public API or a utility method?
* @param toolExecutionIterations The number of toolExecutionIterations | ||
* @return true if the tool execution limit has been exceeded, false otherwise | ||
*/ | ||
default boolean isLimitExceeded(ChatOptions promptOptions, int toolExecutionIterations) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question here as in ToolExecutionEligibilityChecker
. Should this be a public API or a utility method?
I would suggest moving this to ToolCallingChatOptions
as a static method, similar to other utilities we have there to deal with tool execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, @ThomasVitale ,Thank you for your comment, your considerations are very valuable.
Regarding this issue, I think both are acceptable.
As a public API, it opens up possibilities for users to extend, allowing users to be more flexible when implementing ToolExecutionEligibilityPredicate, of course, this is on the premise that users expect to implement isLimitExceeded.
As a utility method, it's also a good design that can meet the business's customization for ToolExecutionEligibilityPredicate (by implementing the isToolExecutionRequired method). It's equivalent to users only needing to be aware of the isToolExecutionRequired SPI method, which would be more concise.
What do you think?
Signed-off-by: lambochen <lambochen@yeah.net>
…onMaxIterations Signed-off-by: lambochen <lambochen@yeah.net>
Signed-off-by: lambochen <lambochen@yeah.net>
This PR primarily addresses the issue of infinite recursive calls to LLM under certain special conditions, with internalToolExecutionEnabled=true in place, ref issue: #3333.
By introducing support for toolExecutionMaxIterations in ToolCallingChatOptions and performing call count checks in each ChatModel, interrupt the process when the maximum call count is reached.
[x] Sign the contributor license agreement
[x] Rebase your changes on the latest
main
branch and squash your commits[x] Add/Update unit tests as needed
[x] Run a build and make sure all tests pass prior to submission