promptfigure 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +29 -15
  2. package/adapters/claude-code/install.mjs +7 -6
  3. package/adapters/claude-code/promptfigure-api/INSTALL.md +45 -0
  4. package/adapters/claude-code/promptfigure-api/SKILL.md +291 -0
  5. package/adapters/claude-code/promptfigure-api/references/api-contract.md +319 -0
  6. package/adapters/claude-code/promptfigure-api/references/deliverables-ledger.md +119 -0
  7. package/adapters/claude-code/promptfigure-api/references/document-workflow.md +231 -0
  8. package/adapters/claude-code/promptfigure-api/references/figure-upgrade-workflow.md +201 -0
  9. package/adapters/claude-code/promptfigure-api/references/proactive-upgrade.md +120 -0
  10. package/adapters/claude-code/promptfigure-api/references/prompt-cookbook.md +223 -0
  11. package/adapters/claude-code/promptfigure-api/references/prompt-review-workflow.md +265 -0
  12. package/adapters/claude-code/promptfigure-api/references/setup-guide.md +151 -0
  13. package/adapters/claude-code/promptfigure-api/references/troubleshooting.md +204 -0
  14. package/adapters/claude-code/{SKILL.md → promptfigure-local/SKILL.md} +31 -0
  15. package/adapters/codex/promptfigure/.codex-plugin/plugin.json +2 -2
  16. package/adapters/codex/promptfigure/skills/promptfigure-api/INSTALL.md +45 -0
  17. package/adapters/codex/promptfigure/skills/promptfigure-api/SKILL.md +291 -0
  18. package/adapters/codex/promptfigure/skills/promptfigure-api/references/api-contract.md +319 -0
  19. package/adapters/codex/promptfigure/skills/promptfigure-api/references/deliverables-ledger.md +119 -0
  20. package/adapters/codex/promptfigure/skills/promptfigure-api/references/document-workflow.md +231 -0
  21. package/adapters/codex/promptfigure/skills/promptfigure-api/references/figure-upgrade-workflow.md +201 -0
  22. package/adapters/codex/promptfigure/skills/promptfigure-api/references/proactive-upgrade.md +120 -0
  23. package/adapters/codex/promptfigure/skills/promptfigure-api/references/prompt-cookbook.md +223 -0
  24. package/adapters/codex/promptfigure/skills/promptfigure-api/references/prompt-review-workflow.md +265 -0
  25. package/adapters/codex/promptfigure/skills/promptfigure-api/references/setup-guide.md +151 -0
  26. package/adapters/codex/promptfigure/skills/promptfigure-api/references/troubleshooting.md +204 -0
  27. package/adapters/codex/promptfigure/skills/promptfigure-local/SKILL.md +31 -0
  28. package/bin/pf.mjs +37 -0
  29. package/package.json +2 -2
  30. package/scripts/build-adapters.mjs +31 -18
  31. package/skill/promptfigure-api/INSTALL.md +45 -0
  32. package/skill/promptfigure-api/SKILL.md +291 -0
  33. package/skill/promptfigure-api/references/api-contract.md +319 -0
  34. package/skill/promptfigure-api/references/deliverables-ledger.md +119 -0
  35. package/skill/promptfigure-api/references/document-workflow.md +231 -0
  36. package/skill/promptfigure-api/references/figure-upgrade-workflow.md +201 -0
  37. package/skill/promptfigure-api/references/proactive-upgrade.md +120 -0
  38. package/skill/promptfigure-api/references/prompt-cookbook.md +223 -0
  39. package/skill/promptfigure-api/references/prompt-review-workflow.md +265 -0
  40. package/skill/promptfigure-api/references/setup-guide.md +151 -0
  41. package/skill/promptfigure-api/references/troubleshooting.md +204 -0
  42. package/skill/promptfigure-local/SKILL.md +31 -0
  43. package/web/app.js +9 -3
  44. package/web/style.css +5 -0
