Update prompt-builder.html
· 1 year ago
88f1ee424f33c60a7b2e89ba9178ea2ca6b7c8a4
Parent:
5bb32135e
1 file changed +221 −52
- prompt-builder.html +221 −52
Diff
--- a/prompt-builder.html +++ b/prompt-builder.html @@ -3,17 +3,64 @@ <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>System Prompt Builder & Guide</title> + <title>System Prompt Builder & Engineering Guide</title> + + <!-- SEO and Core Metadata --> + <meta + name="description" + content="An interactive tool to build and engineer effective system prompts for Large Language Models (LLMs), complete with a comprehensive prompting guide and useful templates." + /> + <meta + name="keywords" + content="system prompt, prompt engineering, LLM, AI, prompt builder, prompt guide, generative AI, large language models, AI assistant, prompt templates, AI tools" + /> + <meta name="author" content="David Vekslers Cheatsheets" /> <link rel="canonical" href="http://cheatsheets.davidveksler.com/prompt-builder.html" /> + + <!-- Favicons --> + <link rel="icon" href="./assets/favicon.ico" sizes="any" /> + <link rel="icon" href="./assets/favicon.svg" type="image/svg+xml" /> + <link rel="apple-touch-icon" href="./assets/apple-touch-icon.png" /> <!-- 180x180 ideally --> + <!-- User-requested custom meta tag with role="icon" --> + <!-- Note: This is a non-standard way to declare an icon. Standard methods are above. --> + <meta name="application-icon" content="./assets/favicon.svg" role="icon" /> + + <!-- Open Graph / Facebook Meta Tags --> + <meta property="og:title" content="System Prompt Builder & Engineering Guide" /> + <meta + property="og:description" + content="Build effective system prompts for LLMs and learn prompt engineering techniques with this interactive tool and guide." + /> + <meta property="og:type" content="website" /> + <meta property="og:url" content="http://cheatsheets.davidveksler.com/prompt-builder.html" /> + <meta property="og:image" content="http://cheatsheets.davidveksler.com/assets/prompt-builder-og-image.png" /> <!-- Ideal: 1200x630px --> + <meta property="og:image:alt" content="Screenshot of the System Prompt Builder & Guide Tool Interface" /> + <meta property="og:site_name" content="David Vekslers Cheatsheets" /> + + <!-- Twitter Card Meta Tags --> + <meta name="twitter:card" content="summary_large_image" /> + <meta name="twitter:title" content="System Prompt Builder & Engineering Guide" /> + <meta + name="twitter:description" + content="Build effective system prompts for LLMs and learn prompt engineering techniques with this interactive tool and guide." + /> + <meta name="twitter:image" content="http://cheatsheets.davidveksler.com/assets/prompt-builder-og-image.png" /> <!-- Same as OG Image --> + <meta name="twitter:image:alt" content="Screenshot of the System Prompt Builder & Guide Tool Interface" /> + <!-- <meta name="twitter:creator" content="@YourTwitterHandle"> --> <!-- Optional: Twitter username --> + + <!-- Stylesheets --> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css" /> <style> body { padding-top: 20px; - background-color: #f8f9fa; + background-color: #f8f9fa; /* Light gray background */ + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", + "Segoe UI Symbol"; /* Modern system font stack */ } .container-main { - max-width: 960px; /* Slightly wider for guide content */ + max-width: 980px; /* Slightly wider for better content flow */ } .form-check-input[type="checkbox"] { cursor: pointer; @@ -29,57 +76,147 @@ z-index: 10; } .advisor-panel { - background-color: #eef7ff; - border-left: 5px solid #0d6efd; + background-color: #eef7ff; /* Light blue */ + border-left: 5px solid #0d6efd; /* Primary blue */ padding: 15px; margin-bottom: 20px; font-size: 0.9em; + border-radius: 0.375rem; /* Added subtle rounding */ } .advisor-panel ul { padding-left: 20px; margin-bottom: 0; } - .tab-content { - border: 1px solid #dee2e6; - border-top: none; - padding: 20px; - background-color: #fff; - } .nav-tabs .nav-link { - color: #0d6efd; + color: #0d6efd; /* Primary blue for inactive tabs */ + font-weight: 500; /* Slightly bolder tab text */ } .nav-tabs .nav-link.active { - color: #495057; - background-color: #fff; + color: #495057; /* Dark gray for active tab text */ + background-color: #fff; /* White background for active tab */ border-color: #dee2e6 #dee2e6 #fff; } + .tab-content { + border: 1px solid #dee2e6; /* Standard Bootstrap border color */ + border-top: none; + padding: 25px; /* Increased padding for better spacing */ + background-color: #fff; /* White background for tab content */ + box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.05); /* Subtle shadow for depth */ + border-bottom-left-radius: 0.375rem; /* Rounded bottom corners */ + border-bottom-right-radius: 0.375rem; /* Rounded bottom corners */ + } .guide-section h4 { - margin-top: 1.5rem; + margin-top: 1.75rem; /* Increased top margin */ margin-bottom: 0.75rem; - color: #0d6efd; + color: #0d6efd; /* Primary blue */ + border-bottom: 1px solid #e9ecef; /* Subtle separator */ + padding-bottom: 0.5rem; /* Space below text, above border */ } .guide-section h5 { - margin-top: 1rem; + margin-top: 1.25rem; /* Increased top margin */ margin-bottom: 0.5rem; - color: #198754; + color: #198754; /* Success green */ } .guide-section p, .guide-section li { font-size: 0.95rem; - line-height: 1.6; + line-height: 1.65; /* Slightly more line height */ } .guide-section code { background-color: #e9ecef; padding: 0.2em 0.4em; border-radius: 3px; font-size: 0.9em; + color: #d63384; /* Bootstrap pink for code */ + } + .guide-section pre > code { /* For multi-line code blocks in guide */ + display: block; + padding: 1rem; + white-space: pre-wrap; + word-break: break-all; + } + + /* Visual Appeal Enhancements */ + .header-title-area { + padding-bottom: 1.5rem; + border-bottom: 1px solid #dee2e6; /* Separator line */ + margin-bottom: 1.5rem !important; + } + .header-title-area h1 { + font-size: 2.2rem; /* Adjusted title size */ + color: #343a40; /* Darker color for title */ + font-weight: 600; + } + .header-title-area h1 .bi { + color: #0d6efd; /* Icon color match primary */ + margin-right: 0.6rem; /* Space between icon and text */ + vertical-align: -0.1em; /* Align icon better with text */ + } + + .accordion-button { + font-weight: 500; + } + .accordion-button:not(.collapsed) { + background-color: #e7f1ff; /* Lighter blue when open */ + color: #0a58ca; /* Darker blue text for open accordion */ + } + .accordion-button:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); /* Bootstrap focus ring */ + } + .accordion-item { + margin-bottom: 0.75rem; /* Spacing between accordion items */ + border: 1px solid #dee2e6; + border-radius: 0.375rem !important; /* Rounded accordion items */ + overflow: hidden; /* To make border-radius work with accordion buttons */ + } + .accordion-item:first-of-type { + border-top-left-radius: 0.375rem !important; + border-top-right-radius: 0.375rem !important; + } + .accordion-item:last-of-type { + border-bottom-left-radius: 0.375rem !important; + border-bottom-right-radius: 0.375rem !important; + } + + #generatedPromptOutput { + background-color: #f1f3f5; /* Slightly different bg from tab content, less stark than f8f9fa */ + border-radius: 0.25rem; + font-family: 'SFMono-Regular', Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* Monospace font */ + font-size: 0.9em; + line-height: 1.5; + } + + .config-buttons-wrapper { + display: flex; + justify-content: flex-start; /* Default for mobile */ + gap: 0.5rem; + } + @media (min-width: 768px) { /* md breakpoint */ + .config-buttons-wrapper { + justify-content: flex-end; /* Align to end on medium and larger screens */ + } + } + + footer.text-center { + padding-top: 2rem; + padding-bottom: 1rem; + border-top: 1px solid #e0e0e0; + color: #6c757d; /* Muted text color */ + font-size: 0.9rem; + } + footer.text-center a { + color: #0d6efd; /* Primary blue for links */ + text-decoration: none; + } + footer.text-center a:hover { + text-decoration: underline; } </style> </head> <body> <div class="container container-main"> - <div class="text-center mb-4"> - <h1><i class="bi bi-journal-richtext"></i> System Prompt Builder & Engineering Guide</h1> + <div class="text-center header-title-area"> <!-- mb-4 removed, handled by new class --> + <h1><i class="bi bi-journal-richtext"></i>System Prompt Builder & Engineering Guide</h1> </div> <!-- Tabs Navigation --> @@ -138,14 +275,16 @@ <option value="reset">Start Fresh / Clear Form</option> </select> </div> - <div class="col-md-6 text-md-end"> - <button class="btn btn-sm btn-outline-secondary me-2 mt-2 mt-md-0" id="exportConfig"> - <i class="bi bi-download"></i> Export - </button> - <input type="file" id="importConfigFile" accept=".json" style="display: none" /> - <button class="btn btn-sm btn-outline-secondary mt-2 mt-md-0" id="importConfigTrigger"> - <i class="bi bi-upload"></i> Import - </button> + <div class="col-md-6"> <!-- text-md-end removed --> + <div class="config-buttons-wrapper mt-2 mt-md-0"> + <button class="btn btn-sm btn-outline-secondary" id="exportConfig"> + <i class="bi bi-download"></i> Export + </button> + <input type="file" id="importConfigFile" accept=".json" style="display: none" /> + <button class="btn btn-sm btn-outline-secondary" id="importConfigTrigger"> + <i class="bi bi-upload"></i> Import + </button> + </div> </div> </div> @@ -502,7 +641,7 @@ <button type="button" class="btn btn-sm btn-outline-primary mt-2" id="addExampleButton"> <i class="bi bi-plus-circle"></i> Add Example </button> - <small class="form-text text-muted d-block">Provide 1-3 clear input/output pairs.</small> + <small class="form-text text-muted d-block mt-1">Provide 1-3 clear input/output pairs.</small> </div> </div> </div> @@ -519,7 +658,7 @@ <button id="copyPromptButton" class="btn btn-sm btn-outline-secondary" title="Copy to Clipboard"> <i class="bi bi-clipboard"></i> Copy </button> - <pre><code id="generatedPromptOutput" class="p-3 border bg-light d-block" style="min-height: 200px; white-space: pre-wrap; word-wrap: break-word;">Your generated prompt will appear here...</code></pre> + <pre><code id="generatedPromptOutput" class="p-3 border d-block" style="min-height: 200px; white-space: pre-wrap; word-wrap: break-word;">Your generated prompt will appear here...</code></pre> </div> </div> <!-- End Builder Tab Pane --> @@ -648,16 +787,16 @@ AI: Roger started with 5 balls. He bought 2 cans, and each can has 3 balls. So, <h5>B. Structuring Prompts with Delimiters/Tags</h5> <p> Use clear separators (e.g., triple quotes <code>"""</code>, XML tags - <code><instruction>...</instruction></code + <code><instruction>...</instruction></code >, Markdown headings <code>## Input Data</code>) to distinguish instructions, context, examples, and input data. This helps the AI parse the prompt effectively. </p> <p>Anthropic's Claude models, for instance, are specifically trained to pay attention to XML tags.</p> - <pre><code><role>You are a helpful assistant.</role> -<user_query> + <pre><code><role>You are a helpful assistant.</role> +<user_query> What's the capital of France? -</user_query> -<instructions>Respond concisely.</instructions></code></pre> +</user_query> +<instructions>Respond concisely.</instructions></code></pre> <h5>C. Breaking Down Complex Tasks (Prompt Chaining)</h5> <p> @@ -683,7 +822,7 @@ What's the capital of France? <p> For complex reasoning, instruct the model to "think out loud" or use a scratchpad area (which you might instruct it to exclude from the final output). Some models benefit from being told to put intermediate - thoughts in specific tags (e.g., <code><thinking>...</thinking></code + thoughts in specific tags (e.g., <code><thinking>...</thinking></code >). </p> @@ -732,13 +871,15 @@ What's the capital of France? </div> <!-- End Tab Content --> - <footer class="text-center mt-5 mb-3"> - <small class="text-muted" + <footer class="text-center mt-5 mb-3"> <!-- Original classes preserved --> + <small >Canonical URL: <a href="http://cheatsheets.davidveksler.com/prompt-builder.html" >cheatsheets.davidveksler.com/prompt-builder.html</a ></small > + <br/> + <small>Ensure you have `favicon.ico`, `favicon.svg`, `apple-touch-icon.png`, and `prompt-builder-og-image.png` in an `./assets/` folder relative to this HTML file for all icons and images to work.</small> </footer> </div> <!-- End Container --> @@ -1031,9 +1172,17 @@ What's the capital of France? if (accordionButton) { accordionButton.addEventListener("click", function () { + // Bootstrap's collapse event might be more reliable, but setTimeout is simpler here setTimeout(() => { + const isCollapsed = !contentArea.classList.contains('show'); + if (isCollapsed && toggle.checked) { // If it was open due to checkbox but button collapses it + // This logic might need refinement if accordion state and checkbox state desync + } else if (!isCollapsed && !toggle.checked) { // If checkbox is off but accordion opens + // This scenario might need attention too. + } + // For now, primarily driven by checkbox setInputsDisabledState(!toggle.checked); - }, 0); + }, 350); // Allow time for collapse animation }); } }); @@ -1045,8 +1194,8 @@ What's the capital of France? } const exampleId = Date.now(); const exampleDiv = document.createElement("div"); - exampleDiv.classList.add("example-pair", "mb-3", "p-2", "border", "rounded"); - exampleDiv.innerHTML = `<h6>Example Pair</h6><textarea class="form-control form-control-sm example-input" rows="2" placeholder="User: ...">${initialInput}</textarea><textarea class="form-control form-control-sm example-output mt-1" rows="3" placeholder="AI: ...">${initialOutput}</textarea><button type="button" class="btn btn-sm btn-outline-danger mt-1 remove-example" data-example-id="${exampleId}"><i class="bi bi-trash"></i> Remove</button>`; + exampleDiv.classList.add("example-pair", "mb-3", "p-2", "border", "rounded", "bg-light"); // Added bg-light for slight differentiation + exampleDiv.innerHTML = `<h6 class="small text-muted">Example Pair</h6><textarea class="form-control form-control-sm example-input" rows="2" placeholder="User: ...">${initialInput}</textarea><textarea class="form-control form-control-sm example-output mt-1" rows="3" placeholder="AI: ...">${initialOutput}</textarea><button type="button" class="btn btn-sm btn-outline-danger mt-2 remove-example" data-example-id="${exampleId}"><i class="bi bi-trash"></i> Remove</button>`; DOMElements.examplesContainer.appendChild(exampleDiv); exampleDiv.querySelector(".remove-example").addEventListener("click", function () { this.parentElement.remove(); @@ -1072,7 +1221,7 @@ What's the capital of France? } else if (sectionId === "keytasks" && getFieldValue("aiTasks")) { prompt += `## Key Tasks & Functions\n${getFieldValue("aiTasks").trim()}\n\n`; } else if (sectionId === "interactionstyle") { - if (getFieldValue("aiTone") !== "Neutral") + if (getFieldValue("aiTone") !== "Neutral") // Only add if not default neutral sectionContent += `Your tone should be: ${getFieldValue("aiTone")}.\n`; if (getFieldValue("aiCommunicationStyle")) sectionContent += `${getFieldValue("aiCommunicationStyle")}\n`; if (sectionContent) prompt += `## Interaction Style & Tone\n${sectionContent.trim()}\n\n`; @@ -1101,19 +1250,19 @@ What's the capital of France? } else if (sectionId === "reasoning") { if (getFieldValue("useCoT")) sectionContent += `Employ step-by-step reasoning. ${ - getFieldValue("cotPhrase") ? getFieldValue("cotPhrase") + "\n" : "\n" + getFieldValue("cotPhrase") ? getFieldValue("cotPhrase").trim() + "\n" : "\n" }`; if (getFieldValue("useScratchpad")) sectionContent += `Use an internal scratchpad. ${ getFieldValue("scratchpadTags") - ? "Enclose thoughts in " + getFieldValue("scratchpadTags") + ".\n" + ? "Enclose thoughts in " + getFieldValue("scratchpadTags").trim() + ".\n" : "\n" }`; if (getFieldValue("selfCritique")) sectionContent += "Perform self-critique and refinement before finalizing.\n"; if (getFieldValue("consultKnowledge")) sectionContent += `Consult external knowledge if necessary. ${ - getFieldValue("knowledgeSourceHint") ? getFieldValue("knowledgeSourceHint") + "\n" : "\n" + getFieldValue("knowledgeSourceHint") ? getFieldValue("knowledgeSourceHint").trim() + "\n" : "\n" }`; if (sectionContent) prompt += `## Reasoning & Process\n${sectionContent.trim()}\n\n`; } else if (sectionId === "examples") { @@ -1129,7 +1278,7 @@ What's the capital of France? } ---\nUser: ${userInput}\nAI: ${aiOutput}\n--- End Example ${index + 1} ---\n\n`; } }); - if (examplesText.length > "Here are some examples of ideal interactions:\n\n".length) { + if (examplesText.length > "Here are some examples of ideal interactions:\n\n".length) { // Check if any actual examples were added prompt += `## Few-Shot Examples\n${examplesText.trim()}\n\n`; } } @@ -1157,7 +1306,12 @@ What's the capital of France? }) .catch((err) => console.error("Failed to copy: ", err)); } else { - alert("Nothing to copy yet. Generate a prompt first."); + // Provide feedback if nothing to copy + const originalText = DOMElements.copyPromptButton.innerHTML; + DOMElements.copyPromptButton.innerHTML = '<i class="bi bi-x-lg"></i> Nothing!'; + setTimeout(() => { + DOMElements.copyPromptButton.innerHTML = originalText; + }, 2000); } }); @@ -1195,6 +1349,8 @@ What's the capital of France? reader.onload = function (e) { try { const config = JSON.parse(e.target.result); + resetFormAndEnableAllSections(); // Clear form before loading + ALL_FIELD_IDS.forEach((id) => { if (config.hasOwnProperty(id)) setFieldValue(id, config[id]); }); @@ -1209,24 +1365,37 @@ What's the capital of France? DOMElements.addExampleButton.disabled = !toggle.checked; }); - if (DOMElements.examplesContainer) DOMElements.examplesContainer.innerHTML = ""; + if (DOMElements.examplesContainer) DOMElements.examplesContainer.innerHTML = ""; // Clear again to be sure if (config.examples && Array.isArray(config.examples)) { config.examples.forEach((ex) => addExamplePair(ex.input, ex.output)); } + // Ensure accordion sections reflect checkbox state visually if they were closed + document.querySelectorAll(".section-toggle").forEach(toggle => { + const collapseElement = document.getElementById(toggle.closest('.accordion-item').querySelector('.accordion-collapse').id); + const bsCollapse = bootstrap.Collapse.getInstance(collapseElement) || new bootstrap.Collapse(collapseElement, {toggle: false}); + if (toggle.checked) { + bsCollapse.show(); + } else { + bsCollapse.hide(); + } + }); + updateAdvisor(); + DOMElements.promptTemplate.value = ""; // Reset template dropdown alert("Configuration loaded successfully!"); } catch (err) { console.error("Error parsing/loading config:", err); - alert("Error loading config."); + alert("Error loading configuration file. Make sure it is a valid JSON export from this tool."); } }; reader.readAsText(file); - DOMElements.importConfigFile.value = ""; + DOMElements.importConfigFile.value = ""; // Reset file input } }); + // Initial call to set up advisor if needed updateAdvisor(); </script> </body> -</html> +</html> \ No newline at end of file