spring-ai icon indicating copy to clipboard operation
spring-ai copied to clipboard

[WIP] Add possibility to register functions in a type-safe manner

Open pgerhard opened this issue 1 year ago • 1 comments

Goal: The goal of this PR is to extend the existing function registration methods to also accept types of beans. The advantage would be that this is type-safe. A type-safe interface improves intelli-sense and refactoring

Things to Do:

  • [ ] Testing, before implementing any tests I would be interest in receiving feedback the approach in general

Discussion Points for this PR:

Should there be multiple factory methods for the ChatClient.Builder? So far I've overloaded the existing factory method and provided a SimpleNameResolver for use in existing calls

General Design Question:

At a higher level I am also wondering about how to register functions in general. The existing model make heavy use of annotations and conventions (e.g. a function must be a java.util.Function). This clearly works, however issues non-obvious issues (e.g. missing @Description annotation) are discovered at runtime. Personally I feel that this is not a great developer experience, especially for people new to the using spring-ai. My preference would be to surface this kind of errors as quickly as possible. A way to address this could be to provide an interface that has to be implemented by beans that should be available as functions for the LLM

pgerhard avatar May 29 '24 13:05 pgerhard

Hi Christian (@tzolov),

As discussed i've updated the PR with a way to define functions via a factory class. Compared to my initial implementation using the BeanNameResolver this feels like a more consistent approach. However, as I mentioned in my comment (see Tools) the different ways that functions are currently handled by the ChatClient makes this more difficult to do. I think a discussion around how we can have a more consistent approach to adding functions to the ChatClient might be helpful If you have some time to discuss this just let me know (also open to jumping on a call)

pgerhard avatar Jun 05 '24 06:06 pgerhard

Thanks for your PR! Declarative tool definition via annotation has been introduced in https://github.com/spring-projects/spring-ai/pull/2064, making it possible to pass to ChatClient an object containing @Tool-annotated methods. Does that handle your use case?

Example:

class MyTools {

    @Tool(description = "Get the list of books written by the given author available in the library")
    List<Book> booksByAuthor(String author) {
        return bookService.getBooksByAuthor(new Author(author));
    }

}
@GetMapping("/chat")
String chat(String authorName) {
    return chatClient.prompt()
            .user("What books written by %s are available in the library?".formatted(authorName))
            .tools(myTools)
            .call()
            .content();
}

ThomasVitale avatar Jan 27 '25 20:01 ThomasVitale

Closing as I believe the new featues in Spring AI address this use case. Thanks for the contribution @pgerhard , please let us know if some use-case is not addressed in the current code base.

markpollack avatar Mar 13 '25 12:03 markpollack