<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: OmarMashal</title>
    <description>The latest articles on DEV Community by OmarMashal (@omarmashal).</description>
    <link>https://dev.to/omarmashal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3995876%2F5aa8e517-a6f7-4246-8ac0-d1896e5348a3.png</url>
      <title>DEV Community: OmarMashal</title>
      <link>https://dev.to/omarmashal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/omarmashal"/>
    <language>en</language>
    <item>
      <title>I edited a system prompt and had no way to prove it changed anything. So I built a measurement tool.</title>
      <dc:creator>OmarMashal</dc:creator>
      <pubDate>Wed, 24 Jun 2026 12:56:30 +0000</pubDate>
      <link>https://dev.to/omarmashal/i-edited-a-system-prompt-and-had-no-way-to-prove-it-changed-anything-so-i-built-a-measurement-tool-1d2n</link>
      <guid>https://dev.to/omarmashal/i-edited-a-system-prompt-and-had-no-way-to-prove-it-changed-anything-so-i-built-a-measurement-tool-1d2n</guid>
      <description>&lt;h1&gt;
  
  
  I edited a system prompt and had no way to prove it changed anything. So I built a measurement tool.
&lt;/h1&gt;

&lt;p&gt;A few months ago I was on a team project. The tech lead asked me to update a chatbot's system prompt to make the responses sound more formal. I made the change, ran the chatbot a few times, and realized I had no real way to verify it worked.&lt;/p&gt;

&lt;p&gt;I was making API calls manually, reading outputs side by side, and guessing.&lt;/p&gt;

&lt;p&gt;So I built the tool I wished I had.&lt;/p&gt;




&lt;h3&gt;
  
  
  The problem with the current options
&lt;/h3&gt;

&lt;p&gt;To compare two system prompts right now, your options are basically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run them manually and eyeball the outputs.&lt;/strong&gt; Slow and unreliable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set up promptfoo with a YAML config.&lt;/strong&gt; Way too much overhead for a quick gut-check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a platform like LangSmith.&lt;/strong&gt; Requires signup and sends your data to a cloud dashboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these fit the use case of "I just want to validate this one change before I push it."&lt;/p&gt;




&lt;h3&gt;
  
  
  What I built
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;compare-prompts&lt;/code&gt; takes a dict of prompts and a list of test inputs, runs them all through your model of choice, and prints a side-by-side behavioral comparison table in your terminal. No config files, no setup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;compare-prompts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;compare_prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;compare&lt;/span&gt;

&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;prompts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;original&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a helpful assistant.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;formal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a professional, formal assistant.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Explain what a database is.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is recursion?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write a short poem about coding.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Running 2 prompts x 3 inputs = 6 calls...

                    Prompt Comparison Results
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                         original             formal
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  avg length (tokens)    187                  143  (-24%)
  tone                   casual (68%)         formal (74%)
  uses lists             67%                  33%
  uses headers           33%                  66%  (+100%)
  avg cost (USD)*        $0.0021              $0.0016  (-24%)
  refusal rate           0%                   0%
  reading level          high school          college
  avg sentence length    18.3 words           24.1 words  (+32%)

* requires: pip install "compare-prompts[all]"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each column is a prompt. Each row is a measured behavioral difference. Numbers in parentheses are deltas from your baseline.&lt;/p&gt;




&lt;h3&gt;
  
  
  What it measures
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;What it tells you&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;avg length (tokens)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Is the change making responses longer or shorter?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tone&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dominant writing style across 9 categories&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;avg cost (USD)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Estimated API cost per call based on token usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;uses lists&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Does the phrasing change how often the model uses bullet points?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;uses headers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Same for markdown headers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;refusal rate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Is the new prompt accidentally making the model more cautious?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;reading level&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Flesch-Kincaid grade&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;avg sentence length&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Proxy for response density&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Supported models
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                        &lt;span class="c1"&gt;# OpenAI
&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;groq/llama-3.3-70b-versatile&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# Groq
&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini/gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;             &lt;span class="c1"&gt;# Google Gemini
&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ollama/llama3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                       &lt;span class="c1"&gt;# Ollama (local)
&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic/claude-3-5-haiku-20241022&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Anthropic
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For 2,600+ additional models (Azure, AWS Bedrock, Vertex AI, OpenRouter):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="s2"&gt;"compare-prompts[all]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Three scenarios where this is actually useful
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;You made a prompt "warmer." Did the tone column actually change, or did you just think it did?&lt;/li&gt;
&lt;li&gt;You are about to deploy a rewritten, shorter version of a 1,000-word inherited prompt. Confirm the refusal rate held at 0% before you push it.&lt;/li&gt;
&lt;li&gt;You want to know if a different model produces responses behaviorally close enough to your current one to justify switching.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  What is next
&lt;/h3&gt;

&lt;p&gt;Tone detection is currently keyword-based. I want to replace it with something smarter. CSV/JSON export, streaming output, and a &lt;code&gt;.gitignore&lt;/code&gt; generator for the init command are on the roadmap.&lt;/p&gt;

&lt;p&gt;PRs are open: &lt;a href="https://github.com/OmarMashal0/compare-prompts" rel="noopener noreferrer"&gt;https://github.com/OmarMashal0/compare-prompts&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>llm</category>
      <category>opensource</category>
      <category>promptengineering</category>
    </item>
  </channel>
</rss>
