spring-ai
spring-ai copied to clipboard
The system message is the second to last message
Bug description Why is the system message the second to last message, not the first? This arrangement yields notably distinct effects from the large language model compared to when the system message is placed at the beginning of the messages list.(I used ai to translate my issues, so please forgive me if there was any tone or emotion involved in my issues.)
Environment The following code initially retrieves historical messages, then appends system messages, and finally appends user messages. Consequently, the system message is positioned as the second-to-last item in the messages list.
org.springframework.ai.chat.client.advisor.api.AdvisedRequest:
public Prompt toPrompt() {
var messages = new ArrayList<>(this.messages());
String processedSystemText = this.systemText();
if (StringUtils.hasText(processedSystemText)) {
if (!CollectionUtils.isEmpty(this.systemParams())) {
processedSystemText = new PromptTemplate(processedSystemText, this.systemParams()).render();
}
messages.add(new SystemMessage(processedSystemText));
}
String formatParam = (String) this.adviseContext().get("formatParam");
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()));
}
... ...
}
Steps to reproduce Perform multiple rounds of conversation on the same conversation
Expected behavior The SystemMessage should be placed as the first item in the messages when passed to the large model. Or, developers should be allowed to customize this situation.
Minimal Complete Reproducible example
@SpringBootTest
class ErrorTest {
@Autowired
ChatClient chatClient;
@Test
void testError() {
String sessionId = "123";
for (int i = 0; i < 10; i++) {
String content = chatClient.prompt()
.system("""
You are an assistant.
""")
.advisors(advisor -> advisor
.param("chat_memory_conversation_id", sessionId)
.param("chat_memory_response_size", 100))
.user("hello")
.call()
.content();
System.out.println(content);
}
}
}