ChatML是一种事实标准(de facto standard),但尚无统一的工业标准。

📝 什么是ChatML?

ChatML(Chat Markup Language,聊天标记语言)-是OpenAI为ChatGPT模型设计的结构化对话格式-。它用特殊标记符来区分对话中的不同角色:

text

<|im_start|>system
你是一个ERP助手
<|im_end|>
<|im_start|>user
帮我查一下库存
<|im_end|>
<|im_start|>assistant
好的,正在查询...
<|im_end|>
  • 角色明确:每条消息都通过<|im_start|>{role}的头部信息,清楚标明是系统(system)、用户(user)还是助手(assistant)-。

  • 边界清晰:通过<|im_start|><|im_end|>这对特殊标记符-,精确界定了每条消息的起始和结束-。

📜 它是“标准”吗?

1. 是“事实标准”(de facto standard)
ChatML已被Qwen(通义千问) 等众多开源模型采用-,也是HuggingFace模型的默认聊天格式-,开发者常将其作为通用格式-。

2. 但并非“官方标准”
OpenAI曾表示ChatML仍在演进中-,目前没有一个国际标准组织(如ISO、IEEE)将其采纳为正式标准。

🌍 现在有提示词的“工业标准”吗?

目前还没有一个统一的全球工业标准,但多个组织和机构正在积极推动标准化工作:

  • 中国国家标准(GB/T):GB/T 45288.1-2025标准明确定义了提示词--14,另有意见稿在规范提示词工程技术--12

  • 国际标准化尝试:IETF(互联网工程任务组)提出了PLPES草案--19,试图为提示词建立正式规范--19

  • 行业/企业层面的最佳实践:微软提出了清晰、有背景等核心原则-;社区也有CO-STAR框架-和“提示即代码”-等探索。

💎 总结

目前,提示词工程领域正从“艺术”向“工程”转变。对中国开发者而言,可以重点关注GB/T 45288.1-2025等国内标准-14;在企业内部,则可以参考微软、Anthropic等公司的指南-建立自己的规范。

虽然统一的全球标准尚未成熟,但主动拥抱这些正在形成的规范,无疑能让你在AI应用开发中更具前瞻性和竞争力。

ChatML(Chat Markup Language,聊天标记语言)是由OpenAI提出,用于结构化对话的事实标准--14。它本质是一种受XML启发的、基于特殊标记符的纯文本格式-。

它的核心思想很简单:通过特定的“开始”和“结束”标记,将对话清晰地划分为多个独立的消息。

📝 ChatML 核心格式

一条完整的ChatML提示由多条消息组成,每条消息的格式都遵循以下结构--2

<|im_start|>{role}\n{content}<|im_end|>

  • <|im_start|>:特殊标记,表示一条新消息的开始--2

  • {role}:消息的发送者角色,主要有system(系统)、user(用户)、assistant(助手)-。

  • \n:换行符,用于分隔角色和消息内容-。

  • {content}:消息的具体文本内容-。

  • <|im_end|>:特殊标记,表示这条消息的结束-。

💡 一个完整的对话示例

一个包含系统设定、用户提问和助手回复的完整对话,看起来是这样的:

text

<|im_start|>system
You are a helpful AI assistant for ERP system.<|im_end|>
<|im_start|>user
请帮我查询一下上个月的销售总额。<|im_end|>
<|im_start|>assistant
好的,正在为您查询上个月的销售总额...<|im_end|>

⚙️ 进阶应用:与Tool Calling集成

它还能用于更复杂的场景,比如Tool Calling(工具调用)-13

text

<|im_start|>user
What's the weather like in Paris?<|im_end|>
<|im_start|>assistant
<tool_call>
{"name": "get_weather", "arguments": {"city": "Paris"}}
</tool_call><|im_end|>
<|im_start|>tool
{"city": "Paris", "temperature": "15", "unit": "celsius"}<|im_end|>
<|im_start|>assistant
The current weather in Paris is 15°C.<|im_end|>

⚖️ ChatML vs. 其他格式

  • Alpaca:单轮指令微调格式,核心是instruction/input/output三元组-14。适合翻译、摘要等简单任务-14

  • ShareGPT:用conversations列表模拟多轮对话,结构更复杂--14。适合构建聊天机器人--14

  • ChatML:用messages列表和role字段区分角色,是当前行业事实标准--14。适合复杂对话和Tool Calling-14

💎 核心总结

  • 显式标记:明确标识消息边界和发送者角色,让模型更容易理解复杂的对话结构-2

  • 广泛兼容:被Qwen(通义千问)--1Hermes-13等众多开源模型采用,也是Hugging Face的默认聊天模板之一-。

  • 进阶应用:原生支持Tool Calling(工具调用) 等复杂交互模式-13

  • 工业级标准:在多轮对话、工具调用等场景,ChatML是最佳实践之一--14

建议你在Spring AI中,优先使用框架自带的apply_chat_template方法,而非手动拼接字符串,以避免出错--14

apply_chat_template方法具体怎么使用

apply_chat_template 并不是 Spring AI 框架的原生方法,它是 Hugging Face Transformers 库中 Tokenizer 对象的一个方法-。

在 Spring AI 项目中,通常有两种方式来使用它:一是直接调用 Hugging Face 的 API,二是完全在本地进行推理。

🤔 为什么需要它?

不同的大模型(如 ChatML、Qwen 等)要求的对话输入格式各不相同-。apply_chat_template 的作用就是自动将你结构化的对话消息,转换成对应模型所期望的、包含特定控制符的字符串格式-。

