Repository navigation
Expand file tree
/
Copy pathapp.html
More file actions
655 lines (602 loc) · 41.6 KB
/
Copy pathapp.html
File metadata and controls
655 lines (602 loc) · 41.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Prompt Architect (with Gemini)</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
}
.prompt-field {
transition: all 0.3s ease;
}
.prompt-field:focus-within {
transform: translateY(-2px);
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
}
.fade-in {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.spinner {
border: 2px solid #f3f3f3;
border-top: 2px solid #6366f1;
border-radius: 50%;
width: 16px;
height: 16px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.template-card {
transition: all 0.25s ease;
}
.template-card:hover {
transform: translateY(-3px);
box-shadow: 0 10px 25px -5px rgb(0 0 0 / 0.1), 0 4px 10px -5px rgb(0 0 0 / 0.08);
}
.prompt-preview {
max-height: 0;
overflow: hidden;
transition: max-height 0.4s ease, padding 0.3s ease;
}
.prompt-preview.expanded {
max-height: 400px;
}
.tab-btn {
transition: all 0.2s ease;
}
.tab-btn.active {
background-color: #4f46e5;
color: white;
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
}
.tab-btn:not(.active) {
color: #64748b;
}
.tab-btn:not(.active):hover {
background-color: #f1f5f9;
color: #1e293b;
}
</style>
</head>
<body class="bg-slate-50 text-slate-900">
<div class="container mx-auto max-w-4xl p-4 md:p-8">
<!-- Header -->
<header class="text-center mb-8">
<h1 class="text-4xl md:text-5xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500">
Prompt Architect
</h1>
<p class="mt-2 text-lg text-slate-600">Xây dựng Prompt hoàn hảo với sức mạnh từ AI</p>
</header>
<!-- Tab Navigation -->
<div class="flex gap-2 mb-6 bg-white p-1.5 rounded-xl shadow-sm border border-slate-200">
<button id="tab-create-btn" class="tab-btn active flex-1 py-2.5 px-4 rounded-lg font-semibold text-sm">
✨ Tạo Prompt tùy chỉnh
</button>
<button id="tab-library-btn" class="tab-btn flex-1 py-2.5 px-4 rounded-lg font-semibold text-sm">
📚 Thư viện Prompt (10)
</button>
</div>
<!-- Panel: Tạo Prompt tùy chỉnh -->
<div id="panel-create">
<!-- Input Section -->
<div class="bg-white p-6 rounded-2xl shadow-lg border border-slate-200 space-y-6">
<div>
<label for="raw-input" class="block text-lg font-semibold mb-2 text-slate-800">1. Mô tả yêu cầu của bạn</label>
<p class="text-slate-500 mb-4">Hãy mô tả ngắn gọn điều bạn muốn AI thực hiện.</p>
<textarea id="raw-input" class="w-full p-4 border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition duration-200" rows="4" placeholder="Ví dụ: Lên kế hoạch cho một chuyến du lịch 3 ngày ở Đà Lạt..."></textarea>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label for="user-level" class="block text-base font-semibold mb-2 text-slate-800">2. Đối tượng người dùng</label>
<p class="text-slate-500 text-sm mb-3">Trình độ của người nhận câu trả lời.</p>
<select id="user-level" class="w-full p-3.5 bg-white border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition duration-200 text-sm">
<option value="Người mới bắt đầu (Newbie)">Người mới bắt đầu (Newbie)</option>
<option value="Người dùng phổ thông (Regular User)" selected>Người dùng phổ thông (Regular User)</option>
<option value="Trình độ khá (Advanced User)">Trình độ khá (Advanced User)</option>
<option value="Chuyên gia (Expert)">Chuyên gia (Expert)</option>
</select>
</div>
<div>
<label for="tone-style" class="block text-base font-semibold mb-2 text-slate-800">3. Phong cách giọng văn</label>
<p class="text-slate-500 text-sm mb-3">Kiểm soát cách AI diễn đạt câu trả lời.</p>
<select id="tone-style" class="w-full p-3.5 bg-white border border-slate-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition duration-200 text-sm">
<option value="Chuyên nghiệp & Chính xác (Professional)">Chuyên nghiệp & Chính xác</option>
<option value="Thân thiện & Dễ hiểu (Friendly)" selected>Thân thiện & Dễ hiểu</option>
<option value="Học thuật & Nghiêm túc (Academic)">Học thuật & Nghiêm túc</option>
<option value="Sáng tạo & Truyền cảm hứng (Creative)">Sáng tạo & Truyền cảm hứng</option>
<option value="Ngắn gọn & Súc tích (Concise)">Ngắn gọn & Súc tích</option>
<option value="Thuyết phục & Bán hàng (Persuasive)">Thuyết phục & Bán hàng</option>
</select>
</div>
</div>
<button id="create-prompt-btn" class="w-full bg-indigo-600 text-white font-bold py-3 px-6 rounded-lg hover:bg-indigo-700 focus:outline-none focus:ring-4 focus:ring-indigo-300 transition-all duration-300 transform hover:scale-105 shadow-md flex items-center justify-center gap-2">
<span id="btn-text">Tạo Prompt chi tiết</span>
<div id="btn-spinner" class="spinner hidden"></div>
</button>
</div>
<!-- Generated Prompt Section -->
<div id="prompt-output-container" class="mt-10 hidden">
<h2 class="text-2xl font-bold mb-2 text-slate-800">4. Tinh chỉnh Prompt của bạn</h2>
<p class="text-slate-500 mb-6">Cấu trúc prompt <span class="font-semibold text-indigo-600">9 thành phần</span> được AI đề xuất — bao gồm Tone, Few-shot Examples và Constraints. Chỉnh sửa từng phần để đạt kết quả tốt nhất.</p>
<div id="prompt-fields" class="space-y-6">
<!-- Role -->
<div class="prompt-field bg-white p-5 rounded-xl shadow-md border border-slate-200">
<label for="role-output" class="flex items-center text-lg font-semibold text-purple-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>
Role (Vai trò)
</label>
<p class="text-sm text-slate-500 mt-1 mb-2">Xác định vai trò hoặc chuyên môn bạn muốn AI đảm nhận.</p>
<textarea id="role-output" class="w-full h-24 p-3 bg-slate-50 border border-slate-300 rounded-md focus:ring-1 focus:ring-purple-500 focus:border-purple-500"></textarea>
</div>
<!-- Task -->
<div class="prompt-field bg-white p-5 rounded-xl shadow-md border border-slate-200">
<label for="task-output" class="flex items-center text-lg font-semibold text-sky-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" /></svg>
Task (Nhiệm vụ)
</label>
<p class="text-sm text-slate-500 mt-1 mb-2">Mô tả rõ ràng, cụ thể nhiệm vụ chính cần thực hiện.</p>
<textarea id="task-output" class="w-full h-24 p-3 bg-slate-50 border border-slate-300 rounded-md focus:ring-1 focus:ring-sky-500 focus:border-sky-500"></textarea>
</div>
<!-- Context -->
<div class="prompt-field bg-white p-5 rounded-xl shadow-md border border-slate-200">
<label for="context-output" class="flex items-center text-lg font-semibold text-emerald-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" /></svg>
Context (Bối cảnh)
</label>
<p class="text-sm text-slate-500 mt-1 mb-2">Cung cấp thông tin nền, các quy tắc, điều cần bao gồm hoặc loại trừ.</p>
<textarea id="context-output" class="w-full h-24 p-3 bg-slate-50 border border-slate-300 rounded-md focus:ring-1 focus:ring-emerald-500 focus:border-emerald-500"></textarea>
</div>
<!-- Reasoning -->
<div class="prompt-field bg-white p-5 rounded-xl shadow-md border border-slate-200">
<label for="reasoning-output" class="flex items-center text-lg font-semibold text-amber-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" /></svg>
Reasoning (Lập luận)
</label>
<p class="text-sm text-slate-500 mt-1 mb-2">Hướng dẫn AI cách suy nghĩ, ví dụ như "suy nghĩ từng bước một".</p>
<textarea id="reasoning-output" class="w-full h-24 p-3 bg-slate-50 border border-slate-300 rounded-md focus:ring-1 focus:ring-amber-500 focus:border-amber-500"></textarea>
</div>
<!-- Output Format -->
<div class="prompt-field bg-white p-5 rounded-xl shadow-md border border-slate-200">
<label for="format-output" class="flex items-center text-lg font-semibold text-rose-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" /></svg>
Output Format (Định dạng đầu ra)
</label>
<p class="text-sm text-slate-500 mt-1 mb-2">Chỉ định rõ định dạng bạn muốn nhận, ví dụ: JSON, Markdown, bảng...</p>
<textarea id="format-output" class="w-full h-24 p-3 bg-slate-50 border border-slate-300 rounded-md focus:ring-1 focus:ring-rose-500 focus:border-rose-500"></textarea>
</div>
<!-- Stop Condition -->
<div class="prompt-field bg-white p-5 rounded-xl shadow-md border border-slate-200">
<label for="stop-output" class="flex items-center text-lg font-semibold text-slate-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /><path stroke-linecap="round" stroke-linejoin="round" d="M9 10h.01M15 10h.01M9 14h6" /></svg>
Stop Condition (Điều kiện dừng)
</label>
<p class="text-sm text-slate-500 mt-1 mb-2">Mô tả khi nào nhiệm vụ được coi là hoàn thành.</p>
<textarea id="stop-output" class="w-full h-24 p-3 bg-slate-50 border border-slate-300 rounded-md focus:ring-1 focus:ring-slate-500 focus:border-slate-500"></textarea>
</div>
<!-- Tone & Style -->
<div class="prompt-field bg-white p-5 rounded-xl shadow-md border border-cyan-200">
<label for="tone-output" class="flex items-center text-lg font-semibold text-cyan-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z" /></svg>
Tone & Style (Phong cách diễn đạt)
</label>
<p class="text-sm text-slate-500 mt-1 mb-2">Hướng dẫn cụ thể về giọng văn, nhịp điệu và cách AI nên diễn đạt để phù hợp nhất với mục tiêu.</p>
<textarea id="tone-output" class="w-full h-24 p-3 bg-slate-50 border border-slate-300 rounded-md focus:ring-1 focus:ring-cyan-500 focus:border-cyan-500"></textarea>
</div>
<!-- Few-shot Examples -->
<div class="prompt-field bg-white p-5 rounded-xl shadow-md border border-violet-200">
<label for="examples-output" class="flex items-center text-lg font-semibold text-violet-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2" /></svg>
Few-shot Examples (Ví dụ mẫu)
</label>
<p class="text-sm text-slate-500 mt-1 mb-2">Cung cấp 1–3 cặp ví dụ Input→Output để AI học đúng format và phong cách mong muốn. Đây là kỹ thuật mạnh nhất để căn chỉnh output.</p>
<textarea id="examples-output" class="w-full h-32 p-3 bg-slate-50 border border-slate-300 rounded-md focus:ring-1 focus:ring-violet-500 focus:border-violet-500"></textarea>
</div>
<!-- Constraints -->
<div class="prompt-field bg-white p-5 rounded-xl shadow-md border border-orange-200">
<label for="constraints-output" class="flex items-center text-lg font-semibold text-orange-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" /></svg>
Constraints (Ràng buộc – Không được làm)
</label>
<p class="text-sm text-slate-500 mt-1 mb-2">Liệt kê rõ những gì AI KHÔNG được làm. Giúp tránh hallucination, đi lạc chủ đề, hoặc đưa ra thông tin không mong muốn.</p>
<textarea id="constraints-output" class="w-full h-24 p-3 bg-slate-50 border border-slate-300 rounded-md focus:ring-1 focus:ring-orange-500 focus:border-orange-500"></textarea>
</div>
</div>
<!-- Action Button -->
<div class="mt-8 text-center">
<button id="copy-prompt-btn" class="bg-emerald-500 text-white font-bold py-3 px-8 rounded-lg hover:bg-emerald-600 focus:outline-none focus:ring-4 focus:ring-emerald-300 transition-all duration-300 transform hover:scale-105 shadow-md">
Sao chép toàn bộ Prompt
</button>
</div>
</div>
</div>
<!-- Panel: Thư viện Prompt -->
<div id="panel-library" class="hidden">
<div class="mb-6">
<h2 class="text-2xl font-bold text-slate-800">Thư viện Prompt học tập & nghiên cứu</h2>
<p class="text-slate-500 mt-1">10 prompt đã được tối ưu, sẵn sàng dùng ngay. Nhấn "Xem & Sao chép" để lấy prompt.</p>
</div>
<div id="template-grid" class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- Cards được tạo động bằng JavaScript -->
</div>
</div>
</div>
<script>
// ============================================================
// DỮ LIỆU: 10 Prompt Templates
// ============================================================
const promptTemplates = [
{
id: 1,
title: "Học siêu tốc với kỹ thuật Feynman",
description: "Đừng để từ ngữ chuyên ngành làm chậm tốc độ tiếp thu của bạn.",
prompt: "Giải thích chủ đề này theo kỹ thuật Feynman dựa trên tài liệu tôi đã tải lên: 1) Giải thích đơn giản (không dùng biệt ngữ). 2) Chỉ ra những lỗ hổng hoặc điểm dễ gây nhầm lẫn trong tài liệu. 3) Viết lại lời giải thích cho rõ ràng hơn. 4) Đưa ra một ví dụ thực tế, dễ liên tưởng để tôi nắm chắc khái niệm.",
icon: "🧠",
accent: "purple",
badgeBg: "bg-purple-100",
badgeText: "text-purple-700",
borderColor: "border-purple-200",
iconBg: "bg-purple-50",
},
{
id: 2,
title: "Làm chủ mọi chương sách / tài liệu",
description: "Dành cho những lúc cần nắm bắt bức tranh lớn trước khi đi vào tiểu tiết.",
prompt: "Biến tài liệu này thành một bản hướng dẫn tổng quát:\n• Tóm tắt cốt lõi trong 2-3 câu.\n• Mục tiêu cần đạt được.\n• Dàn ý: Chủ đề chính → Chủ đề phụ → Chi tiết.\n• Các framework/công thức chính và lúc nào nên dùng.\n• 3 phần khó hiểu nhất và cách tiếp cận chúng dễ dàng hơn.",
icon: "📖",
accent: "sky",
badgeBg: "bg-sky-100",
badgeText: "text-sky-700",
borderColor: "border-sky-200",
iconBg: "bg-sky-50",
},
{
id: 3,
title: "Tóm tắt nghiên cứu (Chuẩn chuyên gia)",
description: "Phân tích tài liệu chuyên sâu theo chuẩn chuyên gia.",
prompt: "Phân tích [CHỦ ĐỀ] CHỈ sử dụng tài liệu tôi đã cung cấp. Yêu cầu bao gồm:\n• Các case study lịch sử + ứng dụng thực tiễn hiện đại.\n• Phương pháp luận và cách thu thập dẫn chứng.\n• Các quan điểm chính của tác giả/chuyên gia.\n• Tóm tắt kết luận và những hành động thực tế có thể áp dụng ngay (actionable takeaways).",
icon: "🔬",
accent: "emerald",
badgeBg: "bg-emerald-100",
badgeText: "text-emerald-700",
borderColor: "border-emerald-200",
iconBg: "bg-emerald-50",
},
{
id: 4,
title: "Lập ma trận ra quyết định",
description: "Để đưa ra quyết định dựa trên dữ liệu, không phải cảm tính.",
prompt: "Tạo một ma trận ra quyết định từ tài liệu để chọn giữa Lựa chọn A và Lựa chọn B (thêm C nếu có). Bao gồm:\n• Tiêu chí đánh giá.\n• Trọng số của từng tiêu chí.\n• Sự đánh đổi và rủi ro của mỗi lựa chọn.\n• Lời khuyên chốt hạ kèm theo mức độ tin cậy dựa trên nguồn tài liệu.",
icon: "⚖️",
accent: "amber",
badgeBg: "bg-amber-100",
badgeText: "text-amber-700",
borderColor: "border-amber-200",
iconBg: "bg-amber-50",
},
{
id: 5,
title: "Lọc \"Vàng\" (High-Signal Data)",
description: "Chỉ tập trung vào những thứ tạo ra kết quả.",
prompt: "Trích xuất những điểm cốt lõi và có giá trị thực tiễn cao nhất từ tài liệu. Quy tắc:\n• Bỏ qua mọi thông tin rườm rà, sáo rỗng.\n• Ưu tiên những insight có khả năng thay đổi quyết định hoặc mang lại tư duy mới.\n• Thêm một dòng \"Tại sao điều này quan trọng\" cho mỗi điểm được trích xuất.",
icon: "💎",
accent: "rose",
badgeBg: "bg-rose-100",
badgeText: "text-rose-700",
borderColor: "border-rose-200",
iconBg: "bg-rose-50",
},
{
id: 6,
title: "Truy tìm điểm mâu thuẫn giữa các nguồn",
description: "Xác định và phân tích các điểm bất đồng trong tài liệu.",
prompt: "Xác định những điểm mâu thuẫn, bất đồng trong các tài liệu tôi đã tải lên. Với mỗi điểm xung đột, hãy làm rõ:\n• Ai nói gì (trích dẫn nguồn cụ thể).\n• Giả định cốt lõi nào dẫn đến sự khác biệt đó.\n• Cách dung hòa các góc nhìn này (hoặc giải thích lý do không thể).\n• Cần thêm dữ liệu gì để giải quyết triệt để mâu thuẫn này.",
icon: "🔍",
accent: "slate",
badgeBg: "bg-slate-100",
badgeText: "text-slate-700",
borderColor: "border-slate-200",
iconBg: "bg-slate-50",
},
{
id: 7,
title: "Outline đa nền tảng cho Content Creator",
description: "Tuyệt chiêu tái chế nội dung (Repurpose Content) cho anh em agency, truyền thông.",
prompt: "Sử dụng tài liệu của tôi để tạo các kịch bản nội dung sau: 1) Outline chi tiết cho bài Blog. 2) Outline kịch bản YouTube. 3) Chuỗi 10 bài post ngắn cho mạng xã hội. Mỗi định dạng phải có trích dẫn cụ thể từ văn bản gốc và một phần \"dẫn chứng\" riêng để củng cố các luận điểm.",
icon: "📣",
accent: "indigo",
badgeBg: "bg-indigo-100",
badgeText: "text-indigo-700",
borderColor: "border-indigo-200",
iconBg: "bg-indigo-50",
},
{
id: 8,
title: "Tạo câu hỏi ôn tập (Active Recall)",
description: "Bộ câu hỏi đa dạng giúp củng cố kiến thức hiệu quả.",
prompt: "Tạo 25 câu hỏi thực hành từ tài liệu:\n• 10 câu gợi nhớ cơ bản.\n• 10 câu vận dụng thực tiễn.\n• 5 câu tổng hợp kiến thức.\nCung cấp đáp án có trích dẫn và giải thích cặn kẽ tại sao các đáp án sai lại sai.",
icon: "✏️",
accent: "orange",
badgeBg: "bg-orange-100",
badgeText: "text-orange-700",
borderColor: "border-orange-200",
iconBg: "bg-orange-50",
},
{
id: 9,
title: "Phác thảo Infographic trực quan",
description: "Lên kế hoạch thiết kế infographic cô đọng từ tài liệu.",
prompt: "Lên kế hoạch thiết kế một infographic cô đọng từ tài liệu. Yêu cầu:\n• Phân cấp thông tin rõ ràng.\n• Không thêm chi tiết trang trí vô nghĩa.\n• Củng cố ý tưởng bằng cả hình ảnh và câu chữ.\nOutput cần có: Tiêu đề, các phần chính, gợi ý icon/biểu đồ, và đoạn text ngắn gọn để đưa vào thiết kế. Nhớ trích nguồn cho từng phần.",
icon: "🎨",
accent: "teal",
badgeBg: "bg-teal-100",
badgeText: "text-teal-700",
borderColor: "border-teal-200",
iconBg: "bg-teal-50",
},
{
id: 10,
title: "Bản đồ Luận điểm – Dẫn chứng",
description: "Xây dựng bản đồ luận điểm chi tiết với dẫn chứng minh bạch (Nghiên cứu sâu).",
prompt: "Xây dựng một Bản đồ Luận điểm - Dẫn chứng dưới dạng bảng với các cột: Luận điểm | Trích dẫn hỗ trợ/Diễn giải | Nguồn + Vị trí | Độ mạnh của dẫn chứng (Thấp/Trung bình/Cao) | Giả định | Bằng chứng phản bác. Yêu cầu: Chỉ sử dụng tài liệu của tôi và trích dẫn minh bạch cho từng hàng.",
icon: "🗺️",
accent: "red",
badgeBg: "bg-red-100",
badgeText: "text-red-700",
borderColor: "border-red-200",
iconBg: "bg-red-50",
},
];
// ============================================================
// RENDER: Template Cards
// ============================================================
function renderTemplateCards() {
const grid = document.getElementById('template-grid');
grid.innerHTML = promptTemplates.map(t => `
<div class="template-card bg-white rounded-xl border ${t.borderColor} shadow-sm overflow-hidden flex flex-col">
<div class="p-5 flex-1">
<div class="flex items-start gap-3 mb-3">
<div class="${t.iconBg} ${t.borderColor} border rounded-lg w-10 h-10 flex items-center justify-center text-xl flex-shrink-0">
${t.icon}
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-0.5">
<span class="text-xs font-semibold px-2 py-0.5 rounded-full ${t.badgeBg} ${t.badgeText}">#${t.id}</span>
</div>
<h3 class="font-bold text-slate-800 text-sm leading-snug">${t.title}</h3>
</div>
</div>
<p class="text-xs text-slate-500 mb-3 leading-relaxed">${t.description}</p>
<!-- Prompt Preview (collapsible) -->
<div id="preview-${t.id}" class="prompt-preview">
<div class="bg-slate-50 border border-slate-200 rounded-lg p-3 mt-2">
<p class="text-xs text-slate-600 leading-relaxed whitespace-pre-wrap font-mono">${escapeHtml(t.prompt)}</p>
</div>
</div>
</div>
<!-- Actions -->
<div class="px-5 pb-4 pt-2 flex items-center gap-2 border-t border-slate-100">
<button onclick="togglePreview(${t.id})" id="toggle-btn-${t.id}"
class="flex-1 text-xs font-semibold py-2 px-3 rounded-lg border border-slate-300 text-slate-600 hover:bg-slate-50 transition-colors duration-200">
Xem Prompt
</button>
<button onclick="copyTemplate(${t.id})" id="copy-btn-${t.id}"
class="flex-1 text-xs font-bold py-2 px-3 rounded-lg ${t.badgeBg} ${t.badgeText} hover:opacity-80 transition-opacity duration-200">
Sao chép
</button>
</div>
</div>
`).join('');
}
function escapeHtml(text) {
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
}
function togglePreview(id) {
const preview = document.getElementById(`preview-${id}`);
const btn = document.getElementById(`toggle-btn-${id}`);
const isExpanded = preview.classList.contains('expanded');
preview.classList.toggle('expanded', !isExpanded);
btn.textContent = isExpanded ? 'Xem Prompt' : 'Ẩn Prompt';
}
function copyTemplate(id) {
const template = promptTemplates.find(t => t.id === id);
if (!template) return;
const btn = document.getElementById(`copy-btn-${id}`);
const originalText = btn.textContent;
const textarea = document.createElement('textarea');
textarea.value = template.prompt;
textarea.style.position = 'fixed';
textarea.style.top = '-9999px';
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
try {
document.execCommand('copy');
btn.textContent = '✓ Đã sao chép!';
setTimeout(() => { btn.textContent = originalText; }, 2000);
} catch (err) {
alert('Không thể sao chép. Vui lòng sao chép thủ công.');
}
document.body.removeChild(textarea);
}
// ============================================================
// TAB SWITCHING
// ============================================================
const tabCreateBtn = document.getElementById('tab-create-btn');
const tabLibraryBtn = document.getElementById('tab-library-btn');
const panelCreate = document.getElementById('panel-create');
const panelLibrary = document.getElementById('panel-library');
tabCreateBtn.addEventListener('click', () => {
tabCreateBtn.classList.add('active');
tabLibraryBtn.classList.remove('active');
panelCreate.classList.remove('hidden');
panelLibrary.classList.add('hidden');
});
tabLibraryBtn.addEventListener('click', () => {
tabLibraryBtn.classList.add('active');
tabCreateBtn.classList.remove('active');
panelLibrary.classList.remove('hidden');
panelCreate.classList.add('hidden');
});
// ============================================================
// GEMINI API – Tạo Prompt tùy chỉnh
// ============================================================
const createPromptBtn = document.getElementById('create-prompt-btn');
const btnText = document.getElementById('btn-text');
const btnSpinner = document.getElementById('btn-spinner');
const rawInput = document.getElementById('raw-input');
const userLevelSelect = document.getElementById('user-level');
const toneStyleSelect = document.getElementById('tone-style');
const promptOutputContainer = document.getElementById('prompt-output-container');
const roleOutput = document.getElementById('role-output');
const taskOutput = document.getElementById('task-output');
const contextOutput = document.getElementById('context-output');
const reasoningOutput = document.getElementById('reasoning-output');
const formatOutput = document.getElementById('format-output');
const stopOutput = document.getElementById('stop-output');
const toneOutput = document.getElementById('tone-output');
const examplesOutput = document.getElementById('examples-output');
const constraintsOutput = document.getElementById('constraints-output');
const copyPromptBtn = document.getElementById('copy-prompt-btn');
async function generatePromptStructure(userInput, userLevel, toneStyle) {
btnText.textContent = 'AI đang phân tích...';
btnSpinner.classList.remove('hidden');
createPromptBtn.disabled = true;
const apiKey = "";
const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`;
const instruction = `Bạn là một chuyên gia Prompt Engineering. Dựa trên yêu cầu: "${userInput}", đối tượng mục tiêu: "${userLevel}", và phong cách giọng văn: "${toneStyle}", hãy tạo ra một cấu trúc prompt 9 thành phần hoàn chỉnh, tối ưu để khai thác AI hiệu quả nhất.
Yêu cầu từng thành phần:
- role: Xác định lĩnh vực và gán vai trò chuyên gia cấp cao phù hợp. Viết ở dạng "Bạn là [vai trò], với [X] năm kinh nghiệm về [lĩnh vực]...".
- task: Mô tả nhiệm vụ cụ thể, rõ ràng, có thể đo lường được. Dùng động từ hành động.
- context: Cung cấp bối cảnh đầy đủ, các quy tắc, thông tin nền cần thiết.
- reasoning: Hướng dẫn AI suy nghĩ từng bước (Chain-of-Thought). Bao gồm yêu cầu tự kiểm tra lại câu trả lời trước khi output.
- output_format: Định dạng chi tiết: cấu trúc, độ dài, ngôn ngữ, markdown...
- stop_condition: Điều kiện hoàn thành rõ ràng.
- tone_style: Hướng dẫn chi tiết về giọng văn "${toneStyle}" — nhịp điệu câu, từ ngữ nên/không nên dùng, mức độ chuyên môn trong diễn đạt. Phù hợp với đối tượng "${userLevel}".
- few_shot_examples: Tạo 2 cặp ví dụ Input→Output ngắn gọn, minh họa đúng format và phong cách output mong muốn. Đây là kỹ thuật few-shot learning.
- constraints: Liệt kê 4-6 điều AI tuyệt đối KHÔNG được làm: không bịa đặt dữ liệu, không mở rộng phạm vi ngoài yêu cầu, không dùng ngôn ngữ mơ hồ... Phù hợp với ngữ cảnh cụ thể của yêu cầu này.`;
const schema = {
type: "OBJECT",
properties: {
role: { type: "STRING" },
task: { type: "STRING" },
context: { type: "STRING" },
reasoning: { type: "STRING" },
output_format: { type: "STRING" },
stop_condition: { type: "STRING" },
tone_style: { type: "STRING" },
few_shot_examples: { type: "STRING" },
constraints: { type: "STRING" },
},
required: ["role", "task", "context", "reasoning", "output_format", "stop_condition", "tone_style", "few_shot_examples", "constraints"],
};
const payload = {
contents: [{ parts: [{ text: instruction }] }],
generationConfig: {
responseMimeType: "application/json",
responseSchema: schema,
},
};
try {
const response = await fetch(apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(`API call failed with status: ${response.status}`);
}
const result = await response.json();
const generatedText = result.candidates[0].content.parts[0].text;
return JSON.parse(generatedText);
} catch (error) {
console.error("Lỗi khi gọi Gemini API:", error);
alert("Rất tiếc, đã có lỗi xảy ra khi kết nối với AI. Vui lòng thử lại sau.");
return null;
} finally {
btnText.textContent = 'Tạo Prompt chi tiết';
btnSpinner.classList.add('hidden');
createPromptBtn.disabled = false;
}
}
createPromptBtn.addEventListener('click', async () => {
const userInput = rawInput.value.trim();
const userLevel = userLevelSelect.value;
const toneStyle = toneStyleSelect.value;
if (userInput === '') {
alert('Vui lòng nhập yêu cầu ban đầu của bạn.');
return;
}
const promptData = await generatePromptStructure(userInput, userLevel, toneStyle);
if (promptData) {
roleOutput.value = promptData.role || '';
taskOutput.value = promptData.task || '';
contextOutput.value = promptData.context || '';
reasoningOutput.value = promptData.reasoning || '';
formatOutput.value = promptData.output_format || '';
stopOutput.value = promptData.stop_condition || '';
toneOutput.value = promptData.tone_style || '';
examplesOutput.value = promptData.few_shot_examples || '';
constraintsOutput.value = promptData.constraints || '';
promptOutputContainer.classList.remove('hidden');
promptOutputContainer.classList.add('fade-in');
promptOutputContainer.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
copyPromptBtn.addEventListener('click', () => {
const allPromptText = `## ROLE\n${roleOutput.value}\n\n` +
`## TASK\n${taskOutput.value}\n\n` +
`## CONTEXT\n${contextOutput.value}\n\n` +
`## REASONING\n${reasoningOutput.value}\n\n` +
`## OUTPUT FORMAT\n${formatOutput.value}\n\n` +
`## STOP CONDITION\n${stopOutput.value}\n\n` +
`## TONE & STYLE\n${toneOutput.value}\n\n` +
`## FEW-SHOT EXAMPLES\n${examplesOutput.value}\n\n` +
`## CONSTRAINTS (KHÔNG ĐƯỢC LÀM)\n${constraintsOutput.value}`;
const textArea = document.createElement("textarea");
textArea.value = allPromptText;
textArea.style.position = "fixed";
textArea.style.top = "-9999px";
textArea.style.left = "-9999px";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
const successful = document.execCommand('copy');
if (successful) {
const originalText = copyPromptBtn.textContent;
copyPromptBtn.textContent = 'Đã sao chép!';
copyPromptBtn.classList.remove('bg-emerald-500', 'hover:bg-emerald-600');
copyPromptBtn.classList.add('bg-green-600');
setTimeout(() => {
copyPromptBtn.textContent = originalText;
copyPromptBtn.classList.remove('bg-green-600');
copyPromptBtn.classList.add('bg-emerald-500', 'hover:bg-emerald-600');
}, 2000);
} else {
alert('Rất tiếc, không thể sao chép.');
}
} catch (err) {
console.error('Lỗi sao chép: ', err);
alert('Rất tiếc, đã có lỗi xảy ra khi sao chép.');
}
document.body.removeChild(textArea);
});
// ============================================================
// KHỞI TẠO
// ============================================================
renderTemplateCards();
</script>
</body>
</html>