@aigne/doc-smith 0.8.2 → 0.8.4
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.
- package/.aigne/doc-smith/config.yaml +3 -3
- package/.aigne/doc-smith/preferences.yml +58 -12
- package/.aigne/doc-smith/upload-cache.yaml +600 -207
- package/CHANGELOG.md +17 -0
- package/README.md +77 -5
- package/docs/advanced-how-it-works.md +55 -60
- package/docs/advanced-how-it-works.zh.md +60 -65
- package/docs/advanced-quality-assurance.md +73 -38
- package/docs/advanced-quality-assurance.zh.md +73 -38
- package/docs/advanced.md +2 -14
- package/docs/advanced.zh.md +5 -17
- package/docs/changelog.md +41 -4
- package/docs/changelog.zh.md +77 -40
- package/docs/cli-reference.md +79 -13
- package/docs/cli-reference.zh.md +92 -26
- package/docs/configuration-interactive-setup.md +102 -49
- package/docs/configuration-interactive-setup.zh.md +102 -49
- package/docs/configuration-language-support.md +69 -39
- package/docs/configuration-language-support.zh.md +68 -38
- package/docs/configuration-llm-setup.md +25 -62
- package/docs/configuration-llm-setup.zh.md +25 -62
- package/docs/configuration-preferences.md +79 -67
- package/docs/configuration-preferences.zh.md +78 -67
- package/docs/configuration.md +122 -109
- package/docs/configuration.zh.md +130 -117
- package/docs/features-generate-documentation.md +44 -24
- package/docs/features-generate-documentation.zh.md +52 -32
- package/docs/features-publish-your-docs.md +41 -40
- package/docs/features-publish-your-docs.zh.md +50 -49
- package/docs/features-translate-documentation.md +73 -17
- package/docs/features-translate-documentation.zh.md +76 -20
- package/docs/features-update-and-refine.md +72 -21
- package/docs/features-update-and-refine.zh.md +80 -29
- package/docs/features.md +24 -28
- package/docs/features.zh.md +25 -29
- package/docs/getting-started.md +87 -38
- package/docs/getting-started.zh.md +88 -39
- package/docs/overview.md +17 -35
- package/docs/overview.zh.md +18 -36
- package/package.json +9 -8
- package/prompts/content-detail-generator.md +1 -0
- package/prompts/document/custom-code-block.md +101 -0
- package/prompts/document/d2-chart/rules.md +941 -1031
- package/prompts/document/detail-generator.md +7 -53
- package/tests/kroki-utils.test.mjs +88 -17
- package/utils/constants.mjs +15 -1
- package/utils/kroki-utils.mjs +22 -14
- package/utils/markdown-checker.mjs +1 -1
- package/utils/utils.mjs +3 -2
- package/prompts/document/d2-chart/diy-examples.md +0 -44
- package/prompts/document/d2-chart/shape-rules.md +0 -182
|
@@ -15,9 +15,6 @@
|
|
|
15
15
|
- 说明要尽可能的详细,如果存在配置项或参数,需要解释每个配置项或参数的含义,如果参数有多个可选值,每种可选值需要解释其含义,并尽可能配上代码示例
|
|
16
16
|
- 参数优先使用 markdown 中的 table 来展示,让内容看上去更整齐,容易阅读
|
|
17
17
|
- 接口/方法调用的说明必须包含 **响应数据示例**
|
|
18
|
-
- 尽可能少的使用 d2 图表,图表中错误的逻辑会导致文档效果更差,绘制 d2 的图表一定要确保可读性和正确性
|
|
19
|
-
- 概览部分,建议包含 d2 图表展示产品架构图
|
|
20
|
-
{% include "d2-chart/rules.md" %}
|
|
21
18
|
- 对输出的 markdown 进行检查,确认输出内容完整,table、d2 信息完整并且格式正确
|
|
22
19
|
- **确保内容完整性**:在生成任何文档内容,特别是代码块(如 d2、JSON、代码等)时,必须确保其是**完整且语法正确**的。在输出完成后,必须进行一次**自我检查**,确认所有的代码块、列表、表格等都已完全闭合且没有中途截断。
|
|
23
20
|
- **代码块原子性**:将每个代码块(例如 ```d2 ... ```)视为一个**不可分割的原子单元**。必须一次性完整生成,从开始标记(```d2)到结束标记(```)之间的所有内容都不能省略或截断。
|
|
@@ -29,6 +26,13 @@
|
|
|
29
26
|
|
|
30
27
|
</document_rules>
|
|
31
28
|
|
|
29
|
+
<document_rules>
|
|
30
|
+
|
|
31
|
+
D2 Diagram Generation Expert Guide:
|
|
32
|
+
{% include "d2-chart/rules.md" %}
|
|
33
|
+
|
|
34
|
+
</document_rules>
|
|
35
|
+
|
|
32
36
|
<TONE_STYLE>
|
|
33
37
|
- Documentation should be plain, rigorous and accurate, avoiding grandiose or empty vocabulary
|
|
34
38
|
- You are writing for humans, not algorithms
|
|
@@ -42,54 +46,4 @@
|
|
|
42
46
|
- Use contractions and idioms sparingly to maintain an informal, yet credible tone
|
|
43
47
|
- Blend technical precision with relatable language
|
|
44
48
|
- Be direct: say what happened, why it matters, and how it helps
|
|
45
|
-
|
|
46
|
-
Example Tone Transformations
|
|
47
|
-
❌ "We’re thrilled to announce our most powerful update yet…"
|
|
48
|
-
✅ "You can now include location and timestamp metadata for each claim, enabling audit-ready transparency."
|
|
49
|
-
|
|
50
|
-
❌ "Unlock the future of verification."
|
|
51
|
-
✅ "This release makes real-world claims independently verifiable across sectors."
|
|
52
49
|
</TONE_STYLE>
|
|
53
|
-
|
|
54
|
-
<WORDS_PHRASES_TO_AVOID>
|
|
55
|
-
|
|
56
|
-
Do not use promotional fluff or filler emotion. Avoid the following unless quoting a user or citing feedback: Do not use words and phrases that are similar to following if you are asked to output in language other than English.
|
|
57
|
-
|
|
58
|
-
<emotion-words>
|
|
59
|
-
excited
|
|
60
|
-
thrilled
|
|
61
|
-
delighted
|
|
62
|
-
proud to announce
|
|
63
|
-
happy to share
|
|
64
|
-
Overused Adjectives:
|
|
65
|
-
powerful
|
|
66
|
-
seamless
|
|
67
|
-
revolutionary
|
|
68
|
-
robust
|
|
69
|
-
amazing
|
|
70
|
-
significant
|
|
71
|
-
transformative
|
|
72
|
-
innovative
|
|
73
|
-
disruptive
|
|
74
|
-
groundbreaking
|
|
75
|
-
</emotion-words>
|
|
76
|
-
|
|
77
|
-
<generic-hype-verbs>
|
|
78
|
-
unlock
|
|
79
|
-
unleash
|
|
80
|
-
empower
|
|
81
|
-
elevate
|
|
82
|
-
reimagine
|
|
83
|
-
transform
|
|
84
|
-
Empty Marketing Phrases:
|
|
85
|
-
in today's world
|
|
86
|
-
at the end of the day
|
|
87
|
-
best practices
|
|
88
|
-
end-to-end
|
|
89
|
-
game changer
|
|
90
|
-
cutting edge
|
|
91
|
-
</generic-hype-verbs>
|
|
92
|
-
|
|
93
|
-
➡️ Instead, focus on concrete outcomes and observable benefits.
|
|
94
|
-
Example: “Now includes location and timestamp for each field report” is better than “a powerful new update.”
|
|
95
|
-
</WORDS_PHRASES_TO_AVOID>
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
2
|
import { existsSync, mkdtemp, rmdir } from "node:fs";
|
|
3
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
|
|
7
|
+
import Debug from "debug";
|
|
8
|
+
|
|
9
|
+
import { TMP_ASSETS_DIR } from "../utils/constants.mjs";
|
|
7
10
|
import {
|
|
8
11
|
beforePublishHook,
|
|
9
12
|
checkD2Content,
|
|
@@ -238,20 +241,33 @@ E -> F
|
|
|
238
241
|
|
|
239
242
|
test("should skip generation if SVG file already exists", async () => {
|
|
240
243
|
const docsDir = path.join(tempDir, "docs");
|
|
241
|
-
|
|
242
|
-
await mkdir(assetsDir, { recursive: true });
|
|
243
|
-
|
|
244
|
+
await mkdir(docsDir, { recursive: true });
|
|
244
245
|
const markdown = `\`\`\`d2\nA -> B\n\`\`\``;
|
|
245
246
|
|
|
246
|
-
//
|
|
247
|
-
|
|
248
|
-
await writeFile(path.join(assetsDir, "test.svg"), testSvgContent);
|
|
247
|
+
// 1. First run to generate the file
|
|
248
|
+
await saveD2Assets({ markdown, docsDir });
|
|
249
249
|
|
|
250
|
-
//
|
|
251
|
-
const
|
|
250
|
+
// 2. Second run to check if cache is used
|
|
251
|
+
const debugLogs = [];
|
|
252
|
+
const originalWrite = process.stderr.write;
|
|
253
|
+
process.stderr.write = (chunk) => {
|
|
254
|
+
debugLogs.push(chunk.toString());
|
|
255
|
+
return true;
|
|
256
|
+
};
|
|
257
|
+
Debug.enable("doc-smith");
|
|
252
258
|
|
|
253
|
-
|
|
254
|
-
|
|
259
|
+
try {
|
|
260
|
+
const result = await saveD2Assets({ markdown, docsDir });
|
|
261
|
+
|
|
262
|
+
expect(typeof result).toBe("string");
|
|
263
|
+
expect(result).toContain(`}`);
|
|
264
|
+
expect(
|
|
265
|
+
debugLogs.some((log) => log.includes("Found assets cache, skipping generation")),
|
|
266
|
+
).toBe(true);
|
|
267
|
+
} finally {
|
|
268
|
+
process.stderr.write = originalWrite;
|
|
269
|
+
Debug.disable();
|
|
270
|
+
}
|
|
255
271
|
});
|
|
256
272
|
|
|
257
273
|
test("should handle D2 generation errors gracefully", async () => {
|
|
@@ -273,6 +289,28 @@ E -> F
|
|
|
273
289
|
global.fetch = originalFetch;
|
|
274
290
|
}
|
|
275
291
|
});
|
|
292
|
+
|
|
293
|
+
test("should write .d2 file when debug is enabled", async () => {
|
|
294
|
+
const docsDir = path.join(tempDir, "docs");
|
|
295
|
+
await mkdir(docsDir, { recursive: true });
|
|
296
|
+
|
|
297
|
+
const markdown = `\`\`\`d2\nA -> B\n\`\`\``;
|
|
298
|
+
|
|
299
|
+
// Enable debug mode
|
|
300
|
+
Debug.enable("doc-smith");
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
await saveD2Assets({ markdown, docsDir });
|
|
304
|
+
|
|
305
|
+
const assetDir = path.join(docsDir, "../", TMP_ASSETS_DIR, "d2");
|
|
306
|
+
const files = await readdir(assetDir);
|
|
307
|
+
const d2File = files.find((file) => file.endsWith(".d2"));
|
|
308
|
+
expect(d2File).toBeDefined();
|
|
309
|
+
} finally {
|
|
310
|
+
// Restore debug mode
|
|
311
|
+
Debug.disable();
|
|
312
|
+
}
|
|
313
|
+
});
|
|
276
314
|
});
|
|
277
315
|
|
|
278
316
|
describe("beforePublishHook", () => {
|
|
@@ -350,13 +388,29 @@ E -> F
|
|
|
350
388
|
// First call should generate
|
|
351
389
|
await checkD2Content({ content });
|
|
352
390
|
|
|
353
|
-
// Second call should use cache
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
391
|
+
// Second call should use cache
|
|
392
|
+
const debugLogs = [];
|
|
393
|
+
const originalWrite = process.stderr.write;
|
|
394
|
+
process.stderr.write = (chunk) => {
|
|
395
|
+
debugLogs.push(chunk.toString());
|
|
396
|
+
return true;
|
|
397
|
+
};
|
|
398
|
+
Debug.enable("doc-smith");
|
|
357
399
|
|
|
358
|
-
|
|
359
|
-
|
|
400
|
+
try {
|
|
401
|
+
const startTime = Date.now();
|
|
402
|
+
await checkD2Content({ content });
|
|
403
|
+
const endTime = Date.now();
|
|
404
|
+
|
|
405
|
+
// Cache hit should be very fast (< 100ms)
|
|
406
|
+
expect(endTime - startTime).toBeLessThan(100);
|
|
407
|
+
expect(
|
|
408
|
+
debugLogs.some((log) => log.includes("Found assets cache, skipping generation")),
|
|
409
|
+
).toBe(true);
|
|
410
|
+
} finally {
|
|
411
|
+
process.stderr.write = originalWrite;
|
|
412
|
+
Debug.disable();
|
|
413
|
+
}
|
|
360
414
|
});
|
|
361
415
|
|
|
362
416
|
test("should handle generation errors in strict mode", async () => {
|
|
@@ -391,6 +445,23 @@ E -> F
|
|
|
391
445
|
expect(error).toBeDefined();
|
|
392
446
|
}
|
|
393
447
|
});
|
|
448
|
+
|
|
449
|
+
test("should write .d2 file when debug is enabled", async () => {
|
|
450
|
+
const content = "A -> B: debug test";
|
|
451
|
+
|
|
452
|
+
Debug.enable("doc-smith");
|
|
453
|
+
|
|
454
|
+
try {
|
|
455
|
+
await checkD2Content({ content });
|
|
456
|
+
|
|
457
|
+
const assetDir = path.join(process.cwd(), ".aigne", "doc-smith", ".tmp", "assets", "d2");
|
|
458
|
+
const files = await readdir(assetDir);
|
|
459
|
+
const d2File = files.find((file) => file.endsWith(".d2"));
|
|
460
|
+
expect(d2File).toBeDefined();
|
|
461
|
+
} finally {
|
|
462
|
+
Debug.disable();
|
|
463
|
+
}
|
|
464
|
+
});
|
|
394
465
|
});
|
|
395
466
|
|
|
396
467
|
describe("ensureTmpDir", () => {
|
package/utils/constants.mjs
CHANGED
|
@@ -513,7 +513,21 @@ export const RESOLUTION_STRATEGIES = {
|
|
|
513
513
|
export const D2_CONFIG = `vars: {
|
|
514
514
|
d2-config: {
|
|
515
515
|
layout-engine: elk
|
|
516
|
-
theme-id:
|
|
516
|
+
theme-id: 105
|
|
517
|
+
theme-overrides: {
|
|
518
|
+
N1: "#18181B"
|
|
519
|
+
N2: "#421E0B"
|
|
520
|
+
N4: "#E6E8EC"
|
|
521
|
+
N5: "#E6E8EC"
|
|
522
|
+
|
|
523
|
+
B3: "#FFE9D1"
|
|
524
|
+
B4: "transparent"
|
|
525
|
+
|
|
526
|
+
AA2: "#421E0B"
|
|
527
|
+
AA4: "#FFE9D1"
|
|
528
|
+
|
|
529
|
+
AB4: "#FBF4E4"
|
|
530
|
+
}
|
|
517
531
|
}
|
|
518
532
|
}`;
|
|
519
533
|
|
package/utils/kroki-utils.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
|
|
3
|
+
import Debug from "debug";
|
|
3
4
|
import fs from "fs-extra";
|
|
4
5
|
import { glob } from "glob";
|
|
5
6
|
import pMap from "p-map";
|
|
@@ -14,6 +15,8 @@ import {
|
|
|
14
15
|
} from "./constants.mjs";
|
|
15
16
|
import { getContentHash } from "./utils.mjs";
|
|
16
17
|
|
|
18
|
+
const debug = Debug("doc-smith");
|
|
19
|
+
|
|
17
20
|
export async function getChart({ chart = "d2", format = "svg", content, strict }) {
|
|
18
21
|
const baseUrl = "https://chart.abtnet.io";
|
|
19
22
|
|
|
@@ -56,7 +59,7 @@ export async function saveD2Assets({ markdown, docsDir }) {
|
|
|
56
59
|
return markdown;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
|
-
const codeBlockRegex = /```d2
|
|
62
|
+
const codeBlockRegex = /```d2.*\n([\s\S]*?)```/g;
|
|
60
63
|
|
|
61
64
|
const { replaced } = await runIterator({
|
|
62
65
|
input: markdown,
|
|
@@ -70,26 +73,26 @@ export async function saveD2Assets({ markdown, docsDir }) {
|
|
|
70
73
|
const svgPath = path.join(assetDir, fileName);
|
|
71
74
|
|
|
72
75
|
if (await fs.pathExists(svgPath)) {
|
|
73
|
-
|
|
74
|
-
console.log("Found assets cache, skipping generation", svgPath);
|
|
75
|
-
}
|
|
76
|
+
debug("Found assets cache, skipping generation", svgPath);
|
|
76
77
|
} else {
|
|
77
|
-
if (process.env.DEBUG) {
|
|
78
|
-
console.log("start generate d2 chart", svgPath);
|
|
79
|
-
}
|
|
80
78
|
try {
|
|
79
|
+
debug("start generate d2 chart", svgPath);
|
|
80
|
+
if (debug.enabled) {
|
|
81
|
+
const d2FileName = `${getContentHash(d2Content)}.d2`;
|
|
82
|
+
const d2Path = path.join(assetDir, d2FileName);
|
|
83
|
+
await fs.writeFile(d2Path, d2Content, { encoding: "utf8" });
|
|
84
|
+
}
|
|
85
|
+
|
|
81
86
|
const svg = await getD2Svg({ content: d2Content });
|
|
82
87
|
if (svg) {
|
|
83
88
|
await fs.writeFile(svgPath, svg, { encoding: "utf8" });
|
|
84
89
|
}
|
|
85
90
|
} catch (error) {
|
|
86
|
-
|
|
87
|
-
console.warn("Failed to generate D2 chart:", error);
|
|
88
|
-
}
|
|
91
|
+
debug("Failed to generate D2 chart:", error);
|
|
89
92
|
return _code;
|
|
90
93
|
}
|
|
91
94
|
}
|
|
92
|
-
return `})`;
|
|
93
96
|
},
|
|
94
97
|
options: { concurrency: KROKI_CONCURRENCY },
|
|
95
98
|
});
|
|
@@ -146,10 +149,15 @@ export async function checkD2Content({ content }) {
|
|
|
146
149
|
const d2Content = [D2_CONFIG, content].join("\n");
|
|
147
150
|
const fileName = `${getContentHash(d2Content)}.svg`;
|
|
148
151
|
const svgPath = path.join(assetDir, fileName);
|
|
152
|
+
|
|
153
|
+
if (debug.enabled) {
|
|
154
|
+
const d2FileName = `${getContentHash(d2Content)}.d2`;
|
|
155
|
+
const d2Path = path.join(assetDir, d2FileName);
|
|
156
|
+
await fs.writeFile(d2Path, d2Content, { encoding: "utf8" });
|
|
157
|
+
}
|
|
158
|
+
|
|
149
159
|
if (await fs.pathExists(svgPath)) {
|
|
150
|
-
|
|
151
|
-
console.log("Found assets cache, skipping generation", svgPath);
|
|
152
|
-
}
|
|
160
|
+
debug("Found assets cache, skipping generation", svgPath);
|
|
153
161
|
return;
|
|
154
162
|
}
|
|
155
163
|
|
|
@@ -243,7 +243,7 @@ function checkLocalImages(markdown, source, errorMessages, markdownFilePath, bas
|
|
|
243
243
|
*/
|
|
244
244
|
function checkContentStructure(markdown, source, errorMessages) {
|
|
245
245
|
const lines = markdown.split("\n");
|
|
246
|
-
const allCodeBlockRegex = /^\s
|
|
246
|
+
const allCodeBlockRegex = /^\s*```.*$/;
|
|
247
247
|
|
|
248
248
|
// State variables for different checks
|
|
249
249
|
let inCodeBlock = false;
|
package/utils/utils.mjs
CHANGED
|
@@ -1158,6 +1158,7 @@ export function detectSystemLanguage() {
|
|
|
1158
1158
|
}
|
|
1159
1159
|
}
|
|
1160
1160
|
|
|
1161
|
-
export function getContentHash(str) {
|
|
1162
|
-
|
|
1161
|
+
export function getContentHash(str, { trim = true } = {}) {
|
|
1162
|
+
const input = trim && typeof str === "string" ? str.trim() : str;
|
|
1163
|
+
return crypto.createHash("sha256").update(input).digest("hex");
|
|
1163
1164
|
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
- 结构图示例:
|
|
2
|
-
```d2
|
|
3
|
-
App: Application
|
|
4
|
-
API: API Server
|
|
5
|
-
DB: Database
|
|
6
|
-
|
|
7
|
-
App -> API: 调用
|
|
8
|
-
API -> DB: 读写数据
|
|
9
|
-
```
|
|
10
|
-
- 流程图示例:
|
|
11
|
-
```d2
|
|
12
|
-
start: 开始
|
|
13
|
-
input: 用户输入
|
|
14
|
-
process: 处理数据
|
|
15
|
-
output: 输出结果
|
|
16
|
-
end: 结束
|
|
17
|
-
|
|
18
|
-
start -> input -> process -> output -> end
|
|
19
|
-
```
|
|
20
|
-
- 时序图示例:
|
|
21
|
-
```d2
|
|
22
|
-
User: 用户
|
|
23
|
-
Service: 服务
|
|
24
|
-
DB: 数据库
|
|
25
|
-
|
|
26
|
-
User -> Service: 请求
|
|
27
|
-
Service -> DB: 查询
|
|
28
|
-
DB -> Service: 返回数据
|
|
29
|
-
Service -> User: 响应
|
|
30
|
-
```
|
|
31
|
-
- 决策树示例:
|
|
32
|
-
```d2
|
|
33
|
-
start: 开始
|
|
34
|
-
check: 是否有效?
|
|
35
|
-
yes: 是
|
|
36
|
-
no: 否
|
|
37
|
-
end: 结束
|
|
38
|
-
|
|
39
|
-
start -> check
|
|
40
|
-
check -> yes: 有效
|
|
41
|
-
check -> no: 无效
|
|
42
|
-
yes -> end
|
|
43
|
-
no -> end
|
|
44
|
-
```
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
# D2 图表绘制 Shape 选择指南与 Prompt 模板
|
|
2
|
-
|
|
3
|
-
## 一、D2 Shape 类型与使用场景
|
|
4
|
-
|
|
5
|
-
### 基础 Shape 类型
|
|
6
|
-
- **rectangle** (默认): 通用节点、组件、系统模块
|
|
7
|
-
- **square**: 数据库、存储、配置项
|
|
8
|
-
- **circle**: 用户、角色、状态节点
|
|
9
|
-
- **oval**: 开始/结束节点、事件
|
|
10
|
-
- **diamond**: 决策节点、条件判断
|
|
11
|
-
- **parallelogram**: 输入/输出、数据流
|
|
12
|
-
- **hexagon**: 准备、预处理步骤
|
|
13
|
-
- **cylinder**: 数据库、数据存储
|
|
14
|
-
- **queue**: 消息队列、缓冲区
|
|
15
|
-
- **package**: 模块、包、容器
|
|
16
|
-
- **step**: 流程步骤
|
|
17
|
-
- **callout**: 注释、说明
|
|
18
|
-
- **stored_data**: 存储的数据
|
|
19
|
-
- **person**: 用户、角色
|
|
20
|
-
- **diamond**: 判断、网关
|
|
21
|
-
- **document**: 文档、报告
|
|
22
|
-
- **multiple_document**: 多个文档
|
|
23
|
-
- **class**: 类定义
|
|
24
|
-
- **sql_table**: 数据库表
|
|
25
|
-
- **image**: 图片、媒体
|
|
26
|
-
|
|
27
|
-
## 二、针对不同图表类型的 Prompt 模板
|
|
28
|
-
|
|
29
|
-
### 1. 系统架构图 Prompt
|
|
30
|
-
```
|
|
31
|
-
请使用 D2 语法绘制系统架构图,遵循以下 shape 选择规则:
|
|
32
|
-
- 用户/角色使用 person 或 circle
|
|
33
|
-
- 前端应用使用 rectangle
|
|
34
|
-
- API/服务使用 rectangle
|
|
35
|
-
- 数据库使用 cylinder 或 sql_table
|
|
36
|
-
- 缓存使用 queue
|
|
37
|
-
- 外部服务使用 package
|
|
38
|
-
- 负载均衡器使用 diamond
|
|
39
|
-
|
|
40
|
-
示例结构:
|
|
41
|
-
用户 -> 前端 -> API网关 -> 微服务 -> 数据库
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### 2. 流程图 Prompt
|
|
45
|
-
```
|
|
46
|
-
请使用 D2 语法绘制流程图,严格按照以下 shape 约定:
|
|
47
|
-
- 开始/结束节点:oval
|
|
48
|
-
- 处理步骤:rectangle
|
|
49
|
-
- 判断节点:diamond
|
|
50
|
-
- 输入/输出:parallelogram
|
|
51
|
-
- 准备步骤:hexagon
|
|
52
|
-
- 文档生成:document
|
|
53
|
-
- 数据存储:cylinder
|
|
54
|
-
|
|
55
|
-
连接线使用箭头表示流向,判断节点要标注 yes/no 分支。
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### 3. 数据流图 Prompt
|
|
59
|
-
```
|
|
60
|
-
使用 D2 绘制数据流图,shape 选择原则:
|
|
61
|
-
- 外部实体:square
|
|
62
|
-
- 数据处理:circle
|
|
63
|
-
- 数据存储:stored_data 或 cylinder
|
|
64
|
-
- 数据流:带标签的箭头连接
|
|
65
|
-
- 数据文件:document
|
|
66
|
-
|
|
67
|
-
确保数据流方向清晰,标注数据类型和流向。
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### 4. 组织架构图 Prompt
|
|
71
|
-
```
|
|
72
|
-
创建组织架构图,使用以下 D2 shape 规范:
|
|
73
|
-
- 高层管理:person (设置较大尺寸)
|
|
74
|
-
- 部门负责人:person
|
|
75
|
-
- 团队/部门:package
|
|
76
|
-
- 具体角色:circle
|
|
77
|
-
- 外部合作方:rectangle (虚线边框)
|
|
78
|
-
|
|
79
|
-
使用层次布局,体现汇报关系。
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## 三、通用优化 Prompt 模板
|
|
83
|
-
|
|
84
|
-
### 基础模板
|
|
85
|
-
```
|
|
86
|
-
请使用 D2 语法创建 [图表类型],要求:
|
|
87
|
-
|
|
88
|
-
1. **Shape 选择原则**:
|
|
89
|
-
- 根据元素功能选择最合适的 shape
|
|
90
|
-
- 保持同类元素使用相同 shape
|
|
91
|
-
- 重要元素可以使用特殊 shape 突出
|
|
92
|
-
|
|
93
|
-
2. **样式要求**:
|
|
94
|
-
- 使用合适的颜色区分不同类型的元素
|
|
95
|
-
- 重要路径使用加粗或特殊颜色
|
|
96
|
-
- 添加适当的标签和注释
|
|
97
|
-
|
|
98
|
-
3. **布局优化**:
|
|
99
|
-
- 使用合理的布局算法 (dagre, elk等)
|
|
100
|
-
- 避免连线交叉
|
|
101
|
-
- 保持整体美观和可读性
|
|
102
|
-
|
|
103
|
-
4. **语法规范**:
|
|
104
|
-
- 使用正确的 D2 语法
|
|
105
|
-
- 节点命名简洁明了
|
|
106
|
-
- 连接关系清晰表达
|
|
107
|
-
|
|
108
|
-
请提供完整的 D2 代码。
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### 高级定制模板
|
|
112
|
-
```
|
|
113
|
-
创建专业级 D2 图表,具体要求:
|
|
114
|
-
|
|
115
|
-
**图表信息**:[描述你要创建的图表]
|
|
116
|
-
|
|
117
|
-
**定制要求**:
|
|
118
|
-
1. **Shape 策略**:
|
|
119
|
-
- 为每种元素类型指定最佳 shape
|
|
120
|
-
- 列出 shape 选择理由
|
|
121
|
-
- 确保视觉一致性
|
|
122
|
-
|
|
123
|
-
2. **颜色方案**:
|
|
124
|
-
- 使用企业级配色
|
|
125
|
-
- 不同模块用不同颜色区分
|
|
126
|
-
- 突出关键路径
|
|
127
|
-
|
|
128
|
-
3. **高级功能**:
|
|
129
|
-
- 添加图标 (如需要)
|
|
130
|
-
- 使用容器分组相关元素
|
|
131
|
-
- 添加交互提示 (tooltip)
|
|
132
|
-
|
|
133
|
-
4. **性能考虑**:
|
|
134
|
-
- 节点数量控制在合理范围
|
|
135
|
-
- 避免过于复杂的嵌套
|
|
136
|
-
|
|
137
|
-
输出格式:
|
|
138
|
-
- D2 代码
|
|
139
|
-
- Shape 选择说明
|
|
140
|
-
- 使用建议
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
## 四、特定场景 Prompt 示例
|
|
144
|
-
|
|
145
|
-
### 网络拓扑图
|
|
146
|
-
```
|
|
147
|
-
绘制网络拓扑图,shape 使用规范:
|
|
148
|
-
- 路由器:diamond
|
|
149
|
-
- 交换机:rectangle
|
|
150
|
-
- 服务器:rectangle (填充色)
|
|
151
|
-
- 终端设备:circle
|
|
152
|
-
- 防火墙:hexagon
|
|
153
|
-
- 云服务:package
|
|
154
|
-
- 网络连接:实线
|
|
155
|
-
- 无线连接:虚线
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### 微服务架构图
|
|
159
|
-
```
|
|
160
|
-
设计微服务架构图:
|
|
161
|
-
- API Gateway:diamond
|
|
162
|
-
- 微服务:rectangle
|
|
163
|
-
- 数据库:cylinder
|
|
164
|
-
- 缓存:queue
|
|
165
|
-
- 消息队列:queue (不同颜色)
|
|
166
|
-
- 负载均衡:parallelogram
|
|
167
|
-
- 监控服务:circle
|
|
168
|
-
- 外部服务:package (虚线边框)
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### 业务流程图
|
|
172
|
-
```
|
|
173
|
-
业务流程建模:
|
|
174
|
-
- 开始事件:oval (绿色)
|
|
175
|
-
- 结束事件:oval (红色)
|
|
176
|
-
- 用户任务:rectangle
|
|
177
|
-
- 系统任务:rectangle (不同颜色)
|
|
178
|
-
- 网关决策:diamond
|
|
179
|
-
- 并行网关:diamond (特殊标记)
|
|
180
|
-
- 数据对象:document
|
|
181
|
-
- 消息流:虚线箭头
|
|
182
|
-
```
|