te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>openai api - Why is template variable resolution performed twice? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

openai api - Why is template variable resolution performed twice? - Stack Overflow

programmeradmin4浏览0评论

I have a application, which calls OpenAI chat. My users can enter text, which is used to create the prompt. The result should be a Java object, see Structured Output Converter.

Unfortunatly, Spring AI is resolving the variables in the template twice. This causes an error, if an user uses some special characters.

Code

@SpringBootApplication
public class MyTestApp {

  public static void main(String[] args) {
    SpringApplication.run(MyTestApp.class, args);
  }

  @Data
  class Result {
    private String text;
  }

  @Controller
  @AllArgsConstructor
  class MyTestService {

    private final ChatClient chatClient;

    @GetMapping("/test")
    public void test() {

      final PromptTemplate promptTemplate = new PromptTemplate("{userInput}");
      final Prompt prompt = promptTemplate.create(Map.of("userInput", "{test}"));

      final Result result =
          chatClient.prompt(prompt).advisors(new SimpleLoggerAdvisor()).call().entity(Result.class);
    }
  }
}

Log

java.lang.IllegalStateException: Not all template variables were replaced. Missing variable names are [test]
    at .springframework.ai.chat.prompt.PromptTemplate.validate(PromptTemplate.java:232) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.prompt.PromptTemplate.render(PromptTemplate.java:125) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.advisor.api.AdvisedRequest.toPrompt(AdvisedRequest.java:171) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultChatClientRequestSpec$1.aroundCall(DefaultChatClient.java:675) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.lambda$nextAroundCall$1(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.14.3.jar:1.14.3]
    at .springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.nextAroundCall(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.advisor.SimpleLoggerAdvisor.aroundCall(SimpleLoggerAdvisor.java:99) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.lambda$nextAroundCall$1(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.14.3.jar:1.14.3]
    at .springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.nextAroundCall(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetChatResponse(DefaultChatClient.java:488) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.lambda$doGetObservableChatResponse$1(DefaultChatClient.java:477) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.14.3.jar:1.14.3]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetObservableChatResponse(DefaultChatClient.java:477) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doSingleWithBeanOutputConverter(DefaultChatClient.java:451) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.entity(DefaultChatClient.java:446) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]

Question

Why is Spring AI resolving variables twice? Is there any predefined method to escape the user input?

I have a application, which calls OpenAI chat. My users can enter text, which is used to create the prompt. The result should be a Java object, see Structured Output Converter.

Unfortunatly, Spring AI is resolving the variables in the template twice. This causes an error, if an user uses some special characters.

Code

@SpringBootApplication
public class MyTestApp {

  public static void main(String[] args) {
    SpringApplication.run(MyTestApp.class, args);
  }

  @Data
  class Result {
    private String text;
  }

  @Controller
  @AllArgsConstructor
  class MyTestService {

    private final ChatClient chatClient;

    @GetMapping("/test")
    public void test() {

      final PromptTemplate promptTemplate = new PromptTemplate("{userInput}");
      final Prompt prompt = promptTemplate.create(Map.of("userInput", "{test}"));

      final Result result =
          chatClient.prompt(prompt).advisors(new SimpleLoggerAdvisor()).call().entity(Result.class);
    }
  }
}

Log

java.lang.IllegalStateException: Not all template variables were replaced. Missing variable names are [test]
    at .springframework.ai.chat.prompt.PromptTemplate.validate(PromptTemplate.java:232) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.prompt.PromptTemplate.render(PromptTemplate.java:125) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.advisor.api.AdvisedRequest.toPrompt(AdvisedRequest.java:171) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultChatClientRequestSpec$1.aroundCall(DefaultChatClient.java:675) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.lambda$nextAroundCall$1(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.14.3.jar:1.14.3]
    at .springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.nextAroundCall(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.advisor.SimpleLoggerAdvisor.aroundCall(SimpleLoggerAdvisor.java:99) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.lambda$nextAroundCall$1(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.14.3.jar:1.14.3]
    at .springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.nextAroundCall(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetChatResponse(DefaultChatClient.java:488) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.lambda$doGetObservableChatResponse$1(DefaultChatClient.java:477) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.14.3.jar:1.14.3]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetObservableChatResponse(DefaultChatClient.java:477) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doSingleWithBeanOutputConverter(DefaultChatClient.java:451) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]
    at .springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.entity(DefaultChatClient.java:446) ~[spring-ai-core-1.0.0-M5.jar:1.0.0-M5]

Question

Why is Spring AI resolving variables twice? Is there any predefined method to escape the user input?

Share Improve this question asked Feb 17 at 12:23 durdur 17k26 gold badges88 silver badges143 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

Spring AI adds additional processing to handle structured output.

The toPrompt() method of AdvisedRequest includes the following code:

var processedUserText = StringUtils.hasText(formatParam)
        ? this.userText() + System.lineSeparator() + "{spring_ai_soc_format}" : this.userText();

if (StringUtils.hasText(processedUserText)) {
    Map<String, Object> userParams = new HashMap<>(this.userParams());
    if (StringUtils.hasText(formatParam)) {
        userParams.put("spring_ai_soc_format", formatParam);
    }
    if (!CollectionUtils.isEmpty(userParams)) {
        processedUserText = new PromptTemplate(processedUserText, userParams).render();
    }
    messages.add(new UserMessage(processedUserText, this.media()));
}

In this code, an additional rendering step is applied to process the {spring_ai_soc_format} placeholder. This causes one more render() call.

发布评论

评论列表(0)

  1. 暂无评论