Spring AI Alibaba 入门开发-提示词功能、提示词模板、格式化输出(备份)
前置内容Spring AI Alibaba 入门开发一-CSDN博客一、提示词Prompt——基础1.1 介绍Prompt 是引导 AI 模型生成特定输出的输入格式Prompt 的设计和措辞会显著影响模型的响应。Prompt 最开始只是简单的字符串随着时间的推移prompt 逐渐开始包含特定的占位符例如 AI 模型可以识别的 “USER:”、“SYSTEM:” 等。阿里云通义模型可通过将多个消息字符串分类为不同的角色然后再由 AI 模型处理为 prompt 引入了更多结构。每条消息都分配有特定的角色这些角色对消息进行分类明确 AI 模型提示的每个部分的上下文和目的。这种结构化方法增强了与 AI 沟通的细微差别和有效性因为 prompt 的每个部分在交互中都扮演着独特且明确的角色。Prompt 中的主要角色Role包括系统角色System Role指导 AI 的行为和响应方式设置 AI 如何解释和回复输入的参数或规则。这类似于在发起对话之前向 AI 提供说明。用户角色User Role代表用户的输入 - 他们向 AI 提出的问题、命令或陈述。这个角色至关重要因为它构成了 AI 响应的基础。助手角色Assistant RoleAI 对用户输入的响应。这不仅仅是一个答案或反应它对于保持对话的流畅性至关重要。通过跟踪 AI 之前的响应其“助手角色”消息系统可确保连贯且上下文相关的交互。助手消息也可能包含功能工具调用请求信息。它就像 AI 中的一个特殊功能在需要执行特定功能例如计算、获取数据或不仅仅是说话时使用。工具/功能角色Tool/Function Role工具/功能角色专注于响应工具调用助手消息返回附加信息。1.2 API 概览Prompt通常使用 ChatModel 的 call() 方法该方法接受 Prompt 实例并返回 ChatResponse。Prompt 类充当有组织的一系列 Message 对象和请求 ChatOptions 的容器。每条消息在提示中都体现了独特的角色其内容和意图各不相同。这些角色可以包含各种元素从用户查询到 AI 生成的响应再到相关背景信息。这种安排可以实现与 AI 模型的复杂而详细的交互因为提示是由多条消息构成的每条消息都被分配了在对话中扮演的特定角色。下面是 Prompt 类的截断版本为简洁起见省略了构造函数和实用方法public class Prompt implements ModelRequestListMessage { private final ListMessage messages; private ChatOptions chatOptions; }MessageMessage 接口封装了一个提示文本、一组元数据属性以及一个称为 MessageType 的分类。该接口定义如下public interface Content { String getContent(); MapString, Object getMetadata(); } public interface Message extends Content { MessageType getMessageType(); }Message 接口的各种实现对应 AI 模型可以处理的不同类别的消息。模型根据对话角色区分消息类别。1.3 提示词的四个角色角色在 Spring AI 中表示为枚举public enum MessageType { USER(user), ASSISTANT(assistant), SYSTEM(system), TOOL(tool); }具体实现类如下各角色功能如下SYSTEM设定AI行为边界/角色/定位。指导AI的行为和响应方式设置AI如何解释和回复输入的.USER用户原始提问输入。代表用户的输入他们向AI提出的问题、命令或陈述。ASSISTANTAI返回的响应信息定义为”助手角色”消息。用它可以确保上下文能够连贯的交互且记忆对话积累回答。TOOL桥接外部服务可以进行函数调用如支付/数据查询等操作类似调用第3方util工具类后面章节详细介绍。总结如下1.4 开发新建子工程项目结构如下1、修改pom.xmldependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !--spring-ai-alibaba dashscope-- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId /dependency !--lombok-- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId version1.18.38/version /dependency !--hutool-- dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.22/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId version3.11.0/version configuration compilerArgs arg-parameters/arg /compilerArgs source21/source target21/target /configuration /plugin /plugins /build repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositories2、新增配置文件server.port8888 #解决中文乱码 server.servlet.encoding.charsetUTF-8 server.servlet.encoding.enabledtrue server.servlet.encoding.forcetrue spring.application.namessa-05-Prompt #Sprig AI Alibaba 相关配置 spring.ai.dashscope.api-key${qianwen-api} spring.ai.dashscope.base-urlhttps://ws-6tq01jo6mtthlhoq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1 #spring.ai.dashscope.chat.options.modelqwen-max3、新增启动类SpringBootApplication public class SSA_05_Prompt_Application { public static void main(String[] args) { SpringApplication.run(SSA_05_Prompt_Application.class, args); } }4、新增配置类——多模型共存、并分别创建ChatModel和ChatClient对象Configuration public class LLMConfig { //定义各个模型名称 private final String DEEPSEEK_MODEL deepseek-v4-pro; private final String QWEN_MODEL qwen-max; //创建deepseekChatModel Bean(name deepseekChatModel) public ChatModel deepseekChatModel() { return DashScopeChatModel.builder().dashScopeApi( DashScopeApi.builder().apiKey(System.getenv(qianwen-api)).build()) .defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build()) .build(); } //创建qwenChatModel Bean(name qwenChatModel) public ChatModel qwenChatModel() { return DashScopeChatModel.builder() .dashScopeApi(DashScopeApi.builder().apiKey(System.getenv(qianwen-api)).build()) .defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build()) .build(); } //创建deepseekChatClient Bean(name deepseekChatClient) public ChatClient deepseekChatClient(Qualifier(deepseekChatModel) ChatModel deepseek) { return ChatClient.builder(deepseek) .defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build()).build(); } //创建qwenChatClient Bean(name qwenChatClient) public ChatClient qwenChatClient(Qualifier(qwenChatModel) ChatModel qwen) { return ChatClient.builder(qwen) .defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build()).build(); } }5、创建Controller——设置SYSTEMRestController public class Prompt_V1_Controller { //创建deepseekChatModel Resource(name deepseekChatModel) private ChatModel deepseekChatModel; //创建qwenChatModel Resource(name qwenChatModel) private ChatModel qwenChatModel; //创建deepseekChatClient Resource(name deepseekChatClient) private ChatClient deepseekChatClient; //创建qwenChatClient Resource(name qwenChatClient) private ChatClient qwenChatClient; //使用SYSTEM角色 GetMapping(/v1/chat) public FluxString chat(String msg){ return deepseekChatClient.prompt() .system(你是一位历史学家只回答历史问题。其他问题则回复我是一位历史学家只回答历史问题) .user(msg) .stream() .content(); } }6、运行结果如下7、修改controller——使用ChatModel调用注意返回类型。GetMapping(/v2/chat) public FluxChatResponse chat2(String msg){ UserMessage userMessage new UserMessage(msg); SystemMessage systemMessage new SystemMessage(你是一位历史学家只回答历史问题。其他问题则回复我是一位历史学家只回答历史问题); Prompt prompt new Prompt(userMessage, systemMessage); return qwenChatModel.stream(prompt); }8、修改controller——设置ASSISTANT注意返回类型//使用ASSISTANT角色 GetMapping(/v3/chat) public String chat3(String msg){ AssistantMessage assistantMessage deepseekChatClient.prompt() .user(msg) .call() .chatResponse() .getResult() .getOutput(); return assistantMessage.getText(); }9、使用TOOL——模拟调用后面章节会演示//使用tool模拟调用第三方接口 GetMapping(/v4/chat) public String chat4(String city){ String answer deepseekChatClient.prompt() .user(city 明天天气如何?) .call() .chatResponse() .getResult() .getOutput() .getText(); ToolResponseMessage toolResponseMessage new ToolResponseMessage( List.of(new ToolResponseMessage.ToolResponse(1,获得天气,city)) ); String toolResponse toolResponseMessage.getText(); return answer toolResponse; }二、提示词Prompt——模板引入占位符(如{占位符变量名})以动态插入内容。2.1 API介绍Prompt TemplateSpring AI 中用于提示模板的关键组件是 PromptTemplate 类。该类使用 Terence Parr 开发的 OSS StringTemplate 引擎来构建和管理提示。PromptTemplate 类旨在促进结构化提示的创建然后将其发送到 AI 模型进行处理public class PromptTemplate implements PromptTemplateActions, PromptTemplateMessageActions { // Other methods to be discussed later }该类实现的接口支持提示创建的不同方面PromptTemplateStringActions 专注于创建和呈现提示字符串代表提示生成的最基本形式。PromptTemplateMessageActions 专门用于通过生成和操作 Message 对象来创建提示。PromptTemplateActions 旨在返回 Prompt 对象该对象可以传递给 ChatModel 以生成响应。虽然这些接口可能在许多项目中没有得到广泛使用但它们展示了创建提示的不同方法。实现的接口是public interface PromptTemplateMessageActions { Message createMessage(); Message createMessage(ListMedia mediaList); Message createMessage(MapString, Object model); }方法 String render()将提示模板渲染为最终字符串格式无需外部输入适用于没有占位符或动态内容的模板。方法 String render(MapString, Object model)增强渲染功能以包含动态内容。它使用 MapString, Object其中映射键是提示模板中的占位符名称值是要插入的动态内容。public interface PromptTemplateMessageActions { Message createMessage(); Message createMessage(ListMedia mediaList); Message createMessage(MapString, Object model); }方法 Message createMessage()创建一个不带附加数据的 Message 对象用于静态或预定义消息内容。方法 Message createMessage(List mediaList)创建一个带有静态文本和媒体内容的 Message 对象。方法 Message createMessage(MapString, Object model)扩展消息创建以集成动态内容接受 MapString, Object其中每个条目代表消息模板中的占位符及其对应的动态值。public interface PromptTemplateActions extends PromptTemplateStringActions { Prompt create(); Prompt create(ChatOptions modelOptions); Prompt create(MapString, Object model); Prompt create(MapString, Object model, ChatOptions modelOptions); }方法 Prompt create()生成不带外部数据输入的 Prompt 对象非常适合静态或预定义提示。方法 Prompt create(ChatOptions modelOptions)生成一个 Prompt 对象无需外部数据输入但具有聊天请求的特定选项。方法 Prompt create(MapString, Object model)扩展提示创建功能以包含动态内容采用 MapString, Object其中每个映射条目都是提示模板中的占位符及其关联的动态值。方法 Prompt create(MapString, Object model, ChatOptions modelOptions)扩展提示创建功能以包含动态内容采用 MapString, Object其中每个映射条目都是提示模板中的占位符及其关联的动态值以及聊天请求的特定选项。2.2 开发1、新增子模块修改pom.xml、新增配置文件、新增配置类、新增启动类与第一部分一样不再赘述。相关代码如下dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !--spring-ai-alibaba dashscope-- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId /dependency !--lombok-- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId version1.18.38/version /dependency !--hutool-- dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.22/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId version3.11.0/version configuration compilerArgs arg-parameters/arg /compilerArgs source21/source target21/target /configuration /plugin /plugins /build repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositoriesserver.port8888 #解决中文乱码 server.servlet.encoding.charsetUTF-8 server.servlet.encoding.enabledtrue server.servlet.encoding.forcetrue spring.application.namessa-06-PromptTemplata #Sprig AI Alibaba 相关配置 spring.ai.dashscope.api-key${qianwen-api} spring.ai.dashscope.base-urlhttps://ws-6tq01jo6mtthlhoq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1 #spring.ai.dashscope.chat.options.modelqwen-maxConfiguration public class LLMConfig { //定义各个模型名称 private final String DEEPSEEK_MODEL deepseek-v4-pro; private final String QWEN_MODEL qwen-max; //创建deepseekChatModel Bean(name deepseekChatModel) public ChatModel deepseekChatModel() { return DashScopeChatModel.builder().dashScopeApi( DashScopeApi.builder().apiKey(System.getenv(qianwen-api)).build()) .defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build()) .build(); } //创建qwenChatModel Bean(name qwenChatModel) public ChatModel qwenChatModel() { return DashScopeChatModel.builder() .dashScopeApi(DashScopeApi.builder().apiKey(System.getenv(qianwen-api)).build()) .defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build()) .build(); } //创建deepseekChatClient Bean(name deepseekChatClient) public ChatClient deepseekChatClient(Qualifier(deepseekChatModel) ChatModel deepseek) { return ChatClient.builder(deepseek) .defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build()).build(); } //创建qwenChatClient Bean(name qwenChatClient) public ChatClient qwenChatClient(Qualifier(qwenChatModel) ChatModel qwen) { return ChatClient.builder(qwen) .defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build()).build(); } }SpringBootApplication public class SSA_06_PromptTemplate { public static void main(String[] args) { SpringApplication.run(SSA_06_PromptTemplate.class, args); } }RestController public class PromptTemplateController { //创建deepseekChatModel Resource(name deepseekChatModel) private ChatModel deepseekChatModel; //创建qwenChatModel Resource(name qwenChatModel) private ChatModel qwenChatModel; //创建deepseekChatClient Resource(name deepseekChatClient) private ChatClient deepseekChatClient; //创建qwenChatClient Resource(name qwenChatClient) private ChatClient qwenChatClient; GetMapping(/v1/chat) public FluxString chat1(String topic,String output_format,String wordCount){ PromptTemplate promptTemplate new PromptTemplate( 讲一个关于{topic}的故事 并以{output_format}格式输出, 字数控制在{wordCount}以内。 ); Prompt prompt promptTemplate.create(Map.of(topic, topic, output_format, output_format, wordCount, wordCount)); return deepseekChatClient.prompt(prompt).stream().content(); } }2、PromptTemplate读取模版文件实现模版功能。在/resource下新建路径存放模板文件修改controllerRestController public class PromptTemplateController { //创建deepseekChatModel Resource(name deepseekChatModel) private ChatModel deepseekChatModel; //创建qwenChatModel Resource(name qwenChatModel) private ChatModel qwenChatModel; //创建deepseekChatClient Resource(name deepseekChatClient) private ChatClient deepseekChatClient; //创建qwenChatClient Resource(name qwenChatClient) private ChatClient qwenChatClient; Value(classpath:/prompt-template/01-template.txt) private org.springframework.core.io.Resource template; GetMapping(/v1/chat) public FluxString chat1(String topic,String output_format,String wordCount){ PromptTemplate promptTemplate new PromptTemplate( 讲一个关于{topic}的故事 并以{output_format}格式输出, 字数控制在{wordCount}以内。 ); Prompt prompt promptTemplate.create(Map.of(topic, topic, output_format, output_format, wordCount, wordCount)); return deepseekChatClient.prompt(prompt).stream().content(); } GetMapping(/v2/chat) public FluxString chat2(String topic,String output_format,String wordCount){ PromptTemplate promptTemplate new PromptTemplate(template); Prompt prompt promptTemplate.create(Map.of(topic, topic, output_format, output_format, wordCount, wordCount)); return deepseekChatClient.prompt(prompt).stream().content(); } }3、多角色设定//系统消息SystemMessage:设定AI的行为规定和功能边界 // 用户消息用户的提问 GetMapping(/v3/chat) public String chat3(String sysTopic,String userTopic){ SystemPromptTemplate systemPromptTemplate new SystemPromptTemplate( 你是{systemTopic}助手只回答{systemTopic}其他无可奉告以markdown格式的结果返回。 ); Message sysMessage systemPromptTemplate.createMessage(Map.of(systemTopic, sysTopic)); PromptTemplate userPromptTemplate new PromptTemplate(解释一下{userTopic}); Message userMessage userPromptTemplate.createMessage(Map.of(userTopic, userTopic)); Prompt prompt new Prompt(List.of(sysMessage, userMessage)); return deepseekChatClient.prompt(prompt).call().content(); }4、分别使用ChatModel和ChatClient实现PromptTemplate人物设定GetMapping(/v4/chat) public String chat4(String msg){ //系统信息 SystemMessage systemMessage new SystemMessage(你是一位历史学家拒绝回答非历史问题); //用户信息 UserMessage userMessage new UserMessage(msg); //完整提示词 系统信息 用户信息 Prompt prompt new Prompt(systemMessage, userMessage); //调用大模型 return deepseekChatModel.call(prompt).getResult().getOutput().getText(); } GetMapping(v5/chat) public FluxString chat5(String msg){ return deepseekChatClient.prompt() .system(你是一位历史学家拒绝回答非历史问题) .user(msg) .stream().content(); }三、格式化输出(Structured Output)3.1 介绍Structured Output 可以协助将ChatModel/ChatClient方法的返回类型从 String 更改为其他类型。LLM 生成结构化输出的能力对于依赖可靠解析输出值的下游应用程序非常重要。开发人员希望快速将 AI 模型的结果转换为可以传递给其他应用程序函数和方法的数据类型例如 JSON、XML 或 Java 类。Spring AI 结构化输出转换器有助于将 LLM 输出转换为结构化格式。在 LLM 调用之前转换器会将期望的输出格式output format instruction附加到 prompt 中为模型提供生成所需输出结构的明确指导这些指令充当蓝图塑造模型的响应以符合指定的格式。在 LLM 调用之后转换器获取模型的输出文本并将其转换为结构化类型的实例此转换过程涉及解析原始文本输出并将其映射到相应的结构化数据表示例如 JSON、XML 或特定于域的数据结构。当前 Spring AI 提供的 Converter 实现有AbstractConversionServiceOutputConverter,AbstractMessageOutputConverter,BeanOutputConverter,MapOutputConverterandListOutputConverter。BeanOutputConverter - 使用指定的 Java 类例如 Bean或 ParameterizedTypeReference 配置此转换器指示 AI 模型生成符合 DRAFT_2020_12 的 JSON 响应JSON 模式派生自指定的 Java 类随后它利用 ObjectMapper 将 JSON 输出反序列化为目标类的 Java 对象实例。MapOutputConverter - 该实现指导 AI 模型生成符合 RFC8259 的 JSON 响应此外它还包含一个转换器实现该实现利用提供的 MessageConverter 将 JSON 负载转换为 java.util.MapString, Object 实例。ListOutputConverter - 该实现指导 AI 模型生成逗号分隔的格式化输出最终转换器将模型文本输出转换为 java.util.List。3.2 开发1、创建子模块修改pom.xml新增启动类、配置文件、配置类。代码分别如下dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !--spring-ai-alibaba dashscope-- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId /dependency !--hutool-- dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.22/version /dependency !--lombok-- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId version1.18.38/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId version3.11.0/version configuration compilerArgs arg-parameters/arg /compilerArgs source21/source target21/target /configuration /plugin /plugins /build repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositoriesSpringBootApplication public class SSA_07_StrucOutputApplication { public static void main(String[] args) { SpringApplication.run(SSA_07_StrucOutputApplication.class, args); } }server.port8888 #解决中文乱码 server.servlet.encoding.charsetUTF-8 server.servlet.encoding.enabledtrue server.servlet.encoding.forcetrue spring.application.namessa-07-StrucOutput #Sprig AI Alibaba 相关配置 spring.ai.dashscope.api-key${qianwen-api} spring.ai.dashscope.base-urlhttps://ws-6tq01jo6mtthlhoq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1 #spring.ai.dashscope.chat.options.modelqwen-maxConfiguration public class LLMConfig { //定义各个模型名称 private final String DEEPSEEK_MODEL deepseek-v4-pro; private final String QWEN_MODEL qwen-max; //定义配置API-KEY的环境变量 private final String API_KEY qianwen-api; //创建deepseekChatModel Bean(name deepseekChatModel) public ChatModel deepseekChatModel() { return DashScopeChatModel.builder() .dashScopeApi(DashScopeApi.builder().apiKey(System.getenv(API_KEY)).build()) .defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build()) .build(); } //创建qwenChatModel Bean(name qwenChatModel) public ChatModel qwenChatModel() { return DashScopeChatModel.builder() .dashScopeApi(DashScopeApi.builder().apiKey(System.getenv(API_KEY)).build()) .defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build()) .build(); } //创建deepseekChatClient Bean(name deepseekChatClient) public ChatClient deepseekChatClient(Qualifier(deepseekChatModel) ChatModel chatModel) { return ChatClient.builder(chatModel) .defaultOptions(DashScopeChatOptions.builder().withModel(DEEPSEEK_MODEL).build()) .build(); } //创建qwenChatClient Bean(name qwenChatClient) public ChatClient qwenChatClient(Qualifier(qwenChatModel) ChatModel chatModel) { return ChatClient.builder(chatModel) .defaultOptions(DashScopeChatOptions.builder().withModel(QWEN_MODEL).build()) .build(); } }2、新增recordpublic record EmperorInfoRecord(String name,String country,Integer lifespan) { }3、新增controllerRestController public class StrucOutPutController { //创建deepseekChatModel Resource(name deepseekChatModel) private ChatModel deepseekChatModel; //创建qwenChatModel Resource(name qwenChatModel) private ChatModel qwenChatModel; //创建deepseekChatClient Resource(name deepseekChatClient) private ChatClient deepseekChatClient; //创建qwenChatClient Resource(name qwenChatClient) private ChatClient qwenChatClient; GetMapping(/v1/chat) public EmperorInfoRecord chat1(String name,String country,Integer lifespan) { return qwenChatClient.prompt() .user(new ConsumerChatClient.PromptUserSpec() { Override public void accept(ChatClient.PromptUserSpec promptUserSpec) { promptUserSpec.text(姓名{name},国号{country},寿命:{lifespan}岁) .param(name,name) .param(country,country) .param(lifespan,lifespan); } }).call().entity(EmperorInfoRecord.class); } //函数式写法 GetMapping(/v2/chat) public EmperorInfoRecord chat2(String name,String country,Integer lifespan) { String template 姓名{name},国号{country},寿命:{lifespan}岁 ; return qwenChatClient.prompt() .user(promptUserSpec -promptUserSpec.text(template) .param(name,name) .param(country,country) .param(lifespan,lifespan)) .call().entity(EmperorInfoRecord.class); } }

