add beanoutput parser
This commit is contained in:
1
pom.xml
1
pom.xml
@@ -67,6 +67,7 @@
|
||||
<open-ai-client.version>0.12.0</open-ai-client.version>
|
||||
<azure-open-ai-client.version>1.0.0-beta.3</azure-open-ai-client.version>
|
||||
<jtokkit.version>0.6.1</jtokkit.version>
|
||||
<victools.version>4.31.1</victools.version>
|
||||
|
||||
<!-- documentation dependencies -->
|
||||
<io.spring.maven.antora-version>0.0.4</io.spring.maven.antora-version>
|
||||
|
||||
@@ -43,6 +43,24 @@
|
||||
<version>${jtokkit.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.victools</groupId>
|
||||
<artifactId>jsonschema-generator</artifactId>
|
||||
<version>4.31.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.victools</groupId>
|
||||
<artifactId>jsonschema-module-jackson</artifactId>
|
||||
<version>4.31.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.kjetland</groupId>-->
|
||||
<!-- <artifactId>mbknor-jackson-jsonschema_2.13</artifactId>-->
|
||||
<!-- <version>1.0.39</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.springframework.ai.parser;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.victools.jsonschema.generator.OptionPreset;
|
||||
import com.github.victools.jsonschema.generator.SchemaGenerator;
|
||||
import com.github.victools.jsonschema.generator.SchemaGeneratorConfig;
|
||||
import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
|
||||
import com.github.victools.jsonschema.generator.SchemaVersion;
|
||||
import org.springframework.ai.prompt.PromptTemplate;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BeanOutputParser<T> implements OutputParser<T> {
|
||||
|
||||
private String jsonSchema;
|
||||
|
||||
private Class clazz;
|
||||
|
||||
public BeanOutputParser(Class clazz) {
|
||||
Objects.requireNonNull(clazz, "Java Class can not be null;");
|
||||
this.clazz = clazz;
|
||||
generateSchema();
|
||||
}
|
||||
|
||||
private void generateSchema() {
|
||||
SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2020_12,
|
||||
OptionPreset.PLAIN_JSON);
|
||||
SchemaGeneratorConfig config = configBuilder.build();
|
||||
SchemaGenerator generator = new SchemaGenerator(config);
|
||||
JsonNode jsonSchema = generator.generateSchema(this.clazz);
|
||||
this.jsonSchema = jsonSchema.toPrettyString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T parse(String text) {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
return (T) objectMapper.readValue(text, this.clazz);
|
||||
}
|
||||
catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
|
||||
String raw = """
|
||||
Your response should be in JSON format.
|
||||
Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation.
|
||||
Here is the JSON Schema instance your output must adhere to in the enclosed markdown codeblock:
|
||||
```json
|
||||
{jsonSchema}
|
||||
```
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(raw);
|
||||
return promptTemplate.render(Map.of("jsonSchema", this.jsonSchema));
|
||||
}
|
||||
// {"type":"object","properties":{"answer":{"type":"string","description":"answer to
|
||||
// the user's question"},"source":{"type":"string","description":"source used to
|
||||
// answer the user's question, should be a
|
||||
// website."}},"required":["answer","source"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}
|
||||
//
|
||||
|
||||
}
|
||||
@@ -33,6 +33,18 @@
|
||||
<version>${open-ai-client.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.victools</groupId>
|
||||
<artifactId>jsonschema-generator</artifactId>
|
||||
<version>${victools.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.victools</groupId>
|
||||
<artifactId>jsonschema-module-jackson</artifactId>
|
||||
<version>${victools.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Framework -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.springframework.ai.openai.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ActorsFilms {
|
||||
|
||||
private String actor;
|
||||
|
||||
private List<String> movies;
|
||||
|
||||
public ActorsFilms() {
|
||||
}
|
||||
|
||||
public String getActor() {
|
||||
return actor;
|
||||
}
|
||||
|
||||
public void setActor(String actor) {
|
||||
this.actor = actor;
|
||||
}
|
||||
|
||||
public List<String> getMovies() {
|
||||
return movies;
|
||||
}
|
||||
|
||||
public void setMovies(List<String> movies) {
|
||||
this.movies = movies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ActorsFilms{" + "actor='" + actor + '\'' + ", movies=" + movies + '}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.ai.client.AiResponse;
|
||||
import org.springframework.ai.client.Generation;
|
||||
import org.springframework.ai.openai.testutils.AbstractIntegrationTest;
|
||||
import org.springframework.ai.parser.BeanOutputParser;
|
||||
import org.springframework.ai.parser.ListOutputParser;
|
||||
import org.springframework.ai.parser.MapOutputParser;
|
||||
import org.springframework.ai.prompt.Prompt;
|
||||
@@ -81,4 +82,22 @@ class ClientIntegrationTests extends AbstractIntegrationTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanOutputParser() {
|
||||
|
||||
BeanOutputParser<ActorsFilms> outputParser = new BeanOutputParser<>(ActorsFilms.class);
|
||||
|
||||
String format = outputParser.getFormat();
|
||||
String template = """
|
||||
Generate the filmography for a random actor.
|
||||
{format}
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = openAiClient.generate(prompt).getGeneration();
|
||||
|
||||
ActorsFilms actorsFilms = outputParser.parse(generation.getText());
|
||||
System.out.println(actorsFilms);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user