Day68-结构化Prompt设计:XML标签法/Markdown法/JSON Schema

发布时间:2026/9/8 16:08:44
Day68-结构化Prompt设计:XML标签法/Markdown法/JSON Schema 一、为什么 Prompt 必须结构化Prompt 的本质是自然语言版的接口契约。如果不结构化会出现 4 个真实的工程问题问题表现根因解析失败下游解析 JSON / Bean 时格式抖动模型输出的边界不规范难以 reviewPR 里 5000 字没人看得完没有分块、没有角色标签改动难追溯不记得当时为什么这么写改动位置和意图没标记多语言模型切换GPT-4o 好用换 Claude 翻车不同模型对格式的理解偏好不同结论把 Prompt 当代码写需要 module、role、constraint 三件套——这正是结构化方法的共同特征。下面三种方法分别对应读起来舒服、人类写起来高效、机器解析最稳三个目标。二、XML 标签法最稳的结构化方案XML 标签是 Anthropic 官方推荐的方式《Claude Prompt Engineering Guide》明确提到 XML 在 Claude 上表现优于 Markdown。它的核心思想是把 Prompt 切成有名字的分区。2.1 一个完整的 XML Prompt 模板role 你是一名资深 Java 性能调优工程师专精 JVM GC 和 Arthas 诊断。 /role context 应用的 JVM 参数-Xms4g -Xmx4g -XX:UseG1GC 应用的 QPS2000平均 RT50ms 线上出现的问题每 6 小时一次 Full GC每次 STW 800ms /context task 根据 context 提供的信息分析 Full GC 频繁的根因并给出可落地的调优方案。 /task constraints - 回答必须用中文 - 长度控制在 500 字以内 - 必须按根因分析 → 调优建议 → 验证步骤三段式输出 - 不要列超过 5 条建议每条都要量化收益 /constraints output_format ## 根因分析 - 3~5 条 ## 调优建议 - 建议 1具体参数 预期效果 - 建议 2... ## 验证步骤 1. ... /output_format为什么用 XML 而不是 Markdown首尾匹配的语义清晰context.../context一对标签就是一块语义完整的区域模型不会被同级的标题层级搞混。可嵌套context里可以再嵌jvm_params、qps适合多源信息融合。Claude 模型显著更稳Anthropic 官方基准测试中XML 标签法在 Claude 3.5/4 上的指令遵循率高 8%~15%。2.2 配合 Spring AI 的 StringTemplate 落地// XML 标签法的 Spring AI 落地——用 StringTemplate 把 XML 模板化 // 依赖spring-boot-starter-ai-openai-spring-boot-starter 1.0.0 Component public class XmlPromptJVMAdvisor { private final ChatClient chatClient; // 推荐把 XML 模板写在独立的 .st 文件里这里为演示内联在代码中 private static final String XML_TEMPLATE role 你是一名资深 Java 性能调优工程师专精 JVM GC 和 Arthas 诊断。 /role context JVM 参数{jvmArgs} QPS{qps}平均 RT{rtMs}ms 现象{symptom} /context task 根据 context 给出 GC 调优方案要求可落地。 /task constraints - 中文输出长度 ≤ 500 字 - 按根因 → 建议 → 验证三段式 - 建议不超过 5 条每条量化收益 /constraints ; public XmlPromptJVMAdvisor(ChatClient.Builder builder) { this.chatClient builder.build(); } public String advise(String jvmArgs, int qps, int rtMs, String symptom) { String prompt XML_TEMPLATE .replace({jvmArgs}, jvmArgs) .replace({qps}, String.valueOf(qps)) .replace({rtMs}, String.valueOf(rtMs)) .replace({symptom}, symptom); return chatClient.prompt() .user(prompt) .call() .content(); } }老梁踩坑模板里如果想强调某个变量不能用b标签——模型会原样输出b。强调用重要二字包一层或用critical这种语义化标签不要用 HTML 的b/strong/i。三、Markdown 法人类阅读体验最好Markdown 法是 LLM 训练数据里最常见的格式GitHub、知乎、技术博客全是 Markdown模型对它天然友好适合给人类同事看的 Prompt 文档。3.1 一个完整的 Markdown Promptmarkdown # 角色 你是一名 MySQL DBA熟悉 InnoDB 锁机制。 # 背景信息 - 数据库版本MySQL 8.0.32 - 表结构orders(id, user_id, status, created_at)无索引 - 当前 SQL sql SELECT * FROM orders WHERE user_id 123 AND status PAID; 任务分析这条 SQL 的性能问题给出索引优化方案。输出要求列出 2~3 个根因给出完整的 DDL 语句用 EXPLAIN 验证优化后的执行计划输出长度 ≤ 300 字**Markdown 优势** - **代码块天然支持**用 sql 包 SQL模型不会误读为自然语言。 - **层级清晰**# / ## / ### 对应角色→任务→细节的认知层级。 - **写起来快**VSCode、Jupyter、resources/prompts/*.md 文件都好管理。 ### 3.2 配合 Spring AI 资源文件管理 把模板外置到 src/main/resources/prompts/order_optimizer.md代码里读文件渲染 //java // Markdown 模板 Spring AI 的标准用法 // 文件位置src/main/resources/prompts/order_optimizer.md Component public class MarkdownPromptSqlAdvisor { private final ChatClient chatClient; private final Resource templateResource; public MarkdownPromptSqlAdvisor( ChatClient.Builder builder, Value(classpath:prompts/order_optimizer.md) Resource templateResource) { this.chatClient builder.build(); this.templateResource templateResource; } public String advise(String mysqlVersion, String tableSchema, String sql) { // Spring AI 的 PromptTemplate 自动加载 .md 文件{var} 占位符替换 PromptTemplate template new PromptTemplate(templateResource); Prompt prompt template.create(Map.of( mysqlVersion, mysqlVersion, tableSchema, tableSchema, sql, sql )); return chatClient.prompt(prompt).call().content(); } }对应的order_optimizer.md内容用{{var}}占位# 角色 你是一名 MySQL {{mysqlVersion}} DBA熟悉 InnoDB 锁机制。 # 背景信息 表结构{{tableSchema}} 当前 SQL sql {{sql}}任务分析这条 SQL 的性能问题给出索引优化方案。输出要求2~3 个根因完整 DDLEXPLAIN 验证计划对比长度 ≤ 300 字**Markdown vs XML 怎么选** - **给模型看 强约束输出** → XML标签首尾匹配模型不易漏字段 - **给同事 review 跨模型兼容** → Markdown人人能读所有模型都认 - **多个变量 需要代码块** → MarkdownXML 包代码块需要 CDATA麻烦 - **Claude 模型 多层语义嵌套** → XMLClaude 的最优解 ## 四、JSON Schema 法机器解析最稳 当 Prompt 的输出要被下游系统**直接消费**入库、渲染、写代码时必须用 JSON Schema 约束输出。这是结构化输出的终极方案。 Spring AI 提供了 BeanOutputConverter 和 ListOutputConverter把 Java Bean 直接作为输出契约 ### 4.1 定义强类型的输出契约 java // 用 Java Bean 直接定义大模型的输出契约 // 依赖spring-boot-starter-ai-openai-spring-boot-starter 1.0.0 public record SqlOptimizationReport( ListString rootCauses, // 根因列表 ListString ddlStatements, // DDL 语句列表 String explainExpectedPlan, // 优化后 EXPLAIN 预期 ListString validationSteps // 验证步骤 ) {}4.2 用 BeanOutputConverter 一行搞定// Spring AI 的 BeanOutputConverter 自动把 Bean 描述转成 JSON Schema Component public class JsonSchemaSqlAdvisor { private final ChatClient chatClient; private final BeanOutputConverterSqlOptimizationReport converter; public JsonSchemaSqlAdvisor(ChatClient.Builder builder) { // 关键把转换器声明出来Spring AI 会自动生成 JSON Schema this.converter new BeanOutputConverter(SqlOptimizationReport.class); this.chatClient builder.build(); } public SqlOptimizationReport advise(String sql, String tableSchema) { // 把 JSON Schema 注入 system 消息告诉模型必须按这个格式输出 String systemPrompt 你是 MySQL 8.0 性能优化专家。 %s .formatted(this.converter.getFormat()); String userPrompt 表结构%s 待优化 SQL%s .formatted(tableSchema, sql); // chatClient 返回的是 String需要 converter 转成 Bean String rawJson chatClient.prompt() .system(systemPrompt) .user(userPrompt) .call() .content(); // 直接反序列化为强类型 Bean下游代码无 if-else return this.converter.convert(rawJson); } }converter.getFormat()会自动生成类似下面的指令注入到 system 消息里Your response should be a JSON object with the following structure: { rootCauses: [string], ddlStatements: [string], explainExpectedPlan: string, validationSteps: [string] }4.3 列表场景用 ListOutputConverter如果只要一个字符串列表更轻量// ListOutputConverter 用于输出必须是 ListString的简单场景 Component public class BugRootCauseExtractor { private final ChatClient chatClient; private final ListOutputConverter converter; public BugRootCauseExtractor(ChatClient.Builder builder) { this.converter new ListOutputConverter(new DefaultConverterService()); this.chatClient builder.build(); } public ListString extract(String stackTrace) { String systemPrompt 你是 Java 异常分析专家。请从堆栈中提取 N 个独立根因。 %s .formatted(converter.getFormat()); return (ListString) converter.convert(chatClient.prompt() .system(systemPrompt) .user(堆栈%s.formatted(stackTrace)) .call() .content()); } }JSON Schema 的两条血泪经验Bean 的字段加 JSR-380 注解NotBlank、Size(max200)不会自动约束大模型但能让 Bean 校验失败时立刻抛错比让模型给你一个空字符串好排查得多。大模型 100% 不会严格遵循 JSON Schema实测 GPT-4o 的 JSON 格式正确率约 95%、Qwen 约 88%。下游必须有容错JsonIgnoreProperties(ignoreUnknown true) 字段默认值不能假设模型给的就是合规 JSON。五、三种结构化方案对比维度XML 标签法Markdown 法JSON Schema 法人类可读中优差模型可读优Claude 首选优中机器解析中需 regex 提取中优强类型映射多变量模板中优中嵌套语义优良良跨模型兼容良优优适用输出长文本、结构化文本长文本、代码块强类型数据Spring AI 支持手动 StringTemplatePromptTemplate ResourceBeanOutputConverter 原生老梁的项目用法团队协作的场景统一用 Markdown调用 Claude API 的场景叠一层 XML 标签输出要入库的场景用 JSON Schema。三者不是互斥是组合拳。六、建议团队统一一套结构化规范别让团队里有的同事写 XML、有的写 Markdown、有的写大段散文。建议制定一个 30 行以内的团队 Prompt 规范塞进 wiki——只规定「角色 / 背景 / 任务 / 约束 / 输出」五个分区强制每条 Prompt 都按这个分区写。可以参考我团队的简化版[角色] 一句话定义专家身份 [背景] 关键参数、上下文 [任务] 用动词开头的一句话目标 [约束] 长度、格式、语言 [输出] Markdown / JSON / 文本写完后强制走 PR reviewPrompt 跟代码一样要 review。JSON Schema 输出必须有兜底解析即使 95% 准确率在 100 万次调用里也有 5 万次格式错误。建议用 Spring AI 的BeanOutputConverter Jackson 容错配置ObjectMapper mapper new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);或者外加一层AI 输出→Java Bean的包装把解析失败统一转成Optional.empty()抛给上层重试。跨模型切换要做 Prompt 兼容性测试集我团队的踩坑同一份 Prompt 从 DeepSeek 切到 GPT-4o 后JSON 格式正确率从 92% 跳到 97%好但 XML 标签下的语义遵循率从 95% 跌到 88%差因为 GPT-4o 对 XML 不如 Claude 敏感。结论每个模型至少备 50 个标注样本做格式回归测试别凭感觉切。结构化 Prompt 不是为了好看是为了让你半夜被叫起来排查时能 30 秒看清这份 Prompt 在干什么。下篇预告Prompt 写出来不是结束——你在生产里会改它 A/B、把它回滚、用 Git 管它。下一篇我们聊《Prompt 调试与版本管理像管理代码一样管理 Prompt》教你用 Langfuse Git 做 Prompt 的灰度发布和回滚。往期回顾90篇JAVA高级深度分析与实践文章做AI的主人代码直接可用,附完整目录Day67-Prompt工程核心技巧从零样本到思维链CoTDay66-开源模型vs闭源模型技术决策框架

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询