相关新闻

用遍所有AI论文工具[特殊字符]终于摸清稳过审的底层逻辑|OKBIYE真的不一样

用遍所有AI论文工具[特殊字符]终于摸清稳过审的底层逻辑|OKBIYE真的不一样

2026写论文真的别再盲目跟风用免费AI了! 之前为了省事,轮番试过各类通用大模型、平价论文AI,本想高效搞定论文,结果踩坑无数:要么AI检测直接高危、要么文献造假翻车、要么模板太重被导师一眼识破,反复返修…

2026/9/24 0:04:38 阅读更多 →
从零搭建自动驾驶训练数据:跟着 LMDrive 走通 7 个环节

从零搭建自动驾驶训练数据:跟着 LMDrive 走通 7 个环节

从零搭建自动驾驶训练数据:跟着 LMDrive 走通 7 个环节 【免费下载链接】LMDrive [CVPR 2024] LMDrive: Closed-Loop End-to-End Driving with Large Language Models 项目地址: https://gitcode.com/gh_mirrors/lm/LMDrive 想训练一辆由大语言模型驱动的自动…

2026/9/27 5:44:59 阅读更多 →
NCM文件打不开?ncmdump免费一键转MP3,零基础也能轻松搞定

NCM文件打不开?ncmdump免费一键转MP3,零基础也能轻松搞定

NCM文件打不开?ncmdump免费一键转MP3,零基础也能轻松搞定 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 深夜十一点,小林把车载U盘拔下来插回电脑,那几百首从网易云音乐下载的 .ncm 歌…

2026/9/27 22:09:57 阅读更多 →

最新新闻

替加环素广谱抗生素解析:从甘氨酰环素机制到 TaoToken 配置实践

替加环素广谱抗生素解析:从甘氨酰环素机制到 TaoToken 配置实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 22:56:56 阅读更多 →
UE32绿色版配置TaoToken:用*.reg文件手动增删注册表项

UE32绿色版配置TaoToken:用*.reg文件手动增删注册表项

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 22:56:56 阅读更多 →
AI工程的进化密码:Harness Engineering让模型调用不再是终点,Agent系统才是新起点!

AI工程的进化密码:Harness Engineering让模型调用不再是终点,Agent系统才是新起点!

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 22:56:56 阅读更多 →
汽车电子能力图谱:从电源树到CAN诊断的实战方法论

汽车电子能力图谱:从电源树到CAN诊断的实战方法论

1. 为什么“汽车电子知识大百科”不是一本词典,而是一套动态能力图谱 “汽车电子知识大百科”——光看标题,很多人第一反应是:哦,又一本堆砌术语的工具书?查查ESP、CAN总线、BMS这些词的定义就完事了?我干这…

2026/9/30 22:55:55 阅读更多 →
嵌入式Linux驱动开发实战:核心任务、调试技巧与学习路线

嵌入式Linux驱动开发实战:核心任务、调试技巧与学习路线

最近后台经常有人问我:“嵌入式驱动开发一天到晚在忙啥?”说实话,这个问题我刚入行的时候也想问。当时以为驱动工程师就是对着芯片手册敲寄存器,后来真干了几年才发现,写代码只是很小一部分,更多时间花在查…

2026/9/30 22:55:55 阅读更多 →
芯片按功能分类详解:从MCU、电源到AI加速器的选型地图

芯片按功能分类详解:从MCU、电源到AI加速器的选型地图

有没有在拆开某个电子产品之后,对着主板上密密麻麻的芯片发过呆?外形都是黑乎乎的小方块,引脚从几个到上千个不等,丝印型号更是五花八门。其实,一旦你掌握了“芯片按功能分类”这条主线,再乱的板子也能被拆…

2026/9/30 22:55:55 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/30 18:13:06 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/30 15:27:04 阅读更多 →