spring-projects / spring-ai

An Application Framework for AI Engineering
https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/index.html
Apache License 2.0
2.13k stars 477 forks source link

PromptTemplate validation prevents using arrays in templates. #631

Closed eschnou closed 2 weeks ago

eschnou commented 3 weeks ago

Bug description Attempting to iterate on a list of item in a PromptTemplate leads to the following error. This is due to the validation being too restrictive and interpreting the token used for iterating on the array as a required input.

java.lang.IllegalStateException: All template variables were not replaced. Missing variable names are [item]

Environment Spring AI 0.8.1

Steps to reproduce

The following unit test fails:

    @Test
    public void testPromptRendering() {
        String templateString = "The items are:\n{items:{item | - {item}\n}}";
        List<String> itemList = Arrays.asList("apple", "banana", "cherry");
        PromptTemplate promptTemplate = new PromptTemplate(templateString);
        Message message = promptTemplate.createMessage(Map.of("items", itemList));

        String expected = "The items are:\n" +
                "- apple\n" +
                "- banana\n" +
                "- cherry\n";

        assertEquals(expected, message.getContent());
    }

Expected behavior

The same pattern used directly within a template does work. I would expect the same to be used within a PromptTemplate.

    @Test
    public void testTemplateRendering() {
        String templateString = "The items are:\n{items:{item | - {item}\n}}";
        List<String> itemList = Arrays.asList("apple", "banana", "cherry");

        ST template = new ST(templateString, '{' , '}');
        template.add("items", itemList);

        String expected = "The items are:\n" +
                "- apple\n" +
                "- banana\n" +
                "- cherry\n";
        String result = template.render();

        assertEquals(expected, result);
    }
thesurlydev commented 2 weeks ago

I have a fix for this and will open a PR shortly.

markpollack commented 2 weeks ago

@thesurlydev do you have any opinions on this issue - https://github.com/spring-projects/spring-ai/issues/355 ?

thesurlydev commented 2 weeks ago

@markpollack I read through the comments and I see advantages to both the default delimeters and the current adoption of curly braces. Normally, I'd just go with the ST default but I do like the curly braces because they align better with other Python frameworks in terms of prompt placeholders.

Ultimately, my preference would be to continue using curly braces as the default delimiters but also provide the option to override via configuration.