用结构化 Prompt 让大模型「干活」:以数据库巡检告警建议生成为例

1. 一次请求里 Prompt 的拼装公式

运行时 user message 只有一条,顺序固定:

perl 复制代码
buildUserMessage(pack) = TASK_PREFIX + XXX_ALERT_RULES + pack + OUTPUT_FORMAT

其中 pack 由服务按当前报告动态生成(A 元信息 + B 分类数据 + C 规则键),不包含已落库的建议正文。


2. 真实 Prompt 片段一:任务前缀(原文)

text 复制代码
你是 Oracle 数据库资深技术专家。请严格依据下方【XXX 告警规则】与【分析包】撰写巡检建议。等级与问题类型由系统按 P_REPORT_DBALERT 自动落库,你无需填写 level/tagId。

作用:定角色、定输入来源、第一时间划掉模型不该管的字段(level / tagId)。


3. 真实 Prompt 片段二:领域规则(节选 + 全文结构)

下面是与代码常量一致的第二节等级表第三节撰写约束(第一节分类规则在代码里更长,此处保留结构并节选关键点)。

3.1 第一节要点(分类如何产生)

text 复制代码
【XXX 告警规则(撰写建议时必须遵循)】

## 一、告警日志「分类分析」如何产生(P_ANALYZE_DB_ALERT)

1) 原始数据为采集表 RD_DB_ALERT,每行含 LOG_TYPE(多为 ORA 错误码、CKPT_NOT_OK 等)。
2) 分析时不参与分类汇总的类型:Start / Shutdown;以及 ALERT_CAPTURE_KEYWORDS 配置值。
3) 其余错误按「同一实例 + 同一时刻 TIME」聚为一簇;簇内多种 LOG_TYPE 拼成 TYPE_CLEAN。
4) 簇内日志序号跨度 > ALERT_ERROR_GAP_MAX 则丢弃该簇。
5) 汇总表 PD_DB_ALERT_SUMM:按 TYPE_CLEAN 去重;view35 的 LOG_TYPE 列 = TYPE_CLEAN。
6) B 节不是「严重度分类」:每行是一类错误类型,种类由本批次动态决定。

## 二、巡检「建议」等级与类型(P_REPORT_DBALERT,与 C 节 ruleKey 一致)

| 场景 | suggestion_level | tag_id | 典型 ruleKey 前缀 |
|------|------------------|--------|-------------------|
| 本批次无 PD_DB_ALERT 数据 | 1 正常 | 3 稳定 | N_ALERT_NORMAL |
| 实例存在 Start 告警 | 2 提示 | 3 稳定 | T_ALERT_INST_START |
| Alert 日志文件超阈值 | 2 提示 | 3 稳定 | T_ALERT_FILE_SIZE |
| CKPT_NOT_OK 超阈值 | 3 警告 | 3 稳定 | W_ALERT_CKPT_TO_LOG |
| B 节 LOG_TYPE 匹配知识库 | 2 提示 | 3 稳定 | T_ALERT_REPOSITORY |
| B 节 LOG_TYPE 未匹配知识库 | 2 提示 | 3 稳定 | T_ALERT_DESCRIPTION |

说明:tag_id 恒为 3(稳定);level 1=正常、2=提示、3=警告;告警章不使用 level=4。

## 三、你撰写建议时的约束

1) 每条建议对应 C 节一个 ruleKey,JSON 中 ruleKey 必须与 C 完全一致。
2) 针对 B 节汇总行撰写时,logType 填该行 LOG_TYPE。
3) 正文结合 LOG_COUNT、时间、LOG_CONTENT;一句完整判断;不要综述、不要操作步骤。
4) 不要自行拆分或合并 ruleKey;不要输出 level、tagId、严重(4)、总体结论。
5) 建议条数与 C 节 ruleKey 数量相当,最多 8 条。

---

【分析包】

说明:这段是静态常量,所有报告共用;改规则引擎行为时要同步改这里,否则模型理解与落库逻辑会分叉。


4. 真实 Prompt 片段三:动态分析包(完整示例)

假设某次巡检(演示数据),buildPack(...) 会生成类似下面的 Markdown(接在「【分析包】」之后):

markdown 复制代码
## A. 元信息

- reportId:10001
- batchName:demo-batch-2025-03
- 报告名称:演示库 3 月巡检报告
- 章节:告警日志
- set_item_id:12005
- set_item_view_id:35

### A.1 机器可读 manifest(JSON)

```json
{"report_id":10001,"record_total_effective":3,"rows_in_pack":3,"detail_row_cap":80,"detail_truncated":false,"max_cell_chars":800,"max_log_content_chars":600}

B. 告警日志分类分析(PD_DB_ALERT_SUMM 子集)

(即 view35「告警日志分类分析」;每行一类错误:LOG_TYPE=分析程序 TYPE_CLEAN,非严重度;分类规则见 prompt【XXX 告警规则】第一节。)

行 1

  • 实例:orcl_demo1
  • 错误类型:ORA-00600
  • 出现次数:12
  • 首次时间:2025-03-10 02:15:33
  • 末次时间:2025-03-10 08:42:01
  • 日志摘要:ORA-00600: internal error code, arguments: [1234], [], [], [], [], []

行 2

  • 实例:orcl_demo1
  • 错误类型:CKPT_NOT_OK
  • 出现次数:28
  • 首次时间:2025-03-09 23:01:00
  • 末次时间:2025-03-10 06:30:12
  • 日志摘要:Checkpoint not complete

行 3

  • 实例:orcl_demo2
  • 错误类型:ORA-07445
  • 出现次数:2
  • 首次时间:2025-03-10 01:20:00
  • 末次时间:2025-03-10 01:22:18
  • 日志摘要:ORA-07445: exception encountered: core dump

C. P_REPORT_DBALERT 规则键(等级/类型由系统按此落库,勿自行填写)

  • ruleKey=T_ALERT_INST_START:orcl_demo1 → level=2 tagId=3(稳定=3) viewId=7 (实例存在 Start 告警)
  • ruleKey=W_ALERT_CKPT_TO_LOG:orcl_demo1 → level=3 tagId=3(稳定=3) viewId=35 logType=CKPT_NOT_OK (检查点未完成次数超阈值)
  • ruleKey=T_ALERT_REPOSITORY:ORA-00600 → level=2 tagId=3(稳定=3) viewId=35 logType=ORA-00600 (知识库命中)
  • ruleKey=T_ALERT_DESCRIPTION:ORA-07445 → level=2 tagId=3(稳定=3) viewId=35 logType=ORA-07445 (未匹配知识库,需描述性建议)
yaml 复制代码
要点:

- **B 只有事实**,没有「已有建议怎么写」。
- **C 只有 ruleKey + 落库元数据 + hint**,hint 是场景说明,不是 BX 里已存的那段 suggestion 正文。
- 列名来自报告列定义(`show_name` / `column_name`),示例里用中文标签是为阅读方便。

---

## 5. 真实 Prompt 片段四:输出格式(原文)

接在分析包之后:

```text

---

【输出要求】仅输出 JSON 数组,不要其它文字:
[
  {"ruleKey": "T_ALERT_REPOSITORY:ORA-00600", "logType": "ORA-00600", "text": "建议正文"},
  {"ruleKey": "W_ALERT_CKPT_TO_LOG:orcl1", "text": "..."}
]
字段:ruleKey(必填,取自 C 节);logType(可选,与 B 节 LOG_TYPE 一致时填写);text(必填)。不要输出 level、tagId。

这是机器解析契约 :解析器只认 JSON 数组;level / tagId 即使模型写了也会被忽略,最终以 C 节规格为准。


6. 模型理想输出示例(对应上一分析包)

json 复制代码
[
  {
    "ruleKey": "T_ALERT_INST_START:orcl_demo1",
    "text": "实例 orcl_demo1 在巡检周期内存在数据库启动(Start)类告警记录,建议结合变更窗口确认是否为计划内重启。"
  },
  {
    "ruleKey": "W_ALERT_CKPT_TO_LOG:orcl_demo1",
    "logType": "CKPT_NOT_OK",
    "text": "实例 orcl_demo1 在 2025-03-09 至 2025-03-10 期间出现 28 次检查点未完成(CKPT_NOT_OK),频率偏高,存在日志切换或检查点推进受阻风险。"
  },
  {
    "ruleKey": "T_ALERT_REPOSITORY:ORA-00600",
    "logType": "ORA-00600",
    "text": "实例 orcl_demo1 出现 12 次 ORA-00600 内部错误,最近一次为 2025-03-10 08:42:01,属 Oracle 内部错误,建议按 MOS 与 trace 进一步定位。"
  },
  {
    "ruleKey": "T_ALERT_DESCRIPTION:ORA-07445",
    "logType": "ORA-07445",
    "text": "实例 orcl_demo2 出现 2 次 ORA-07445 进程异常终止,伴随 core dump 风险,建议检查对应时段补丁与已知缺陷。"
  }
]

注意模型没有 输出 leveltagId;写入库时由程序按 C 节映射为 level=2/3、tagId=3、viewId=7/35。


7. 程序侧流水线(Prompt 之后发生什么)

sequenceDiagram participant P as Prompt拼接 participant L as 大模型 participant Par as JSON解析 participant Enf as 规则强制对齐 participant BX as 建议落库 P->>L: TASK_PREFIX + 规则 + A/B/C + OUTPUT_FORMAT L->>Par: 仅 JSON 数组 Par->>Enf: ruleKey + text (+ logType) Enf->>BX: 多条 ADD,identifier AI_ALERT_GEN_001... Note over BX: 再生前 HIDE 旧 AI 行,不进入 Prompt
  • 不进 PromptgetSuggestions 查到的规则建议正文、旧 AI 建议正文。
  • 进 Prompt:本批次 B 数据 + 本批次 C ruleKey 列表 + 静态领域规则。

8. 好 Prompt 的写法(结合真实片段归纳)

做法 本案例中的体现
先划边界 任务前缀明确「等级/标签系统填」
静态规则 + 动态数据 XXX_ALERT_RULES 常量 + buildPack
可解析输出 仅 JSON 数组 + 字段说明 + 示例
键值对齐 C 节 ruleKey ↔ 输出 ruleKey 必须一致
控制篇幅 行数上限 80、单元格截断、最多 8 条建议
负面约束 不要综述、不要步骤、不要 level/tagId
程序兜底 AlertAiSuggestionRuleEnforcer 按 spec 填 level/tag/view

9. 反例:同样场景下的「坏 Prompt」

text 复制代码
请根据以下数据写一份告警分析总结,并给出严重程度和建议操作步骤。
[粘贴整棵建议树,含已有规则建议全文......]
输出用 markdown,方便阅读。

常见问题:模型自造严重度、写成一篇综述、照抄已有建议、输出无法被 JSON.parse 稳定解析。

相关推荐
Xiacqi11 小时前
Java数据库连接--JDBC--DRUID
数据库·后端
snakeshe10101 小时前
SpringBoot 多人协作平台实战(8):Cookie 与登录状态维持
后端
代码北人生1 小时前
后端工程师开始用 Claude Code 了,Stripe 4天完成了本来要10个工程师周的迁移
后端·claude
小江的记录本2 小时前
【Java基础】核心关键字:final、static、volatile、synchronized、transient(附《思维导图》+《面试高频考点清单》)
java·前端·数据结构·后端·ai·面试·ai编程
fliter2 小时前
Rust 泛型 vs Java 泛型:它们看起来相似,但骨子里截然不同
后端
文心快码BaiduComate2 小时前
520,Comate Mission模式跨越界限,和你达成最「深」联动
前端·数据库·后端
_Evan_Yao3 小时前
限流的艺术:令牌桶与滑动窗口的博弈,以及我为何在 AI 项目中选择了后者
java·后端·架构
iccb10133 小时前
详解 Docker 环境变量技术,以及如何通过环境变量一键部署客服系统
后端