23 KiB
AutoRDO Web 工作台 Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 落地 Axhub 原型 autorodo-web:粘贴素材 → 复制 AutoRDO 清洗提示词 → 粘回初稿 → 按需求分页确认待确认并回填描述 → 填写优先级/标签/提交部门/提交人 → 一键复制 YunxiaoPMapp 多条记录需求提示词。
Architecture: 纯函数放在原型内 lib/(解析初稿、出题回填、拼提示词、识别部门/提交人),UI 为三步工作台(React + OneOS V2 Token)。MVP 不连云效、不嵌 OCR/ASR;Cursor 往返靠剪贴板。预留 agentAdapter 接口形状供组织 Agent。
Tech Stack: React + TypeScript(Axhub Make 原型)、Vitest、OneOS V2(oneos-ds-tokens.css + UIComponents 按需)、PrototypeAnnotationHost。
Spec: docs/superpowers/specs/2026-07-25-autorodo-web-design.md
文件结构(锁定)
| 路径 | 职责 |
|---|---|
src/prototypes/autorodo-web/lib/types.ts |
需求稿、待确认点、元数据、步骤状态类型 |
src/prototypes/autorodo-web/lib/parseDraft.ts |
解析粘回的 AutoRDO Markdown → RequirementDraft[] |
src/prototypes/autorodo-web/lib/parseDraft.test.ts |
解析单测 |
src/prototypes/autorodo-web/lib/applyAnswer.ts |
选择题/补充 → 回填描述、消待确认 |
src/prototypes/autorodo-web/lib/applyAnswer.test.ts |
回填单测 |
src/prototypes/autorodo-web/lib/buildCleanPrompt.ts |
步骤 1 清洗提示词 |
src/prototypes/autorodo-web/lib/buildRecordPrompt.ts |
步骤 3 YunxiaoPMapp 多条口令 |
src/prototypes/autorodo-web/lib/buildRecordPrompt.test.ts |
上报词单测 |
src/prototypes/autorodo-web/lib/inferMeta.ts |
从原文推断提交部门/提交人 |
src/prototypes/autorodo-web/lib/inferMeta.test.ts |
推断单测 |
src/prototypes/autorodo-web/lib/agentAdapter.ts |
预留 clean / record 接口类型(MVP 空实现) |
src/prototypes/autorodo-web/lib/clipboard.ts |
navigator.clipboard.writeText 封装 |
src/prototypes/autorodo-web/lib/pendingQuestions.ts |
从「待确认」文案生成选择题选项(词典摘要常量) |
src/prototypes/autorodo-web/components/StepPaste.tsx |
步骤 1 UI |
src/prototypes/autorodo-web/components/StepConfirm.tsx |
步骤 2 UI |
src/prototypes/autorodo-web/components/StepExport.tsx |
步骤 3 UI |
src/prototypes/autorodo-web/AutorodoWebApp.tsx |
三步状态机主壳 |
src/prototypes/autorodo-web/index.tsx |
入口 @name + AnnotationHost |
src/prototypes/autorodo-web/style.css |
布局与触控样式 |
src/prototypes/autorodo-web/annotation-source.json |
标注目录 |
src/prototypes/autorodo-web/.spec/requirements-prd.md |
AutoPRD |
src/prototypes/autorodo-web/.spec/confirm-flow.md |
确认与回填规则全文 |
src/resources/prd/autorodo-web-autoprd.md |
PRD 副本(若项目惯例需要) |
修改 .axhub/make/project.json |
注册原型(若 Make 未自动发现) |
修改 ~/.cursor/skills/YunxiaoPMapp + 项目内副本 |
记录需求解析四字段(Task 8,可同迭代或紧随) |
不放入 src/common/:逻辑仅本原型使用,避免污染公共层。
Task 1: 类型 + parseDraft + 单测
Files:
-
Create:
src/prototypes/autorodo-web/lib/types.ts -
Create:
src/prototypes/autorodo-web/lib/parseDraft.ts -
Create:
src/prototypes/autorodo-web/lib/parseDraft.test.ts -
Step 1: 写入类型
// src/prototypes/autorodo-web/lib/types.ts
export type Priority = '紧急' | '高' | '中' | '低';
export type RequirementMeta = {
priority: Priority | '';
tags: string[];
submitDept: string;
submitter: string;
titleKind: '新增' | '优化' | '';
};
export type PendingItem = {
id: string;
raw: string;
question: string;
options: string[];
resolved: boolean;
answer?: string;
};
export type RequirementDraft = {
index: number;
title: string;
description: string;
pendings: PendingItem[];
meta: RequirementMeta;
confirmed: boolean;
};
export type WizardStep = 1 | 2 | 3;
- Step 2: 写失败单测(多条 + 待确认)
// src/prototypes/autorodo-web/lib/parseDraft.test.ts
import { describe, it, expect } from 'vitest';
import { parseAutorodoDraft } from './parseDraft';
const SAMPLE = `共 2 条
### 1
## 原始诉求(AutoRDO)
**标题**:合同台账批量导出
**描述**:
在租赁合同台账支持批量导出
待确认:
- 导出范围未说明
### 2
## 原始诉求(AutoRDO)
**标题**:证照到期提醒
**描述**:
调整证照到期提醒口径
待确认:
无
`;
describe('parseAutorodoDraft', () => {
it('splits multiple requirements and pending items', () => {
const list = parseAutorodoDraft(SAMPLE);
expect(list).toHaveLength(2);
expect(list[0].title).toContain('合同台账');
expect(list[0].pendings).toHaveLength(1);
expect(list[0].pendings[0].raw).toContain('导出范围');
expect(list[1].pendings).toHaveLength(0);
expect(list[1].confirmed).toBe(true);
});
});
- Step 3: 跑测确认失败
Run: npx vitest run src/prototypes/autorodo-web/lib/parseDraft.test.ts
Expected: FAIL(模块不存在或 parseAutorodoDraft 未定义)
- Step 4: 实现解析
// src/prototypes/autorodo-web/lib/parseDraft.ts
import type { RequirementDraft, PendingItem, RequirementMeta } from './types';
const emptyMeta = (): RequirementMeta => ({
priority: '',
tags: [],
submitDept: '',
submitter: '',
titleKind: '',
});
function parsePendings(block: string, reqIndex: number): PendingItem[] {
const m = block.match(/待确认[::]\s*([\s\S]*?)(?=\n###|\n##\s*原始诉求|$)/);
if (!m) return [];
const body = m[1].trim();
if (!body || body === '无') return [];
const lines = body
.split('\n')
.map((l) => l.replace(/^[-*•\d.、)\s]+/, '').trim())
.filter(Boolean);
return lines.map((raw, i) => ({
id: `r${reqIndex}-p${i}`,
raw,
question: raw,
options: [],
resolved: false,
}));
}
export function parseAutorodoDraft(md: string): RequirementDraft[] {
const parts = md.split(/(?=^###\s*\d+)/m).filter((p) => /原始诉求(AutoRDO)/.test(p) || /\*\*标题\*\*/.test(p));
const chunks =
parts.length > 0
? parts
: md.includes('**标题**')
? [md]
: [];
return chunks.map((chunk, index) => {
const title = (chunk.match(/\*\*标题\*\*[::]\s*(.+)/)?.[1] ?? '').trim();
const descMatch = chunk.match(/\*\*描述\*\*[::]\s*\n?([\s\S]*?)(?=\n待确认|$)/);
const description = (descMatch?.[1] ?? '').trim();
const pendings = parsePendings(chunk, index);
return {
index,
title,
description,
pendings,
meta: emptyMeta(),
confirmed: pendings.length === 0,
};
});
}
- Step 5: 跑测确认通过
Run: npx vitest run src/prototypes/autorodo-web/lib/parseDraft.test.ts
Expected: PASS
- Step 6: Commit(仅当用户要求提交时执行;否则跳过所有 Commit 步骤)
git add src/prototypes/autorodo-web/lib/types.ts src/prototypes/autorodo-web/lib/parseDraft.ts src/prototypes/autorodo-web/lib/parseDraft.test.ts
git commit -m "$(cat <<'EOF'
feat(autorodo-web): add AutoRDO draft parser and types
EOF
)"
Task 2: applyAnswer + pendingQuestions
Files:
-
Create:
src/prototypes/autorodo-web/lib/applyAnswer.ts -
Create:
src/prototypes/autorodo-web/lib/applyAnswer.test.ts -
Create:
src/prototypes/autorodo-web/lib/pendingQuestions.ts -
Step 1: 写回填单测
import { describe, it, expect } from 'vitest';
import { applyPendingAnswer } from './applyAnswer';
import type { RequirementDraft } from './types';
const base: RequirementDraft = {
index: 0,
title: '合同台账批量导出',
description: '在租赁合同台账支持批量导出\n导出范围:待确认',
pendings: [
{
id: 'r0-p0',
raw: '导出范围未说明',
question: '导出范围指什么?',
options: ['当前筛选结果', '全部合同', '仅勾选行'],
resolved: false,
},
],
meta: { priority: '', tags: [], submitDept: '', submitter: '', titleKind: '' },
confirmed: false,
};
describe('applyPendingAnswer', () => {
it('merges answer into description and marks pending resolved', () => {
const next = applyPendingAnswer(base, 'r0-p0', '当前筛选结果');
expect(next.pendings[0].resolved).toBe(true);
expect(next.pendings[0].answer).toBe('当前筛选结果');
expect(next.description).toContain('当前筛选结果');
expect(next.description).not.toMatch(/导出范围:待确认/);
expect(next.confirmed).toBe(true);
});
});
- Step 2: 跑测确认失败
Run: npx vitest run src/prototypes/autorodo-web/lib/applyAnswer.test.ts
Expected: FAIL
- Step 3: 实现 applyAnswer + 简易出题
// applyAnswer.ts
import type { RequirementDraft } from './types';
export function applyPendingAnswer(
draft: RequirementDraft,
pendingId: string,
answer: string,
): RequirementDraft {
const pendings = draft.pendings.map((p) =>
p.id === pendingId ? { ...p, resolved: true, answer: answer.trim() } : p,
);
const hit = draft.pendings.find((p) => p.id === pendingId);
let description = draft.description;
if (hit) {
const label = hit.raw.replace(/未说明|待确认|不清楚/g, '').trim() || hit.raw;
if (/待确认/.test(description)) {
description = description.replace(/待确认/g, answer.trim());
} else {
description = `${description.replace(/\s+$/, '')}\n${label}:${answer.trim()}`;
}
}
const confirmed = pendings.every((p) => p.resolved);
return { ...draft, description, pendings, confirmed };
}
// pendingQuestions.ts — MVP:关键词启发式;无匹配则「是 / 否 / 需补充」
export function buildOptionsForPending(raw: string): { question: string; options: string[] } {
if (/导出范围|范围/.test(raw)) {
return {
question: '「导出范围」指什么?',
options: ['当前筛选结果', '全部数据', '仅勾选行'],
};
}
if (/模块|归属/.test(raw)) {
return {
question: '归属哪个业务模块?',
options: ['租赁合同管理', '车辆管理', '证照管理', '还车应结款'],
};
}
return {
question: raw.endsWith('?') || raw.endsWith('?') ? raw : `${raw}?`,
options: ['确认按原文理解', '暂不纳入本需求', '需文字补充'],
};
}
export function enrichPendingsWithQuestions(draft: RequirementDraft): RequirementDraft {
return {
...draft,
pendings: draft.pendings.map((p) => {
const q = buildOptionsForPending(p.raw);
return { ...p, question: q.question, options: q.options };
}),
};
}
在 parseAutorodoDraft 返回前对每条调用 enrichPendingsWithQuestions,或在 UI 粘回后统一 enrich(二选一,推荐 UI 粘回后调用,保持 parse 纯净)。
- Step 4: 跑测确认通过
Run: npx vitest run src/prototypes/autorodo-web/lib/applyAnswer.test.ts
Expected: PASS
- Step 5: Commit(用户要求时)
Task 3: inferMeta + buildCleanPrompt + buildRecordPrompt
Files:
-
Create:
src/prototypes/autorodo-web/lib/inferMeta.ts -
Create:
src/prototypes/autorodo-web/lib/inferMeta.test.ts -
Create:
src/prototypes/autorodo-web/lib/buildCleanPrompt.ts -
Create:
src/prototypes/autorodo-web/lib/buildRecordPrompt.ts -
Create:
src/prototypes/autorodo-web/lib/buildRecordPrompt.test.ts -
Create:
src/prototypes/autorodo-web/lib/clipboard.ts -
Create:
src/prototypes/autorodo-web/lib/agentAdapter.ts -
Step 1: inferMeta 单测
import { describe, it, expect } from 'vitest';
import { inferSubmitMeta } from './inferMeta';
describe('inferSubmitMeta', () => {
it('detects dept and person from free text', () => {
const r = inferSubmitMeta('业务管理组张三反馈:合同导出不好用');
expect(r.submitDept).toMatch(/业务/);
expect(r.submitter).toContain('张三');
});
});
- Step 2: 实现 inferMeta
const DEPT_PATTERNS = [
/(?:提交部门|部门)[::]\s*([^\s,,;;]+)/,
/(业务管理组|产品部|安全部|运营部|财务部|技术部)/,
];
const PERSON_PATTERNS = [
/(?:提交人|反馈人|提出人)[::]\s*([^\s,,;;]+)/,
/@([\u4e00-\u9fa5]{2,4})/,
/([\u4e00-\u9fa5]{2,4})反馈/,
];
export function inferSubmitMeta(text: string): { submitDept: string; submitter: string } {
let submitDept = '';
let submitter = '';
for (const re of DEPT_PATTERNS) {
const m = text.match(re);
if (m?.[1]) {
submitDept = m[1];
break;
}
}
for (const re of PERSON_PATTERNS) {
const m = text.match(re);
if (m?.[1]) {
submitter = m[1];
break;
}
}
return { submitDept, submitter };
}
- Step 3: buildRecordPrompt 单测 + 实现
// buildRecordPrompt.test.ts
import { describe, it, expect } from 'vitest';
import { buildYunxiaoRecordPrompt } from './buildRecordPrompt';
import type { RequirementDraft } from './types';
const one: RequirementDraft = {
index: 0,
title: '合同台账批量导出',
description: '在租赁合同台账支持按筛选结果批量导出 Excel',
pendings: [],
meta: {
priority: '中',
tags: ['租赁合同'],
submitDept: '产品部',
submitter: '王冕',
titleKind: '新增',
},
confirmed: true,
};
describe('buildYunxiaoRecordPrompt', () => {
it('includes priority tags dept submitter', () => {
const text = buildYunxiaoRecordPrompt([one]);
expect(text).toContain('YunxiaoPMapp');
expect(text).toContain('记录需求:【新增】合同台账批量导出');
expect(text).toContain('优先级=中');
expect(text).toContain('标签=租赁合同');
expect(text).toContain('提交部门=产品部');
expect(text).toContain('提交人=王冕');
expect(text).toContain('推进至=暂不推进');
});
it('throws when meta incomplete', () => {
expect(() =>
buildYunxiaoRecordPrompt([{ ...one, meta: { ...one.meta, submitter: '' } }]),
).toThrow(/提交人/);
});
});
// buildRecordPrompt.ts
import type { RequirementDraft } from './types';
export function metaComplete(d: RequirementDraft): boolean {
const m = d.meta;
return Boolean(
m.priority && m.tags.length > 0 && m.submitDept.trim() && m.submitter.trim() && m.titleKind,
);
}
export function buildYunxiaoRecordPrompt(drafts: RequirementDraft[]): string {
for (const d of drafts) {
if (!d.confirmed) throw new Error(`需求 ${d.index + 1} 仍有未确认项`);
if (!metaComplete(d)) throw new Error(`需求 ${d.index + 1} 缺少优先级/标签/提交部门/提交人/类型`);
}
const lines = drafts.map((d) => {
const title = `【${d.meta.titleKind}】${d.title.replace(/^【(?:新增|优化)】/, '')}`;
const tags = d.meta.tags.join('、');
return `记录需求:${title};描述=${d.description.replace(/\n/g, ' ')};优先级=${d.meta.priority};标签=${tags};提交部门=${d.meta.submitDept};提交人=${d.meta.submitter};推进至=暂不推进`;
});
return [
'YunxiaoPMapp',
'请按下列条目依次记录需求;每条保持独立,不要合并。',
'',
...lines,
].join('\n');
}
// buildCleanPrompt.ts
export function buildCleanPrompt(payload: {
text: string;
attachmentNames: string[];
}): string {
const files =
payload.attachmentNames.length > 0
? `附件:${payload.attachmentNames.join('、')}(请用多模态识读图/语音内容)`
: '附件:无';
return [
'AutoRDO',
'请按 AutoRDO 规则清洗下列素材:多条独立诉求拆成多份;提炼标题与书面描述;不确定处标「待确认」;描述无结尾句号。',
files,
'',
'—— 素材开始 ——',
payload.text.trim() || '(仅附件,无正文)',
'—— 素材结束 ——',
].join('\n');
}
// clipboard.ts
export async function copyText(text: string): Promise<void> {
await navigator.clipboard.writeText(text);
}
// agentAdapter.ts
export type CleanRequest = { text: string; attachmentNames: string[] };
export type RecordRequest = { drafts: import('./types').RequirementDraft[] };
/** MVP:未接组织 Agent;后续替换实现即可 */
export const agentAdapter = {
async clean(_req: CleanRequest): Promise<null> {
return null;
},
async record(_req: RecordRequest): Promise<null> {
return null;
},
};
- Step 4: 跑全部 lib 单测
Run: npx vitest run src/prototypes/autorodo-web/lib
Expected: 全部 PASS
- Step 5: Commit(用户要求时)
Task 4: 原型壳 + 步骤 1 UI
Files:
- Create:
src/prototypes/autorodo-web/index.tsx - Create:
src/prototypes/autorodo-web/AutorodoWebApp.tsx - Create:
src/prototypes/autorodo-web/style.css - Create:
src/prototypes/autorodo-web/components/StepPaste.tsx - Create:
src/prototypes/autorodo-web/annotation-source.json(先最小目录) - Modify:
.axhub/make/project.json(若启动后未出现在列表则补注册)
前置:Read src/resources/design-system/DESIGN.md(Token、触控 ≥44px、禁止原生 select)。
- Step 1: 入口与主壳骨架
// index.tsx
/**
* @name AutoRDO 需求清洗工作台
*/
import './style.css';
import '../../../resources/design-system/oneos-ds-tokens.css';
import React from 'react';
import { PrototypeAnnotationHost } from '../../common/prototype-annotation-host';
import type { AnnotationSourceDocument } from '@axhub/annotation';
import annotationSourceDocument from './annotation-source.json';
import { AutorodoWebApp } from './AutorodoWebApp';
export default function AutorodoWebEntry() {
return (
<>
<AutorodoWebApp />
<PrototypeAnnotationHost
source={annotationSourceDocument as AnnotationSourceDocument}
options={{}}
/>
</>
);
}
AutorodoWebApp:左侧步骤 1/2/3;step state;步骤 1 渲染 StepPaste。
-
Step 2: StepPaste
-
contentEditable 或 textarea 接收粘贴;
onPaste收集clipboardData.files(image/、audio/)为附件名列表(原型阶段可用 File.name,不上传) -
按钮「确认并复制清洗提示词」→
buildCleanPrompt+copyText;toast「已复制,请粘到 Cursor 跑 AutoRDO」 -
可选 checkbox「粘贴后自动复制」(默认关)
-
控件:优先
V2封装;按钮 min-height 44px -
Step 3: 本地预览
Run: 打开 Make 预览 /prototypes/autorodo-web
Expected: 能粘贴、点确认后剪贴板为 AutoRDO 提示词
- Step 4: Commit(用户要求时)
Task 5: 步骤 2 确认 UI
Files:
-
Create:
src/prototypes/autorodo-web/components/StepConfirm.tsx -
Modify:
src/prototypes/autorodo-web/AutorodoWebApp.tsx -
Step 1: 粘回区 + 解析
-
textarea「粘回 AutoRDO 初稿」
-
按钮「解析初稿」→
parseAutorodoDraft→enrichPendingsWithQuestions→ 对每条inferSubmitMeta(description + title)预填 meta -
Pill 切换需求 index
-
Step 2: 左右分栏确认
-
左:标题(可编辑)+ 描述(只读展示实时稿)
-
右:当前未解决 pending;单选 options;补充 input;「确认并下一题」调用
applyPendingAnswer -
元数据:优先级四选一;标签用可增删 chip(自由输入 MVP);提交部门/提交人 input;类型 新增/优化
-
全部 confirmed 且
metaComplete后可进步骤 3 -
Step 3: 手动验收路径
- 粘贴 Task1 SAMPLE 初稿
- 答完题后描述含答案且无「待确认」
- 填齐元数据
- Step 4: Commit(用户要求时)
Task 6: 步骤 3 导出 + 样式打磨
Files:
-
Create:
src/prototypes/autorodo-web/components/StepExport.tsx -
Modify:
style.css、AutorodoWebApp.tsx -
Step 1: StepExport
-
预览
buildYunxiaoRecordPrompt(drafts) -
「一键复制上报提示词」
-
「复制定稿 Markdown」(输出多份已确认
## 原始诉求(AutoRDO),待确认:无) -
错误态:捕获 throw,页面内提示缺哪条哪字段
-
Step 2: 响应式
-
≤767px:步骤条顶置;确认区改为上下堆叠;触控 ≥44px;正文 ≥14px
-
Step 3: 预览验收
全路径走通:粘贴 → 复制清洗词 →(模拟)粘回 SAMPLE → 确认 → 复制上报词,粘贴到文本编辑器检查字段齐全。
- Step 4: Commit(用户要求时)
Task 7: AutoPRD + 标注 + 导航同步
Files:
-
Create:
src/prototypes/autorodo-web/.spec/confirm-flow.md -
Create:
src/prototypes/autorodo-web/.spec/requirements-prd.md -
Create:
src/resources/prd/autorodo-web-autoprd.md(与 PRD 同步) -
Modify:
annotation-source.json(产品需求说明节点) -
Step 1: 写 confirm-flow.md
含:判定顺序表、前置条件、数据源(粘回 Markdown / 本地启发式选项)、用户可见结果、标明未接真 API。
- Step 2: 写 requirements-prd.md
按 oneos-autoprd 结构:总览/目标/边界/角色/用户故事(起点→运作→闭环)/验收;链到 confirm-flow.md。
- Step 3: 同步标注与导航
npm run nav:sync -- --prototype autorodo-web --note "新增 AutoRDO 网页清洗与云效上报提示词工作台"
- Step 4: Commit(用户要求时)
Task 8: YunxiaoPMapp 消费四字段(Skill 扩展)
Files:
-
Modify:
~/.claude/skills/YunxiaoPMapp/references/commands.md(及项目.cursor/.claude同步副本) -
Modify: YunxiaoPMapp
SKILL.md记录需求参数说明 -
可选:
references/record-meta-fields.md新文件 -
Step 1: 文档约定口令字段
在口令面增加:
记录需求:…;优先级=紧急|高|中|低;标签=…;提交部门=…;提交人=…;推进至=…
说明:网页上报词已带齐时,禁止再 Plan 重复问这四项(除非缺省);缺省则仍问。
- Step 2: 实现侧
若现有 live 脚本已支持 priority/tag:把提交部门/提交人映射到云效字段(查 runtime-ids.json;未验证字段则先写入描述尾部 提交部门/提交人,并在文档标明「字段 ID 待验证」)。
- Step 3: 与网页联调
用步骤 3 复制出的提示词在 Cursor 跑一次「记录需求」(测试项目或 dry-run 策略按团队惯例)。
- Step 4: Commit(用户要求时)
规格覆盖自检
| Spec 要求 | Task |
|---|---|
| 粘贴文/图/语音 + 复制清洗词 | 4 |
| 粘回初稿 + 分页确认 + 回填 | 1,2,5 |
| 优先级/标签/部门/提交人 | 3,5,6 |
| 一键 Yunxiao 多条口令 | 3,6 |
| 预留组织 Agent | 3 agentAdapter |
| AutoPRD / 业务规则文档 | 7 |
| Yunxiao 消费四字段 | 8 |
| 不直连云效 / 无 OCR | 全程遵守 |
执行说明
- 所有 Commit 步骤默认跳过,除非用户明确要求提交。
- Task 8 可与 Task 4–7 并行由另一会话做;网页 MVP 以 Task 1–7 为可演示闭环(上报词已含四字段,即使 Skill 暂未写入云效自定义字段,口令仍可用于人工/后续 Skill)。
Plan complete and saved to docs/superpowers/plans/2026-07-25-autorodo-web.md.
两种执行方式:
- Subagent-Driven(推荐) — 每任务开新子代理,任务间复核,迭代快
- Inline Execution — 本会话按 executing-plans 连续执行,设检查点
要哪一种?