diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java index 13eab1370..a06827f39 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java @@ -1,7 +1,32 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.parser; import org.springframework.core.convert.support.DefaultConversionService; +/** + * Abstract {@link OutputParser} implementation that uses a pre-configured + * {@link DefaultConversionService} to convert the LLM output into the desired type + * format. + * + * @param Specifies the desired response type. + * @author Mark Pollack + * @author Christian Tzolov + */ public abstract class AbstractConversionServiceOutputParser implements OutputParser { private final DefaultConversionService conversionService; diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java index 2b5543228..01dbadaf1 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java @@ -1,7 +1,31 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.parser; import org.springframework.messaging.converter.MessageConverter; +/** + * Abstract {@link OutputParser} implementation that uses a pre-configured + * {@link MessageConverter} to convert the LLM output into the desired type format. + * + * @param Specifies the desired response type. + * @author Mark Pollack + * @author Christian Tzolov + */ public abstract class AbstractMessageConverterOutputParser implements OutputParser { private MessageConverter messageConverter; @@ -11,7 +35,7 @@ public abstract class AbstractMessageConverterOutputParser implements OutputP } public MessageConverter getMessageConverter() { - return messageConverter; + return this.messageConverter; } } diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/BeanOutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/BeanOutputParser.java index ca8f41807..919c4f456 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/parser/BeanOutputParser.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/BeanOutputParser.java @@ -1,3 +1,19 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.parser; import com.fasterxml.jackson.core.JsonProcessingException; @@ -14,6 +30,14 @@ import org.springframework.ai.prompt.PromptTemplate; import java.util.Map; import java.util.Objects; +/** + * {@link OutputParser} implementation that uses JSON schema to convert the LLM output + * into a desired object of type T. + * + * @param The target type to convert the output into. + * @author Mark Pollack + * @author Christian Tzolov + */ public class BeanOutputParser implements OutputParser { private String jsonSchema; diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/ListOutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/ListOutputParser.java index f863d29c7..c5a466ecf 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/parser/ListOutputParser.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/ListOutputParser.java @@ -1,11 +1,30 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.ai.parser; -import org.springframework.core.convert.support.DefaultConversionService; - import java.util.List; +import org.springframework.core.convert.support.DefaultConversionService; + /** - * Parse out a List from a formatting request to convert a + * {@link OutputParser} implementation that uses a {@link DefaultConversionService} to + * convert the LLM output into a {@link java.util.List} instance. + * + * @author Mark Pollack + * @author Christian Tzolov */ public class ListOutputParser extends AbstractConversionServiceOutputParser> { diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/MapOutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/MapOutputParser.java index 2b238b8f5..27e30b8d8 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/parser/MapOutputParser.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/MapOutputParser.java @@ -1,15 +1,36 @@ -package org.springframework.ai.parser; +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import org.springframework.messaging.Message; -import org.springframework.messaging.converter.MappingJackson2MessageConverter; -import org.springframework.messaging.support.MessageBuilder; +package org.springframework.ai.parser; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; +import org.springframework.messaging.Message; +import org.springframework.messaging.converter.MappingJackson2MessageConverter; +import org.springframework.messaging.support.MessageBuilder; + /** - * Uses Jackson + * {@link OutputParser} implementation that uses a pre-configured + * {@link MappingJackson2MessageConverter} to convert the LLM output into a + * java.util.Map<String, Object> instance. + * + * @author Mark Pollack + * @author Christian Tzolov */ public class MapOutputParser extends AbstractMessageConverterOutputParser> { diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/OutputParser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/OutputParser.java index b2cd14d33..4c8fc53c6 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/parser/OutputParser.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/OutputParser.java @@ -18,6 +18,15 @@ package org.springframework.ai.parser; import org.springframework.ai.prompt.FormatProvider; +/** + * Converts the (raw) LLM output into a structured responses of type. The + * {@link FormatProvider#getFormat()} method should provide the LLM prompt description of + * the desired format. + * + * @param Specifies the desired response type. + * @author Mark Pollack + * @author Christian Tzolov + */ public interface OutputParser extends Parser, FormatProvider { } diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/Parser.java b/spring-ai-core/src/main/java/org/springframework/ai/parser/Parser.java index 2f220ccf8..559473f08 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/parser/Parser.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/Parser.java @@ -1,3 +1,19 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.ai.parser; @FunctionalInterface diff --git a/spring-ai-core/src/main/java/org/springframework/ai/parser/README.md b/spring-ai-core/src/main/java/org/springframework/ai/parser/README.md new file mode 100644 index 000000000..72521d2cb --- /dev/null +++ b/spring-ai-core/src/main/java/org/springframework/ai/parser/README.md @@ -0,0 +1,12 @@ +# Output Parsing + +* [Documentation](https://docs.spring.io/spring-ai/reference/concepts.html#_output_parsing) +* [Usage examples](https://github.com/spring-projects-experimental/spring-ai/blob/main/spring-ai-openai/src/test/java/org/springframework/ai/openai/client/ClientIT.java) + +The output of AI models traditionally arrives as a java.util.String, even if you ask for the reply to be in JSON. It may be the correct JSON, but it isn’t a JSON data structure. It is just a string. Also, asking "for JSON" as part of the prompt isn’t 100% accurate. + +This intricacy has led to the emergence of a specialized field involving the creation of prompts to yield the intended output, followed by parsing the resulting simple string into a usable data structure for application integration. + +Output parsing employs meticulously crafted prompts, often necessitating multiple interactions with the model to achieve the desired formatting. + +This challenge has prompted OpenAI to introduce 'OpenAI Functions' as a means to specify the desired output format from the model precisely.