@@ -0,0 +1,319 @@
1
+ # API 契约完整版
2
+
3
+ **站点**:https://promptfigure.top
4
+
5
+ ---
6
+
7
+ ## ⚠️ 必看
8
+
9
+ 1. **默认就是完整润色管线**——`/api/v1/generate` 与网页工作台同一套(编排 + 净化 + 审查 + 出图),只是没有网页的多轮问询/二次确认。**不要因为要"一次性答完"就绕过润色。**
10
+ 2. **`polish:false` 仅是紧急绕过**(服务端不扩写,需自己写完整英文提示词),平时**不要传**。上游文本限频期服务端会自动回落重试(主模型 agnes-2.5-flash → 备用 agnes-2.0-flash)。
11
+ 3. **CF WAF 拦 `Python-urllib/*`**——其它客户端都过。
12
+ 4. **`balance` 字段滞后**——`/api/login`、`/api/me` 返回的 balance 不等于真实余额。
13
+
14
+ ---
15
+
16
+ ## 路径 A:API 直调(v1,同步)
17
+
18
+ **Endpoint**:`POST https://promptfigure.top/api/v1/generate`
19
+ **鉴权**:`Authorization: Bearer pf_...`
20
+ **CORS**:全开(`Access-Control-Allow-Origin: *`),鉴权靠 key 不靠 cookie。
21
+
22
+ ### Request
23
+
24
+ ```jsonc
25
+ {
26
+ "prompt": "", // ✅ 必填,大白话即可,≤8000 字符
27
+ "polish": true, // 默认润色;false 仅紧急绕过(服务端不扩写,平时不要传)
28
+ "model": "standard" | "premium", // 服务端默认 standard;非 "premium" 一律 standard
29
+ "size": "1K" | "2K", // 仅 premium 生效,默认 2K
30
+ "ratio": "1:1" | "3:2" | "2:3" | "16:9" | "9:16", // 默认 1:1,非法值回落 1:1
31
+ "refUrl": "https://.../ref.png", // 公网图片直链,PNG ≤8MB
32
+ "refDataUrl": "data:image/png;base64,...", // base64 后 ≤8MB
33
+ "mode": "replica" // 一键临摹(2026-09-18);别名 "replica":true、"mode":"一键临摹"
34
+ }
35
+ ```
36
+
37
+ 规则:
38
+ - `prompt` 空或缺失 → `400 prompt_required`(**临摹模式例外**:`mode:"replica"` 时 `prompt` 可留空,服务端补一句中性复刻指令)
39
+ - `prompt` >8000 字符 → `400 prompt_too_long`
40
+ - `model` 非 `"premium"` 任何值 → `standard`
41
+ - `size` 非 `"1K"` → 2K;`standard` 恒输出 1K
42
+ - `refUrl` + `refDataUrl` 都传 → **`refDataUrl` 优先**
43
+ - `refUrl` 服务端安全限制:只接 `http(s)`;`localhost`/`.local`/`.internal`/环回与私网 IP 拒绝;校验 PNG 文件魔数(不看 content-type);≤8MB;拉取超时 20s
44
+ - **注意**:上游 `/images/edits` 端点 2026-09-07 起持续 503。`refUrl`/`refDataUrl` 当前可能 `refIgnored: true`(被忽略,**当次照常出图并计费**)
45
+
46
+ ### Response
47
+
48
+ 成功 `200`:
49
+
50
+ ```jsonc
51
+ {
52
+ "b64_json": "<PNG base64>",
53
+ "size": "2K",
54
+ "ratio": "16:9",
55
+ "model": "premium",
56
+ "provider": "premium", // agnes=standard, premium=premium 档(高级档中转通道)
57
+ "crafted": false, // false=polish:false 直出
58
+ "charged": 0.15,
59
+ "balance": 12.34,
60
+ // 仅 mode:"replica" 出现:
61
+ "mode": "replica",
62
+ "referenceSpec": { /* 见下「一键临摹」 */ },
63
+ "specError": null // 非 null = 参考图规格提取失败,已退化(不额外计费)
64
+ }
65
+ ```
66
+
67
+ 失败:
68
+
69
+ ```jsonc
70
+ { "error": "insufficient_balance", "required": 0.15, "balance": 0.02 } // 402
71
+ { "error": "rate_limited", "limit": 5 } // 429,已退款
72
+ { "error": "generation_failed", "detail": "orchestration_failed: ...", "refunded": 0.15 } // 502,已退款
73
+ { "error": "invalid_api_key" } // 401
74
+ ```
75
+
76
+ ### 计费
77
+
78
+ | model | 单价 | 输出 | 备注 |
79
+ |---|---|---|---|
80
+ | `standard` | **$0.02** / 次 | 恒 1K(Agnes) | 草稿、迭代、批量试错 |
81
+ | `premium` | **$0.15** / 次 | 1K 或 2K **同价** | 终稿、正式交付、入 paper |
82
+
83
+ ✅ 尺寸不影响价格 → premium 无脑用 2K。
84
+ ✅ 每 key 关联账号,**只从余额扣**,与会员订阅额度独立。
85
+ ✅ **生成失败自动原路退款**(含 RPM 429 场景)。
86
+
87
+ **RPM(每分钟请求数),与网页端共享同一窗口**:免费 5 · Lite 10 · Plus 15 · Pro 40 · Ultra 80。
88
+ 未订阅 = 免费层 5 RPM,批量任务务必串行 + 退避。
89
+
90
+ ### 调用示例
91
+
92
+ #### Bash / curl(默认 UA 不会被 WAF 拦)
93
+
94
+ 🔴 **响应必须落文件,禁止把原始响应直接回显进对话**——`b64_json` 是几百 KB 的 base64
95
+ (数十万 token 级),直接打印轻则污染上下文、重则撑爆会话(2026-09-25 实测)。
96
+ 照下面的范式:管道进文件,jq 只回显元数据字段。
97
+
98
+ 🔴 **落盘一律用当前目录相对路径,禁用 `/tmp`**(2026-09-25 实测):Windows 下 Git Bash 的
99
+ `/tmp` 指向 AppData\Local\Temp,而 Windows 版 curl/python 把 `/tmp` 解析成 `<当前盘>:\tmp`——
100
+ 两套解析混用会「写入成功但读不到」反复重试,最终交付物还会落在用户找不到的 `C:\tmp`。
101
+ 中间产物和最终交付图都放当前工作目录。
102
+
103
+ 🔴 **curl 必须显式 `--max-time 300`**:生成耗时 46s~160s+,很多宿主的 Bash 工具默认 120s
104
+ 就掐断命令(2026-09-25 实测连续两次超时返工)。宿主有 timeout 参数的一并设到 300s+。
105
+ ⚠️ **注意:`timeout 300 curl …` 救不了宿主工具级的 120s 掐断**——掐的是整个命令不是 curl。
106
+ 宿主 Bash 工具支持 timeout 参数的(如 claude CLI)调用时必须显式传(如 `timeout: 300000`);
107
+ 不支持的用后台模式 + 分次轮询:
108
+
109
+ 🔴 **禁用宿主 Bash 工具自带的「后台任务」机制跑 curl**(claude CLI 的 run_in_background 等):
110
+ **会话一结束,未完成的任务直接被杀**——2026-09-25 实测 curl 被这样杀掉后 resp 文件根本没落地,
111
+ 宿主却已向用户报告"已提交、预算 $0.04"(虚报)。要后台只允许 `nohup … &`(脱离会话存活)+
112
+ **轮询到 DONE 才能结束回合**;否则一律前台 curl。
113
+
114
+ 🔴 **先核实后宣称**:向用户报告任何进度前必须核实证据——resp 文件存在(`ls`)、
115
+ JSON 合法(`jq '{size,model,crafted,charged,balance}' resp.json` 回显元数据)。
116
+ 没核实禁止说「已提交 / 已在生成 / 已计费」。台账 `pf-ledger.md` 每次调用**立即补一行**,禁止空表。
117
+
118
+ ```bash
119
+ nohup curl -s --max-time 300 -X POST https://promptfigure.top/api/v1/generate \
120
+ -H "Authorization: Bearer $PROMPTFIGURE_KEY" -H "Content-Type: application/json" \
121
+ -d @req.json -o resp.json > curl.log 2>&1 &
122
+ # 之后的工具调用里轮询(每次调用查一次,别在一个命令里 sleep 死等):
123
+ jq -e '.b64_json' resp.json > /dev/null && echo DONE || echo WAITING
124
+ ```
125
+
126
+ ```bash
127
+ gen() {
128
+ curl -s --max-time 300 -X POST https://promptfigure.top/api/v1/generate \
129
+ -H "Authorization: Bearer $PROMPTFIGURE_KEY" \
130
+ -H "Content-Type: application/json" \
131
+ -d "$1" -o resp.json
132
+ jq -r .b64_json resp.json | base64 -d > "${2:-figure.png}"
133
+ jq '{size,model,crafted,charged,balance,refIgnored}' resp.json
134
+ }
135
+ gen '{"prompt":"对比 ResTiNet 和 CNN 在 OCT 分类上的表现,左侧数据流右侧柱状图","model":"premium","ratio":"16:9"}' fig1.png
136
+ # 紧急绕过(平时不需要):末尾加 "polish":false,且 prompt 需自己写成完整英文专业提示词
137
+ # gen '{"prompt":"<完整英文提示词>","model":"premium","polish":false,"ratio":"16:9"}' fig1.png
138
+ ```
139
+
140
+ #### Node(fetch 默认 UA 不过 WAF)
141
+
142
+ ```js
143
+ const B = "https://promptfigure.top";
144
+ const b64 = await fetch(B + "/api/v1/generate", {
145
+ method: "POST",
146
+ headers: { Authorization: `Bearer ${process.env.PROMPTFIGURE_KEY}`,
147
+ "Content-Type": "application/json" },
148
+ body: JSON.stringify({ prompt, model: "premium", ratio: "16:9" }), // 正常:不传 polish
149
+ // 紧急绕过(平时不需要):加 polish: false,且 prompt 需写成完整英文专业提示词
150
+ }).then(r => r.json());
151
+ require("fs").writeFileSync("figure.png", Buffer.from(b64.b64_json, "base64"));
152
+ ```
153
+
154
+ #### Python `requests`(UA 安全,需 `pip install requests`)
155
+
156
+ ```python
157
+ import os, base64, requests
158
+ r = requests.post(
159
+ "https://promptfigure.top/api/v1/generate",
160
+ headers={"Authorization": f"Bearer {os.environ['PROMPTFIGURE_KEY']}"},
161
+ json={"prompt": "对比 ResTiNet 和 CNN 在 OCT 分类上的表现,左侧数据流右侧柱状图",
162
+ "model": "premium", "ratio": "16:9"}, # 正常:不传 polish
163
+ # 紧急绕过(平时不需要):加 "polish": False,prompt 需写成完整英文专业提示词
164
+ timeout=300,
165
+ )
166
+ if not r.ok:
167
+ raise SystemExit(f"{r.status_code} {r.json()}")
168
+ d = r.json()
169
+ open("figure.png", "wb").write(base64.b64decode(d["b64_json"]))
170
+ print(d["charged"], d["balance"], d.get("refIgnored"))
171
+ ```
172
+
173
+ #### Python `urllib.request`(⚠️ 必须改 UA,否则 403)
174
+
175
+ ```python
176
+ import json, base64, urllib.request
177
+ req = urllib.request.Request(
178
+ "https://promptfigure.top/api/v1/generate",
179
+ data=json.dumps({"prompt":"...","model":"premium","ratio":"16:9"}).encode(),
180
+ # 紧急绕过(平时不需要):dict 里加 "polish": False
181
+ headers={
182
+ "Authorization": f"Bearer {os.environ['PROMPTFIGURE_KEY']}",
183
+ "Content-Type": "application/json",
184
+ "User-Agent": "Mozilla/5.0", # 绕开 CF WAF 拦截
185
+ },
186
+ method="POST",
187
+ )
188
+ d = json.loads(urllib.request.urlopen(req, timeout=300).read())
189
+ open("figure.png", "wb").write(base64.b64decode(d["b64_json"]))
190
+ ```
191
+
192
+ ### 客户端 `timeout`
193
+
194
+ 默认管线实测 42–90s;premium 2K 偶尔更久。**所有客户端 timeout 建议 ≥ 300s**。
195
+
196
+ ---
197
+
198
+ ## 路径 B:网页工作流等价的异步流程
199
+
200
+ 完整 4 步(路径 B 走默认润色,无 polish 开关):
201
+
202
+ ```js
203
+ const B = "https://promptfigure.top";
204
+ const post = (p, b, t) => fetch(B+p, {
205
+ method:"POST",
206
+ headers:{"Content-Type":"application/json", Authorization:`Bearer ${t}`},
207
+ body:JSON.stringify(b),
208
+ }).then(r=>r.json());
209
+
210
+ // 1. 登录
211
+ const { token: tok } = await post("/api/login", {email, password});
212
+
213
+ // 2. 铸造 gen token(此处扣费)
214
+ // body: { token: tok, prompt, size: "1K"|"2K", pool: "premium"|null, ratio }
215
+ const { token: gt } = await post("/api/generate-token", {
216
+ token: tok,
217
+ prompt: "...",
218
+ size: "1K",
219
+ pool: null, // null=标准池;premium 显式传 "premium"
220
+ ratio: "16:9",
221
+ });
222
+
223
+ // 3. 入队
224
+ const { jobId } = await post("/api/gen-async", { token: gt });
225
+
226
+ // 4. 轮询 /api/gen-result,status 序列:queued → polishing → imaging → qa → done(终态还有 error)
227
+ for (;;) {
228
+ const r = await post("/api/gen-result", { token: tok, id: jobId });
229
+ if (r.status === "done") return r.imageUrl; // 直接可用的图 URL
230
+ if (r.status === "error" || r.error) throw new Error(JSON.stringify(r));
231
+ await new Promise(s => setTimeout(s, 5000));
232
+ }
233
+ ```
234
+
235
+ ⚠️ 路径 B **没有等价 `polish:false` 开关**——上游限频期偏慢或失败时,急用请走路径 A。
236
+
237
+ ---
238
+
239
+ ## 一键临摹 `mode: "replica"`(2026-09-18)
240
+
241
+ **什么时候用**:用户给了一张现成的科研图(示意图 / 流程图 / 机制图 / 图形摘要 / 体系结构图),要求"照这个画一版 / 重画一张 / 保持结构一致",或者想把别人论文里那张图重做成自己的一套图。**这是这种需求的首选参数**,比自己揣摩着写 prompt 准得多。
242
+
243
+ **和普通参考图的区别**(关键,决定该不该用它):
244
+
245
+ | | 普通参考图(refUrl/refDataUrl) | 一键临摹(+ mode:"replica") |
246
+ |---|---|---|
247
+ | 参考图给谁 | 只给生图模型,提示词层不知道它存在 | 先送**视觉模型**读成结构化清单,再由清单驱动提示词与审查 |
248
+ | 保真依据 | 靠模型看图即兴 | 清单逐条比对(漏项/多项/编造都能判) |
249
+ | 适合 | 只借风格、构图、配色 | 要**结构一致**的复刻 |
250
+
251
+ **请求**(必须带参考图,`prompt` 可留空):
252
+
253
+ ```bash
254
+ gen '{"mode":"replica","refUrl":"https://.../figure3.png","model":"premium","ratio":"16:9"}' replica.png
255
+ # prompt 也可以写要点,例如 {"mode":"replica","prompt":"改成中文标注","refUrl":"..."}
256
+ ```
257
+
258
+ **响应里的 `referenceSpec` 就是那份清单**,可拿来核对本次出图:
259
+
260
+ ```jsonc
261
+ {
262
+ "canvas": "16:9 landscape", // ⚠️ 视觉模型对该字段不稳定,仅供方向参考(真实比例由 ratio 决定)
263
+ "layout": "three phases stacked vertically, Phase II splits into 3 parallel columns",
264
+ "sections": [{ "id": "a", "role": "..." }],
265
+ "palette": [{ "role": "process steps", "color": "light green" }],
266
+ "text": [{ "s": "MAPE 8.3%", "kind": "label", "lang": "en", "readable": true }],
267
+ "elements": [{ "name": "Data preprocessing box", "kind": "box", "note": "green rounded" }],
268
+ "relations":["Data -> Raw data box", "Decision diamond -> ... (no/tighten constraints)"],
269
+ "photos": ["western blot panel"],
270
+ "ambiguities": ["exact arrow connectivity not individually drawn"]
271
+ }
272
+ ```
273
+
274
+ - `text` 是**原样抄录**(不翻译、不纠错),出图的图上文字按它逐字渲染——所以它也是"中文/英文标注是否正确"的验收依据。`readable:false` 的条目会用中性占位,不会瞎猜。
275
+ - `photos` 里的区域会以**示意方式**重绘,不会伪造显微照片/电泳条带细节(科研场景伪造图像属于学术不端)。
276
+
277
+ **约束与错误码**:
278
+
279
+ | 情况 | 结果 |
280
+ |---|---|
281
+ | 没带参考图 | `400 replica_requires_reference`(不扣费) |
282
+ | 参考图 base64 后 >8MB | `413 replica_reference_too_large`(临摹要把图送视觉模型,上限比普通参考图紧;压缩/裁剪后重试) |
283
+ | 视觉轮失败 | 不报错:退化为"带图直接写提示词",`specError` 带原因,正常计费 |
284
+ | 润色失败 | `502 orchestration_failed` + **自动退款**(与普通生成同一闭环) |
285
+
286
+ **不适合临摹的**:照片/显微照片/电泳图**本身**(要的是保真像素,不是重画);数据图表里要精确到像素的坐标轴排布。
287
+
288
+ ---
289
+
290
+ ## 批处理
291
+
292
+ 必须串行 + 429 退避:
293
+
294
+ ```python
295
+ import time, requests
296
+ def gen(prompt, **kw):
297
+ for attempt in range(4):
298
+ r = requests.post(URL, headers=H,
299
+ json={"prompt": prompt, **kw}, # 正常:不传 polish
300
+ timeout=300)
301
+ if r.status_code == 429:
302
+ time.sleep(2 ** attempt); continue
303
+ if r.status_code == 502:
304
+ time.sleep(1); continue # 已退款,可安全重试
305
+ r.raise_for_status()
306
+ return r.json()
307
+ raise RuntimeError("retry exhausted")
308
+ ```
309
+
310
+ ❌ 不要并发——RPM 是账号级窗口,并发只会换来 429,总吞吐不变。
311
+ ✅ 预算有限时先跑 `standard` 看构图,定了再跑 `premium` 出终稿。
312
+
313
+ ---
314
+
315
+ ## 不适合本 API 的场景
316
+
317
+ - 需要**精确数据绑定**的图表(要有真实 CSV 数值驱动)→ 用 matplotlib / ggplot 画更准确
318
+ - 超大分辨率打印级图(最高 2K)
319
+ - 严格可复现、像素级可控的排版
@@ -0,0 +1,119 @@
1
+ # 每轮交付与台账(round deliverables & ledger)
2
+
3
+ > 场景:每次用 promptFigure 出图 / 优化图片 / 整文批处理结束后,宿主 AI 必须按本文件产出结构化交付。
4
+ > 目的:用户随时能回答三个问题——**这轮做了什么图、图插在原文哪里、用了什么上下文/数据**。
5
+ > 🔴 本文件是硬性协议:缺任何一项 = 交付不完整。CLI 优先——全程用 `pf` 命令沉淀状态,GUI 只留给人「看一眼 / 点审批」。
6
+
7
+ ---
8
+
9
+ ## 0. CLI 优先原则(2026-09-25 定规)
10
+
11
+ - 出图、核验、审批、定稿全链路都有 CLI:`pf open → craft → render → qa → review resolve → premium`,**能用 CLI 就用 CLI**
12
+ - GUI 只用于两件事:人亲眼看图、人点审批。插件的门禁与留痕都挂在 CLI 上,走 CLI 的每一步都可审计
13
+ - 每轮结束的交付目录里,路径一律引用**用户本机真实路径**(相对当前交付目录优先,跨目录用绝对路径),禁止只给「见图库」这类指不到文件的话
14
+
15
+ ---
16
+
17
+ ## 1. 交付目录结构(每一轮 = 一个新文件夹)
18
+
19
+ 在**用户当前工作目录**(论文旁边)建 `promptfigure-out/`,每轮交付新建递增版本文件夹:
20
+
21
+ ```
22
+ promptfigure-out/
23
+ ├── v1/ ← 第 1 轮交付(每次交付新建一个,v1 → v2 → v3…)
24
+ │ ├── round-v1.md ← 本轮反馈(见 §2 必含项)
25
+ │ └── figures/ ← 本轮产出的图(文件名带版本号)
26
+ │ ├── fig-method-v1.png
27
+ │ └── fig-method-v2.png ← 改版后重新出,旧版保留可回溯
28
+ ├── v2/round-v2.md ← 第 2 轮……
29
+ ├── paper-with-figures.md ← 不断演进的「论文 + 已插图」版(见 §3)
30
+ └── final/ ← 最终论文版本(见 §4,仅最终成稿时建)
31
+ ├── paper-final.md
32
+ └── paper-final.docx ← 格式副本,按用户原文档格式(见 §4)
33
+ ```
34
+
35
+ - 版本号判断:`ls promptfigure-out/` 取最大 N + 1;用户已有自己的目录约定时听用户的
36
+ - `figures/` 里的图**永不覆盖**:同一张图的每个版本都是独立文件(`-v1/-v2/…`),旧版要能随时打开对比
37
+
38
+ ---
39
+
40
+ ## 2. round-vN.md 必含项(本轮反馈)
41
+
42
+ 模板(每轮照此填,没有的项目写「无」并说明原因,禁止静默省略):
43
+
44
+ ```markdown
45
+ # 第 N 轮交付 · YYYY-MM-DD HH:mm
46
+
47
+ ## 本轮清单
48
+ | # | 图 | 图种 | 档位 | 版本 | 本机路径 | 插入位置(§¶) | 状态 |
49
+ |---|---|---|---|---|---|---|---|
50
+ | 1 | 方法流程图 | pipeline | premium | v2 | figures/fig-method-v2.png | §2 ¶1 ↔ §2 ¶2 之间 | 已审批 |
51
+
52
+ ## 插入位置(图放在原文哪两段之间)
53
+ 逐张图给出——**上一段最后一句 + 「……」 + 下一段第一句**,让用户一眼定位:
54
+
55
+ > ……la optimización por enjambre de partículas ajusta automáticamente los principales parámetros.……La estrategia de aumento de datos incluye recorte aleatorio, jitter de color y deformación elástica.
56
+ > (图 1 插在上述两句之间,即 §2 ¶1 末 ↔ §2 ¶2 首)
57
+
58
+ - 自然段为粒度(¶),不用句号硬切;原文没有下一段时注明「§2 段末,文末」
59
+
60
+ ## 所用上下文(只放首尾句,中间省略)
61
+ - 原文上下文:「首句……尾句」(禁止整段贴入;用了哪几段就列哪几条,§¶ 标清楚)
62
+ - 引用范围声明:本次生成具体使用了 §2 ¶1–¶2(明确到段,供用户核对)
63
+
64
+ ## 数据与引用
65
+ - 本地表格/数据文件:[table1.csv](../data/table1.csv)、[run_exp2.m](../code/run_exp2.m) —— **只给引用链接,不内联内容**
66
+ - 参考图:refDataUrl(本地图 /path/to/ref.png)或 refUrl(https://…);用了就标,没用写「无」
67
+
68
+ ## 优化前 → 优化后(仅「优化已有图」任务)
69
+ | 图 | 优化前 | 优化后 | 改了什么 | 所用上下文(首尾句) |
70
+ |---|---|---|---|---|
71
+ | 原图1(曲线组) | figures/orig/fig1-old.png | figures/fig1-v1.png | 色板改语义化、字号 8pt、去 3D | 「首句……尾句」 |
72
+ ```
73
+
74
+ **三条填写铁律**:
75
+ 1. **上下文只放首句 + 尾句,中间一律省略号**——整段进 MD 会让用户无法快速审阅,也让版本 diff 爆炸
76
+ 2. **表格 / 代码 / 数据文件一律引用链接,禁止内联内容**——内联会让 MD 迅速腐烂、版本更新时无法对账;要「看见这轮用了什么」,点链接就是
77
+ 3. **每张图必须看得到版本**(文件名 `-vN` + 清单里的版本列 + 状态列)——版本是回溯和 diff 的唯一坐标
78
+
79
+ ---
80
+
81
+ ## 3. paper-with-figures.md(不断演进的呈现版)
82
+
83
+ - 结构 = 用户原文的章节树;**本轮涉及的段落**照录,**不涉及的段落**一律省略为一行:`……(§3 全文见原文)`
84
+ - 每张图插在自己的插入位置(§2 ¶1 ↔ ¶2 之间),图片用相对路径引用 vN 文件夹里的真实文件
85
+ - 每次交付**更新同一个文件**(或在文件名带版本 `paper-with-figures.vN.md` 保留历史)——用户随时打开这一个文件就能看到「论文现在长什么样」
86
+
87
+ ---
88
+
89
+ ## 4. final/ 最终论文版本
90
+
91
+ 用户要求「最终成稿 / 定稿」时才建,包含:
92
+
93
+ 1. `final/paper-final.md`——最终呈现版(全部已审批图就位、引用与上下文清单汇总)
94
+ 2. `final/paper-final.<用户格式>`——**格式副本,按用户原文档格式来**:
95
+ - Word/.docx → 交付 .docx(有 pandoc/docx 工具就用;无工具要明说「做不了格式副本,交付 MD」)
96
+ - LaTeX/.tex → 交付 .tex(图用 `\includegraphics` 引用真实路径,结构可编译)
97
+ - WPS → 交付 .docx(WPS 可直接打开)
98
+ - 🔴 **副本必须能正常打开**:交付前自己验证(文件非零、结构完整、能找到图);验证不了就明说,禁止交一个打不开的坏副本
99
+
100
+ ---
101
+
102
+ ## 5. 最终成稿流程(用户说「定稿 / 最终版」时按此走)
103
+
104
+ 1. **先提醒核对**:提醒用户「数据有没有更新?要不要重新跑一次核验?」——用户明确确认后,才进入 premium 最终定稿
105
+ 2. **确认高级定稿**:向用户复述「将消耗 premium 档额度出高清定稿,N 张」并取得确认;未确认不动手
106
+ 3. **定稿后问矢量图**(衔接 SKILL.md 阶段 5):
107
+ - 提醒成本:矢量图由**用户自己的 AI 本地重绘**,token 消耗大、速度慢
108
+ - 🔴 **比赛 / 数学建模 / 学术会议竞赛:默认不做**,速度优先;只有时间充裕才做
109
+ 4. **用户确认做矢量图时**:把最终图**按元素分层重绘**为可编辑矢量(PPT 形状 / 分层 SVG 分组,每个模块、箭头、标签是独立对象),在用户偏好的应用里操作——**PPT 还是 WPS 还是其他,按用户主要偏好来**;描摹矢量(位图转路径)一律禁止
110
+
111
+ ---
112
+
113
+ ## 6. 自检清单(每轮交付前过一遍)
114
+
115
+ - [ ] 版本文件夹新建(vN 递增)、图带版本号、旧版未覆盖
116
+ - [ ] round-vN.md 五项齐:清单 / 插入位置(两段边界句)/ 上下文(首尾句)/ 数据引用(链接)/ 优化前后(如适用)
117
+ - [ ] paper-with-figures.md 已更新到含本轮所有图
118
+ - [ ] 路径全部指得到真实文件(md 里的链接点得开)
119
+ - [ ] final/ 仅在最终成稿时出现,格式副本已验证可打开