Skip to content

PromptTemplate throwing "The template string is not valid" when using Structured Output unless escaped #1849

Closed
@jrgleason

Description

@jrgleason

Bug description
I have the following code...

       private final BeanOutputConverter<TransactionRecord> transactionRecordConverter;
       ...
       this.transactionRecordConverter = new BeanOutputConverter<>(TransactionRecord.class);
       ...
       PromptTemplate promptTemplate = new PromptTemplate("""
                    Given the following transaction details, check if the values are correct especially the category and business name. If you can't add value to the record than just return and empty message. 
                    Please do not include any other than the JSON string. I should be able to parse the response as json.
                    The transaction is: {transaction}
                    The response should be a json string in the following format.
                    {format}
                """);
        Map<String, Object> templateVars = new HashMap<>();
        templateVars.put("transaction", transaction.toString());
        templateVars.put("format", transactionRecordConverter.getFormat());
        Prompt prompt = promptTemplate.create(templateVars);
        String response = openAiClient.prompt(prompt).call().content();

When I run I get

org.stringtemplate.v4.compiler.STException: null
   at org.stringtemplate.v4.compiler.Compiler.reportMessageAndThrowSTException(Compiler.java:224) ~[ST4-4.3.4.jar:na]
   at org.stringtemplate.v4.compiler.Compiler.compile(Compiler.java:154) ~[ST4-4.3.4.jar:na]
   at org.stringtemplate.v4.STGroup.compile(STGroup.java:514) ~[ST4-4.3.4.jar:na]
   at org.stringtemplate.v4.ST.<init>(ST.java:162) ~[ST4-4.3.4.jar:na]
   at org.stringtemplate.v4.ST.<init>(ST.java:156) ~[ST4-4.3.4.jar:na]

From this.st = new ST(this.template, '{', '}');

The full template is available here

Environment
Latest 1.0 and I am running on Spring Boot with Java 23

Steps to reproduce
I don't have publicly available code that reproduces it but I will try to create something soon. In the meantime you should be able to use the raw gist in the PromptTemplate here...

try {
  this.st = new ST(this.template, '{', '}');
  for (Entry<String, Object> entry : model.entrySet()) {
    add(entry.getKey(), entry.getValue());
  }
}

And you should be able to reproduce

Expected behavior
I would expect to be able to run the prompt without the failure. If I remove the {format} the prompt completes.

Workaround

I can get it to work if I use...

String jsonSchema = transactionRecordConverter.getFormat()
                                                      .replace("{", "\\{")
                                                      .replace("}", "\\}");
templateVars.put("format", jsonSchema);                                                      

But in the docs it says I shouldn't need to escape

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions