Message

AI提示词

  • 提示词是引导AI进行特定的处理及生成的输入,高效的提示词可以显著提升AI的处理及响应。
  • 这里要记录的并不是提示词深入的概念,也不是如何设计高效的提示词,最起码首要目标不是这些。
  • 而是学习和记录如何使用SpringAI提供的API快速的、灵活的将提示词编入程序与AI进行交互。
  • 其实早在入门篇中就已经记录到了,且在过去的案例里面也基本都是用到了,不过都相对简单。

回顾前面的案例

ChatClient

  • 在学习SpringAI记录的第一个案例中(如下)我们就已经使用到了提示词

    1
    2
    3
    4
    // 创建一个 client
    ChatClient chatClient = ChatClient.create(chatModel);
    // 调用 deepseek
    String content = chatClient.prompt().system(SYSTEM_PROMPT).user(userMessage).call().content();
  • 使用ChatClient在调用call()方法之前就通过设置system、user消息作为提示词来与AI交互。

  • 通过简单查看源码发现最后是创建了SystemMessageUserMessage

    image

Advisor

  • 还有在记录Advisor(三)中的“提示词增强”的PromptEnhancementExampleAdvisor中使用到的如下代码。

    1
    2
    3
    chatClientRequest.prompt()
    .augmentSystemMessage(systemMessage -> SystemMessage.builder().text(sysMsg).build())
    .augmentUserMessage(userMessage -> UserMessage.builder().text(String.format(userTemplate, userMessage.getText())).build())
  • 上面的Code是通过ChatClientRequestsystem、user消息进行修改/增强后作为新的提示词与AI交互。

  • 这里也是使用的SystemMessageUserMessage来创建新的消息

Message家族

Message族谱

  • 下面是官方的类图

    Spring AI Message API

  • 从类图中可以看到被分成来消息Message和多媒体MediaContent两块,这里主要以Message为主,多媒体后续可能会在多模态继续记录到。

  • Message又通过MessageType来定义了四类角色的消息,除了已经接触到的system、user,还有assistant、tool(function)

    • system:用于表示向AI设定规则指令的输入。比如要求AI按指定结构输出的规则指令。还有比如要求AI是Java专家、小朋友科普老师等一些拟人行为的规则指令。
    • user:用于表示用户需求的输入。比如提问、要求AI处理或生成内容等需求性指令。
    • assistant:用于给AI作为上下文辅助的输入。
      • 比如与AI历史的对话内容确保AI的处理是在一个已有的上下文中进行;
      • 还有就是如果交互包含工具调用,那么在工具调用后补充内容给AI时需要将工具信息添加在assistant消息中,再结合tool消息共同使用。
    • tool(function):用于结合assistant消息一起将工具调用后的内容补充给AI的输入。(工具调用具体后面会继续学习记录)

案例1

  • 先使用system、user消息与AI正常交互,再使用assistant消息结合上下文

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    private final ChatClient promptClient;

    public void assistantExample() {
    log.info("\n=======================================第一次与AI正常交互=======================================");
    Prompt prompt = Prompt.builder()
    .messages(
    // 用英文作为系统提示词
    SystemMessage.builder().text("You are a Java expert").build(),
    // 用户输入了Deque类,默认也是英文
    UserMessage.builder().text("java.util.Deque").build()
    ).build();

    String content = promptClient.prompt(prompt).call().content();
    log.info("\n=======================================第二次结合上下文交互=======================================");
    Prompt assistantPrompt = Prompt.builder()
    .messages(
    // 用户再次要求使用中文输出
    UserMessage.builder().text("中文").build(),
    // 并将上一次的输出内容添加在assistant消息作为上下文
    new AssistantMessage(content)
    ).build();
    promptClient.prompt(assistantPrompt).call().content();
    }
  • 第一次交互结果,可以看到都是英文输出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    2025-07-01T17:25:52.824+08:00  INFO 12889 --- [spring-ai-example] [           main] c.s.a.e.prompt.PromptClientExample       : 
    =======================================第一次与AI正常交互=======================================
    2025-07-01T17:25:52.876+08:00 INFO 12889 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
    Chat client request to AI
    prompt text -> You are a Java expertjava.util.Deque
    context -> {
    "ClientName" : "promptClient"
    }
    2025-07-01T17:26:36.162+08:00 INFO 12889 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
    Chat client response from AI
    output text -> # `java.util.Deque` Interface in Java

    The `Deque` (pronounced "deck") interface in Java represents a double-ended queue, which is a linear collection that supports element insertion and removal at both ends. It extends the `Queue` interface and is part of the Java Collections Framework.

    ## Key Features

    - **Double-ended operations**: Supports insertion, removal, and examination at both head and tail
    - **Capacity-restricted implementations**: Some implementations (like `ArrayDeque`) have fixed size limits
    - **Null elements**: Most implementations don't allow null elements
    - **Not thread-safe**: Requires external synchronization for concurrent access
  • 第二次交互结果输出的部分就全是中文了,并且这次的提示词是包含第一次输出的英文结果的(就是AssistantMessage)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    2025-07-01T17:26:36.165+08:00  INFO 12889 --- [spring-ai-example] [           main] c.s.a.e.prompt.PromptClientExample       : 
    =======================================第二次结合上下文交互=======================================
    2025-07-01T17:26:53.887+08:00 INFO 12889 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
    Chat client request to AI
    prompt text -> 中文# `java.util.Deque` Interface in Java

    The `Deque` (pronounced "deck") interface in Java represents a double-ended queue, which is a linear collection that supports element insertion and removal at both ends. It extends the `Queue` interface and is part of the Java Collections Framework.

    ## Key Features

    - **Double-ended operations**: Supports insertion, removal, and examination at both head and tail
    - **Capacity-restricted implementations**: Some implementations (like `ArrayDeque`) have fixed size limits
    - **Null elements**: Most implementations don't allow null elements
    - **Not thread-safe**: Requires external synchronization for concurrent access
    2025-07-01T17:27:40.511+08:00 INFO 12889 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
    Chat client response from AI
    output text -> # Java中的`java.util.Deque`接口

    `Deque`(发音为"deck")是Java中的双端队列接口,它代表了一个支持在两端插入和移除元素的线性集合。它扩展了`Queue`接口,是Java集合框架的一部分。

    ## 核心特性

    - **双端操作**:支持在头部和尾部进行插入、移除和检查操作
    - **容量限制**:某些实现(如`ArrayDeque`)有固定大小限制
    - **空元素**:大多数实现不允许null元素
    - **非线程安全**:需要外部同步来实现并发访问

案例2

  • 在与AI交互的时候,可能会用到工具调用来增强AI的能力。这时候与AI交互的过程中就需要用到assistanttool两个角色的消息了。

  • 这里简单模拟一个工具调用的案例,然后大概看看SpringAI是如何将工具调用的结果补充给AI的。

    • 创建一个模拟获取天气的工具类,写死返回张家界的天气信息。(这里不做过多记录,后面会专门学习工具调用)

      1
      2
      3
      4
      5
      6
      public class MockGetWeather {
      @Tool(name = "mockGetWeather", description = "获取一个位置的天气,但需要先提供一个位置")
      public String mockGetWeather(@ToolParam(description = "城市,如长沙市或湖南省长沙市") String location) {
      return "{\"location\":{\"name\":\"张家界\",\"path\":\"中国, 湖南, 张家界\"},\"now\":{\"precipitation\":0,\"temperature\":31.5,\"pressure\":1005,\"humidity\":43,\"windDirection\":\"西南风\",\"windDirectionDegree\":216,\"windSpeed\":2.7,\"windScale\":\"微风\",\"feelst\":23.1}}";
      }
      }
    • 添加工具调用

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      public void toolExample() {
      String content = promptClient.prompt()
      // 这里只是做了一层封装,与 SystemMessage.builder() 是一样的,底层还是用的 SystemMessage
      .system("你是一个万能的小助手")
      // 这里也是封装了,底层是 UserMessage
      .user("帮我查询张家界今天天气如何?")
      // 添加工具调用
      .tools(new MockGetWeather())
      .call()
      .content();
      }
    • 调用结果。是可以看到这些天气数据是与模拟天气工具中返回的数据是一致的。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      2025-07-01T18:31:26.544+08:00  INFO 14325 --- [spring-ai-example] [           main] c.s.a.e.advisor.three.LogExampleAdvisor  : 
      Chat client request to AI
      prompt text -> 你是一个万能的小助手帮我查询张家界今天天气如何?
      context -> {
      "ClientName" : "promptClient"
      }
      2025-07-01T18:31:37.199+08:00 INFO 14325 --- [spring-ai-example] [ main] c.s.a.e.advisor.three.LogExampleAdvisor :
      Chat client response from AI
      output text -> 张家界今天的天气情况如下:

      - **温度**: 31.5°C
      - **体感温度**: 23.1°C
      - **降水概率**: 0%
      - **气压**: 1005 hPa
      - **湿度**: 43%
      - **风向**: 西南风(216°)
      - **风速**: 2.7 m/s(微风)

      天气晴朗,适合出行!
      context -> {ClientName=promptClient}

  • 简单看了一下SpringAI与AI交互的过程,下图就是执行工具的大概过程,可以看到其实就是使用AssistantMessageToolResponseMessage

    image

总结

  • 可以通过提示词来约束、要求AI按照特定的规则处理及生成;也可以显著提升、增强AI的处理能力。
  • SpringAI与AI交互的提示词主要是通过Message来实现结构化。
  • 四类角色的Message分别在不同的角度使用提示词来增强AI的能力。
  • 工具调用的消息是需要AssistantMessageToolResponseMessage结合使用的,否则可能会报错。

最后

  • 工具调用相关的后续会继续学习记录如何使用。
  • SpringAI还提供了提示词更多的操作在下一篇继续记录,如提示词模版。
  • 所有案例的源码,都会提交在GitHub上。包:com.spring.ai.example.prompt.one