Skip to content

$ cat what-we-can-learn-from-claudes-fable-51-system-prompt.md

What We Can Learn from Claude’s Fable 5.1 System Prompt

Compares Anthropic's Claude Fable 5.1 system prompt with the Fable 5.0 version to show how product design and model quirks shift over time. Uses a diff of the lists_and_bullets section to show how formatting guidance was rewritten.

Drew Breunig08 Sept 2026 · 7 min read · summary
Read on www.dbreunig.com ↗
A couple notes on Claude’s Fable 5.1 system prompt. As I’ve written, looking at changes over time reveals product design decisions and more. Comparing Claude’s Fable 5.1 system prompt to its Fable 5.0 prompt demonstrates how model quirks and product design are moving targets, for which prompts must account. .diff-viz-root { --dv-font: charter, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; --dv-heading-font: charter, "Helvetica Neue", Helvetica, Arial, sans-serif; --dv-mono: monospace; --dv-text: #333; --dv-muted: #777; --dv-light: #999; --dv-primary: #6face8; --dv-primary-light: rgba(111, 172, 232, 0.2); --dv-callout-bg: #ebf5fb; --dv-border: lightgray; --dv-bg: #fff; --dv-del-text: #a12a2a; --dv-del-bg: #fde8e8; --dv-ins-text: #1f6b3a; --dv-ins-bg: #d9f5e3; font-family: var(--dv-font); font-size: 1.1rem; line-height: 1.5; color: var(--dv-text); margin: 2em 0; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .diff-viz-root .dv-container { border: 1px solid var(--dv-border); overflow: hidden; background: var(--dv-bg); } .diff-viz-root .dv-header { display: flex; align-items: center; justify-content: space-between; gap: 1em; padding: 0.6em 1em; border-bottom: 1px solid var(--dv-border); background: var(--dv-callout-bg); } .diff-viz-root .dv-title { font-family: var(--dv-mono); font-size: 13px; color: var(--dv-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* ── Segmented control ── */ .diff-viz-root .dv-segment { display: inline-flex; flex: none; border: 1px solid var(--dv-border); border-radius: 4px; background: var(--dv-bg); overflow: hidden; } .diff-viz-root .dv-segment button { width: auto; margin: 0; padding: 0.35em 0.9em; border: none; border-right: 1px solid var(--dv-border); border-radius: 0; background: transparent; color: var(--dv-muted); font-family: var(--dv-font); font-size: 13px; line-height: 1.2; cursor: pointer; transition: background 0.15s, color 0.15s; user-select: none; -webkit-user-select: none; } .diff-viz-root .dv-segment button:last-child { border-right: none; } .diff-viz-root .dv-segment button:hover:not(:disabled) { background: var(--dv-primary-light); } .diff-viz-root .dv-segment button:disabled { opacity: 0.3; cursor: default; } .diff-viz-root .dv-segment button.active { background: var(--dv-primary); color: #fff; } .diff-viz-root .dv-body { padding: 1.5em; font-family: var(--dv-mono); font-size: 0.8em; line-height: 1.6em; white-space: pre-wrap; word-wrap: break-word; } .diff-viz-root .dv-body del { color: var(--dv-del-text); background: var(--dv-del-bg); text-decoration: line-through; text-decoration-thickness: 1px; border-radius: 2px; padding: 0 0.1em; } .diff-viz-root .dv-body ins { color: var(--dv-ins-text); background: var(--dv-ins-bg); text-decoration: none; border-radius: 2px; padding: 0 0.1em; } .diff-viz-root .dv-src { display: none; } @media (max-width: 600px) { .diff-viz-root .dv-body { padding: 1em; } } lists_and_bullets Old Diff New ### lists_and_bullets Claude avoids over-formatting with bold emphasis, headers, lists, and bullet points, using the minimum formatting needed for clarity. Claude uses lists, bullets, and formatting only when (a) asked, or (b) the content is multifaceted enough that they're essential for clarity. Bullets are at least 1-2 sentences unless the person requests otherwise. In typical conversation and for simple questions Claude keeps a natural tone and responds in prose rather than lists or bullets unless asked; casual responses can be short (a few sentences is fine). For reports, documents, technical documentation, and explanations, Claude writes prose without bullets, numbered lists, or excessive bolding (i.e. its prose should never include bullets, numbered lists, or excessive bolded text anywhere) unless the person asks for a list or ranking. Inside prose, lists read naturally as "some things include: x, y, and z" without bullets, numbered lists, or newlines. Claude never uses bullet points when declining a task; the additional care helps soften the blow. `<lists_and_bullets>` Claude uses lists and bullet points when asked to or when the content is multifaceted enough that they help with clarity. Claude uses the minimum formatting needed for clarity If the person explicitly requests minimal formatting or for Claude to not use bullet points, headers, lists, bold emphasis and so on, Claude should always format its responses without these things as requested. Claude never uses bullet points when declining a task; the additional care helps soften the blow. In friendly, personal, or emotional chats Claude doesn't use formatting. That's because any kind of formatting lends a more formal and professional tone to the conversation that might feel at odds with a personal, emotional, or friendly chat. (function() { 'use strict'; if (!window.__diffViz) { window.__diffViz = {}; // Lines are matched first, then words within paired lines. A rewritten // paragraph that shares too few words with its partner is shown whole. var PAIR_THRESHOLD = 0.3; // Tokens are a word plus its trailing whitespace. Only the word is compared, // so reflowed whitespace does not register as a change. function tokenize(text) { var out = []; var re = /(\S+)(\s*)|(\s+)/g; var m; while ((m = re.exec(text)) !== null) { if (m[1] !== undefined) out.push({ key: m[1], text: m[1] + m[2] }); else out.push({ key: '', text: m[3] }); } return out; } // Longest common subsequence over item keys, walked into an edit script. function diff(a, b) { var n = a.length, m = b.length; var rows = new Array(n + 1); for (var i = 0; i = 0; i--) { for (var j = m - 1; j >= 0; j--) { rows[i][j] = a[i].key === b[j].key ? rows[i + 1][j + 1] + 1 : Math.max(rows[i + 1][j], rows[i][j + 1]); } } var ops = []; var i = 0, j = 0; while (i < n && j < m) { if (a[i].key === b[j].key) { ops.push(['eq', b[j]]); i++; j++; } else if (rows[i + 1][j] >= rows[i][j + 1]) { ops.push(['del', a[i]]); i++; } else { ops.push(['ins', b[j]]); j++; } } while (i < n) ops.push(['del', a[i++]]); while (j < m) ops.push(['ins', b[j++]]); return ops; } function append(target, tag, text) { if (!text) return; if (!tag) { target.appendChild(document.createTextNode(text)); return; } var el = document.createElement(tag); el.textContent = text; target.appendChild(el); } // Emits a word diff of one old line against one new line. Runs of the // same op collapse into one span, deletions ahead of insertions. function renderWords(oldLine, newLine, target) { var ops = diff(tokenize(oldLine), tokenize(newLine)); var k = 0; var tail = ' '; var emit = function(tag, text) { if (!text) return; if (!/\s$/.test(tail) && !/^\s/.test(text)) append(target, null, ' '); append(target, tag, text); tail = text.slice(-1); }; while (k < ops.length) { if (ops[k][0] === 'eq') { var eq = ''; while (k < ops.length && ops[k][0] === 'eq') eq += ops[k++][1].text; emit(null, eq); } else { var dels = '', inss = ''; while (k < ops.length && ops[k][0] !== 'eq') { if (ops[k][0] === 'del') dels += ops[k][1].text; else inss += ops[k][1].text; k++; } if (dels) { emit('del', dels.replace(/\s+$/, '')); emit(null, dels.match(/\s*$/)[0] || ' '); } if (inss) { emit('ins', inss.replace(/\s+$/, '')); emit(null, inss.match(/\s*$/)[0]); } } } } function similarity(a, b) { var ta = tokenize(a), tb = tokenize(b); if (!ta.length || !tb.length) return 0; var common = diff(ta, tb).filter(function(op) { return op[0] === 'eq'; }).length; return (2 * common) / (ta.length + tb.length); } function render(oldText, newText, target) { target.textContent = ''; var toLines = function(t) { if (!t.trim()) return []; return t.split('\n').map(function(l) { return { key: l.trim(), text: l }; }); }; var ops = diff(toLines(oldText), toLines(newText)); var k = 0; while (k < ops.length) { if (ops[k][0] === 'eq') { append(target, null, ops[k++][1].text + '\n'); continue; } var dels = [], inss = []; while (k < ops.length && ops[k][0] !== 'eq') { (ops[k][0] === 'del' ? dels : inss).push(ops[k][1].text); k++; } var count = Math.max(dels.length, inss.length); for (var p = 0; p < count; p++) { var d = dels[p], s = inss[p]; if (d !== undefined && s !== undefined && similarity(d, s) >= PAIR_THRESHOLD) { renderWords(d, s, target); append(target, null, '\n'); continue; } if (d !== undefined) { append(target, 'del', d.trim()); append(target, null, '\n'); } if (s !== undefined) { append(target, 'ins', s.trim()); append(target, null, '\n'); } } } } window.__diffViz.run = function(root) { if (root.dataset.rendered) return; var oldText = root.querySelector('.dv-old').textContent; var newText = root.querySelector('.dv-new').textContent; var body = root.querySelector('.dv-body'); var buttons = root.querySelectorAll('.dv-segment button'); function show(view) { if (view === 'old') body.textContent = oldText; else if (view === 'new') body.textContent = newText; else render(oldText, newText, body); buttons.forEach(function(b) { b.classList.toggle('active', b.dataset.view === view); }); } buttons.forEach(function(b) { if (b.dataset.view === 'old' && !oldText.trim()) b.disabled = true; b.addEventListener('click', function() { show(b.dataset.view); }); }); show('diff'); root.dataset.rendered = '1'; }; } var roots = document.querySelectorAll('.diff-viz-root'); window.__diffViz.run(roots[roots.length - 1]); })(); When I try to describe why Fable 5 and Opus 5 are terrible writers, my most concise take is that they write in bulleted lists while actively avoiding bullets. Short, curt points compressed into dense paragraphs. This was partially due to a system prompt that specifically discouraged bullets, but never stated why. Fable 5.1’s prompt dials this rule back and gives us a motivation while defining an exception: bullets make Claude feel less personal and friendly. It’s a good example of the challenges labs face as their user base grows. System prompts have to work for an

source

This is a summary of an article first published by Drew Breunig. The full piece is on their site.

Open original