From 246f718630bb04eb1dcdc74c18ebda1a4b649f88 Mon Sep 17 00:00:00 2001 From: peptiderepo Date: Mon, 20 Apr 2026 00:54:57 +0700 Subject: [PATCH] Fix writing instructions not obeyed by LLM (v0.5.3) Writing instructions were framed as a weak "Additional instructions:" block at the end of the system prompt. Models prioritized competing format directives in each stage's user prompt and ignored the style guide. Now: system prompt wraps instructions as "MANDATORY STYLE GUIDE" with override language, every stage user prompt reinforces compliance, polish stage explicitly preserves lists and links, and chief editor revision preserves structural formatting. Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 18 +++++++ includes/core/class-chief-editor.php | 1 + includes/core/class-content-generator.php | 59 ++++++++--------------- prautoblogger.php | 4 +- 4 files changed, 42 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5708a19..dddb2c0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,24 @@ All notable changes to PRAutoBlogger will be documented in this file. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project uses [Semantic Versioning](https://semver.org/). +## [0.5.3] — 2026-04-20 + +### Fixed +- **Writing instructions not obeyed by LLM.** The user-configured writing + instructions (bullet points, hyperlinks, style rules) were appended to the + system prompt as a weak "Additional instructions:" afterthought. Models + prioritized competing format directives in the user prompts and ignored + the style guide. + - System prompt now frames writing instructions as a "MANDATORY STYLE GUIDE" + with explicit override language. + - Every stage's user prompt (outline, draft, single-pass) now includes a + reinforcement line: "Follow EVERY requirement from your system prompt + style guide." + - Polish stage explicitly preserves bullet points, numbered lists, and + hyperlinks instead of flattening them. + - Chief editor's revision rules now preserve structural formatting (lists, + links) from the original draft. + ## [0.5.2] — 2026-04-20 ### Added diff --git a/includes/core/class-chief-editor.php b/includes/core/class-chief-editor.php index d7c8d31..6c562a8 100755 --- a/includes/core/class-chief-editor.php +++ b/includes/core/class-chief-editor.php @@ -109,6 +109,7 @@ class PRAutoBlogger_Chief_Editor { $prompt .= "- REVISE if fixable issues exist — you MUST provide the full revised HTML\n"; $prompt .= "- REJECT only if the content is fundamentally flawed or off-topic\n"; $prompt .= "- When revising, fix the issues yourself. Don't just describe them.\n"; + $prompt .= "- When revising, PRESERVE all bullet points, numbered lists, hyperlinks, and structural formatting from the original. Do NOT flatten lists into prose or remove links.\n"; // Append user-defined editor instructions if configured. $instructions = trim( (string) get_option( 'prautoblogger_editor_instructions', '' ) ); diff --git a/includes/core/class-content-generator.php b/includes/core/class-content-generator.php index c60c9ab..62cab6c 100755 --- a/includes/core/class-content-generator.php +++ b/includes/core/class-content-generator.php @@ -96,13 +96,7 @@ class PRAutoBlogger_Content_Generator { return $response['content']; } - /** - * Multi-step generation: Outline → Draft → Polish. - * - * @param PRAutoBlogger_Content_Request $request - * - * @return string Generated HTML content. - */ + /** Multi-step generation: Outline → Draft → Polish. */ private function generate_multi_step( PRAutoBlogger_Content_Request $request ): string { $model = get_option( 'prautoblogger_writing_model', PRAUTOBLOGGER_DEFAULT_WRITING_MODEL ); @@ -118,14 +112,7 @@ class PRAutoBlogger_Content_Generator { return $polished; } - /** - * Multi-step stage 1: Generate an article outline. - * - * @param PRAutoBlogger_Content_Request $request - * @param string $model - * - * @return string The outline text. - */ + /** Multi-step stage 1: Generate an article outline. */ private function stage_outline( PRAutoBlogger_Content_Request $request, string $model ): string { $idea = $request->get_idea(); @@ -135,7 +122,8 @@ class PRAutoBlogger_Content_Generator { "Target keywords: %s\n\n" . "The outline should have 4-6 main sections with bullet points under each. " . "Include an introduction hook and a conclusion with a call to action. " . - "Word count target: %d-%d words.", + "Word count target: %d-%d words.\n\n" . + "Plan the structure to satisfy EVERY requirement in your system prompt style guide.", $idea->get_suggested_title(), $idea->get_topic(), $idea->get_article_type(), @@ -162,15 +150,7 @@ class PRAutoBlogger_Content_Generator { return $response['content']; } - /** - * Multi-step stage 2: Write the full draft from the outline. - * - * @param PRAutoBlogger_Content_Request $request - * @param string $outline - * @param string $model - * - * @return string Draft HTML content. - */ + /** Multi-step stage 2: Write the full draft from the outline. */ private function stage_draft( PRAutoBlogger_Content_Request $request, string $outline, string $model ): string { $prompt = sprintf( "Using this outline, write the full blog post in HTML format.\n\n" . @@ -182,7 +162,8 @@ class PRAutoBlogger_Content_Generator { "- Include an engaging introduction and strong conclusion\n" . "- Naturally incorporate these keywords: %s\n" . "- Do NOT include the title in the HTML (it will be set separately)\n" . - "- Do NOT wrap in , , or tags — just the article content", + "- Do NOT wrap in , , or tags — just the article content\n" . + "- Follow EVERY formatting and structural requirement from your system prompt style guide", $outline, $request->get_tone(), $request->get_min_word_count(), @@ -207,15 +188,7 @@ class PRAutoBlogger_Content_Generator { return $response['content']; } - /** - * Multi-step stage 3: Polish and refine the draft. - * - * @param PRAutoBlogger_Content_Request $request - * @param string $draft - * @param string $model - * - * @return string Polished HTML content. - */ + /** Multi-step stage 3: Polish and refine the draft. */ private function stage_polish( PRAutoBlogger_Content_Request $request, string $draft, string $model ): string { $prompt = "Review and polish this blog post draft. Improve:\n" . "1. Flow and readability\n" . @@ -223,6 +196,10 @@ class PRAutoBlogger_Content_Generator { "3. Engagement (hooks, transitions, call-to-action)\n" . "4. Accuracy and clarity\n" . "5. Remove any filler or redundant sentences\n\n" . + "IMPORTANT: Preserve all bullet points, numbered lists, hyperlinks, and " . + "structural elements from the draft. Do NOT flatten lists into prose or " . + "remove links. Ensure every requirement from your system prompt style " . + "guide is satisfied in the final output.\n\n" . "Return the polished HTML content only. Do not add commentary.\n\n" . "DRAFT:\n" . $draft; @@ -259,10 +236,15 @@ class PRAutoBlogger_Content_Generator { $prompt .= "Use a {$request->get_tone()} tone. "; $prompt .= "Output HTML content only — no markdown, no code fences, no commentary."; - // Append user-defined writing instructions if configured. + // Append user-defined writing instructions as a mandatory style guide. + // Framed prominently to ensure the model treats them as requirements, + // not optional suggestions — "Additional instructions" was too weak. $instructions = trim( $request->get_writing_instructions() ); if ( '' !== $instructions ) { - $prompt .= "\n\nAdditional instructions:\n" . $instructions; + $prompt .= "\n\n--- MANDATORY STYLE GUIDE ---\n"; + $prompt .= "You MUST follow every requirement below. These override any conflicting defaults:\n\n"; + $prompt .= $instructions; + $prompt .= "\n--- END STYLE GUIDE ---"; } return $prompt; @@ -287,7 +269,8 @@ class PRAutoBlogger_Content_Generator { "- Proper HTML (h2, h3, p, ul/li)\n" . "- Engaging intro, strong conclusion with CTA\n" . "- Do NOT include the title or / tags\n" . - "- Output HTML only, no markdown or commentary", + "- Output HTML only, no markdown or commentary\n" . + "- Follow EVERY formatting and structural requirement from your system prompt style guide", $idea->get_suggested_title(), $idea->get_topic(), $idea->get_article_type(), diff --git a/prautoblogger.php b/prautoblogger.php index 1116fb8..0d82547 100644 --- a/prautoblogger.php +++ b/prautoblogger.php @@ -8,7 +8,7 @@ declare(strict_types=1); * Plugin Name: PRAutoBlogger * Plugin URI: https://peptiderepo.com/prautoblogger * Description: Monitors social media for trending topics, generates SEO-friendly blog posts using AI, and publishes them on a daily schedule with full cost tracking and self-improvement metrics. - * Version: 0.5.2 + * Version: 0.5.3 * Requires at least: 6.0 * Requires PHP: 7.4 * Author: PeptideRepo @@ -35,7 +35,7 @@ if ( ! defined( 'ABSPATH' ) ) { | and limits without magic strings. */ -define( 'PRAUTOBLOGGER_VERSION', '0.5.2' ); +define( 'PRAUTOBLOGGER_VERSION', '0.5.3' ); define( 'PRAUTOBLOGGER_DB_VERSION', '1.1.0' ); define( 'PRAUTOBLOGGER_PLUGIN_FILE', __FILE__ ); define( 'PRAUTOBLOGGER_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );