spring-ai
spring-ai copied to clipboard
Create GenerativeTextTemplate that streamlines usage of AiClient, Prompts, and OutputParsers
There is an analogy to make between GenerationTemplate and JdbcTemplate that will help simplify the use of the lower level classes such as AiClient, Prompts, and OutputParsers. Note: AiClient should likely be renamed GenerationClient as it is focused on generation, specifcally text, so perhaps even TextGenerationClient as we haven't yet experimented with multi-modal apis.
DataSource <-> AiClient
String Query with placeholdres <-> Prompt with placeholders
RowMapper <-> OutputParser
The simplest method (which is a default method in AiClient) is string input and string output, that could be removed from the AiClient interface and used in GenerateTemplate instead. Here are a few sample signatures for consideration.
public interface GenerateOperations {
String generate(String message);
String generate(String message, Map<String, Object> model)
String generate(PromptTemplate promptTemplate, Map<String, Object> model);
<T> T generate(String message, Class<T> elementType, Map<String, Object> model);
<T> T generate(String message, OutputParser<T> parser, Map<String, Object> model);
<T> List<T> generateList(String message, Class<T> elementType, Map<String, Object> model);
<T> List<T> generateList(String message, OutputParser<T> parser, Map<String, Object> model);
AiResponse generateResponse(PromptTemplate promptTemplate, Map<String, Object> model);
}
Example usage
ActorsFilms actorsFilms = generateTemplate.generate("Generate the filmography for the actor {actor}",
ActorsFilms.class, Map.of("actor", "Tom Hanks"));
Simple "chains" for flows can be done with standard Java functional programming, and we can see how our needs for a "chain" or a "flow" evolve over time. e.g. the example of a chain from langchain using functional programming
@Test
void functionalChains() {
Function<String, String> combinedFunction = generateSynopsis.andThen(generateReview);
System.out.println(combinedFunction.apply("Tragedy at sunset on the beach"));
}
private Function<String, String> generateSynopsis = title -> {
String synopsisInput = """
You are a playwright. Given the title of play, it is your job to write a synopsis for that title.
Title: {title}
Playwright: This is a synopsis for the above play:""";
return generateTemplate.generate(synopsisInput, Map.of("title", title));
};
private Function<String, String> generateReview = synopsis -> {
String synopsisInput = """
You are a play critic from the New York Times. Given the synopsis of play, it is your job to write a review for that play.
Play Synopsis:
{synopsis}
Review from a New York Times play critic of the above play:""";
return generateTemplate.generate(synopsisInput, Map.of("synopsis", synopsis));
};
As a note, a new issue to create a 'GenerateTextOperation' class that has a fluent api, akin to SimpleJdbcCall
and company
this has been addressed with the fluent api in the updated chatclient.