🧪 方式一:调用 Hugging Face 推理端点 (API)

这种方式将格式化的任务放在云端,适合不想管理本地模型的场景。

  1. 添加依赖:在 pom.xml 中加入 Spring AI 为 Hugging Face 提供的 starter-11

    xml

    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-huggingface-starter</artifactId>
        <version>1.0.0-M5</version>
    </dependency>
  2. 配置连接:在 application.yml 中配置 API Token 和端点-。

  3. 注入并调用:直接注入 Spring AI 自动配置好的 ChatClient 进行调用-11。在这种方式下,格式化的工作由 Hugging Face 服务端自动完成,你无需手动调用 apply_chat_template

💻 方式二:完全本地推理 (Hugging Face + Java)

这种方式更为灵活,你可以直接在 Java 中加载模型并手动调用 apply_chat_template

添加依赖:在 pom.xml 中加入 Hugging Face 的核心库。

xml

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-transformers</artifactId>
</dependency>

代码实现:在 Spring Bean 中,通过 Python 或直接调用 Java 绑定的方式来使用 apply_chat_template-。

java

// 伪代码示例,具体实现取决于你使用的 Java 推理库
@Service
public class LocalAIService {

    public String formatPrompt() {
        // 1. 加载模型和分词器 (Tokenizer)
        // 2. 准备你的对话消息
        List<Map<String, String>> messages = List.of(
            Map.of("role", "system", "content", "你是一个ERP助手"),
            Map.of("role", "user", "content", "帮我查一下库存")
        );
        // 3. 调用 apply_chat_template 生成模型所需的最终提示词字符串[reference:9][reference:10]
        // String finalPrompt = tokenizer.apply_chat_template(messages, false, true);
        // 4. 将 finalPrompt 发送给模型进行推理
        return null;
    }
}

⚠️ 注意事项

  • 不是 Spring AI 方法apply_chat_template 是 Hugging Face 的 Python 方法,在 Java 中需要通过其 Java 绑定或 JNI 等方式调用。

  • 空列表会报错:传入空的消息列表会导致 IndexError-。

  • 注意角色名称:消息的 role 字段必须使用 systemuserassistant 等标准值-。

  • 本质是 Jinja 模板:聊天模板基于 Jinja 模板引擎编写,可以通过 print(tokenizer.chat_template) 查看原始模板。

理解 apply_chat_template 的本质,能帮你更好地把握模型输入格式化的关键环节。你是打算直接调用 Hugging Face 的云端 API,还是想完全在本地进行推理呢?

那直接使用spring ai 标注的提示词写法怎么写需要注意什么

在 Spring AI 中,不要将 Prompt 视为一个巨大的文本字符串,而应将其看作一个由多条消息(Message)组成的结构化容器-1。官方建议采用 ChatClient 的流式 API 来构建提示词--10

📝 核心消息类型

在 Spring AI 中,提示词通过区分角色来界定不同语义层次--2

  • SystemMessage(系统消息):设定 AI 的全局角色、性格和长期行为边界--2。例如:“你是一个严谨的 Java 架构师。”

  • UserMessage(用户消息):承载当前具体的用户问题或任务,是每次请求的核心-2

  • AssistantMessage(助手消息):AI 的回复,主要用于维护多轮对话的历史上下文-2

  • ToolResponseMessage(工具响应):AI 调用工具后,工具执行完返回的结果-2

💻 基本写法示例

使用 ChatClient 的流式 API,通过链式调用清晰区分不同角色--1

java

String result = chatClient.prompt()
        .system("你是一位资深的Java工程师,回答需简洁准确,使用中文。") // 1. 设定系统消息[reference:13][reference:14]
        .user(u -> u
            .text("请帮我分析一个Spring Boot项目结构。约束:1. 只讨论Java项目 2. 项目背景:{context}")
            .param("context", "团队已有Spring Boot基础,没有AI经验") // 2. 动态注入参数[reference:15]
        )
        .options(ChatOptions.builder()
            .temperature(0.3) // 3. 配置生成参数[reference:16]
            .build()
        )
        .call()
        .content(); // 4. 执行调用并获取结果[reference:17]

🧩 动态提示词与模板化

可以使用 PromptTemplate 将常用提示词模板化,提高可维护性-4

  • 基础用法:创建模板后用 Map 填充占位符-4

  • 系统消息模板SystemPromptTemplate 专门用于创建动态的系统消息-4-10

  • 外部文件:将复杂模板放在 src/main/resources/prompts/ 下,用 ClassPathResource 加载-18

⚠️ 五大注意事项(避坑指南)

  1. 分离 System 和 User:不要把系统指令和用户问题混在一个大字符串里-1

  2. 使用 ChatOptions 控制参数temperaturemaxTokens 等生成参数应通过 .options() 设置-1-。

  3. 警惕占位符冲突:模板用 {},若提示词本身含 JSON 且带 {},需对 JSON 内的花括号进行转义,或使用其他分隔符-1

  4. 利用 Advisor 管理上下文:不要手动将聊天历史、RAG 结果拼入 Prompt,应使用 Advisor 自动管理-。

  5. 使用 BeanOutputConverter 获取结构化输出:不要用文字要求 AI 返回 JSON,应使用转换器-,让 AI 严格按 Schema 返回。

想了解 Advisor 如何具体管理对话历史,或者 BeanOutputConverter 强制结构化输出的更多细节

Logo

AtomGit AI 社区提供模型库、数据集、Agent、Token等资源

更多推荐