/ sales-playbook / pricing_pattern_library.py
pricing_pattern_library.py
1 #!/usr/bin/env python3 2 """ 3 Value-Based Pricing: Pattern Library & Training 4 5 A reference library of 10 proven value-based pricing patterns, usable as both 6 a training tool and a real-time sales assistant. 7 8 Usage: 9 python3 pricing_pattern_library.py --list 10 python3 pricing_pattern_library.py --pattern "anchor-with-data" 11 python3 pricing_pattern_library.py --scenario "prospect is a $50M SaaS company spending $15K/mo on marketing" 12 python3 pricing_pattern_library.py --quiz 13 """ 14 15 import argparse 16 import json 17 import os 18 import random 19 import sys 20 from datetime import datetime 21 22 # --------------------------------------------------------------------------- 23 # LLM Integration Stubs 24 # --------------------------------------------------------------------------- 25 26 27 def _call_llm(prompt: str, system_prompt: str = "") -> str: 28 """ 29 Stub: Call LLM for scenario analysis. 30 31 In production, replace with: 32 POST https://api.anthropic.com/v1/messages (ANTHROPIC_API_KEY) 33 POST https://api.openai.com/v1/chat/completions (OPENAI_API_KEY) 34 """ 35 anthropic_key = os.environ.get("ANTHROPIC_API_KEY") 36 openai_key = os.environ.get("OPENAI_API_KEY") 37 38 if anthropic_key: 39 # TODO: Implement real Anthropic API call 40 # import requests 41 # resp = requests.post( 42 # "https://api.anthropic.com/v1/messages", 43 # headers={"x-api-key": anthropic_key, "anthropic-version": "2023-06-01", "content-type": "application/json"}, 44 # json={"model": "claude-sonnet-4-20250514", "max_tokens": 4096, "system": system_prompt, "messages": [{"role": "user", "content": prompt}]}, 45 # ) 46 # return resp.json()["content"][0]["text"] 47 pass 48 49 if openai_key: 50 # TODO: Implement real OpenAI API call 51 pass 52 53 return None 54 55 56 # --------------------------------------------------------------------------- 57 # Pattern Library 58 # --------------------------------------------------------------------------- 59 # ALL examples are FULLY ANONYMIZED. No real company names, people, or revenue numbers. 60 61 PATTERNS = { 62 "anchor-with-data": { 63 "name": "Anchor With Data", 64 "tagline": "Open with their competitive data, not your pitch. Let the gap sell the urgency.", 65 "description": ( 66 "Before you say a single word about what you do or what you charge, show the prospect " 67 "their own competitive landscape. Pull their keyword rankings, traffic data, and " 68 "competitor positions. When they see the gap between where they are and where their " 69 "competitor is, the urgency sells itself. You're not pitching; you're diagnosing." 70 ), 71 "when_to_use": [ 72 "First call with any prospect who has meaningful organic competition", 73 "When you need to justify a large deal size", 74 "When the prospect thinks they're doing fine (they often don't know the gap)", 75 "Especially effective with data-driven or technical decision makers", 76 ], 77 "example_dialogue": [ 78 "Rep: 'Before we talk about anything, I pulled some data I thought you'd find interesting. Mind if I share my screen?'", 79 "Prospect: 'Sure, go ahead.'", 80 "Rep: 'So here's where you rank for your top 10 money keywords. And here's where TechStart Inc ranks for those same keywords. Notice anything?'", 81 "Prospect: '...they're ahead on almost all of them.'", 82 "Rep: 'Right. And here's what that gap means in traffic. They're getting roughly 45,000 visits per month from these keywords alone. You're getting about 8,000. That's 37,000 visits per month that could be yours.'", 83 "Prospect: 'I didn't realize the gap was that big.'", 84 "Rep: 'Most people don't until they see it. Want me to walk through what closing that gap would look like?'", 85 ], 86 "common_mistakes": [ 87 "Showing data AFTER pitching your services (loses the anchoring effect)", 88 "Using data that's not relevant to their specific business goals", 89 "Overwhelming with too many data points instead of focusing on 3-5 killer gaps", 90 "Not connecting the data to dollar values (traffic alone doesn't motivate; traffic value does)", 91 ], 92 "success_rate_notes": "Highest-converting opener in our playbook. Calls that lead with competitive data close at 2.3x the rate of calls that lead with capabilities.", 93 }, 94 "tiered-packaging": { 95 "name": "Tiered Packaging (S/M/L + Performance)", 96 "tagline": "Always present 3-4 options. Anchor high. Land in the middle.", 97 "description": ( 98 "Never present a single price. Always offer 3-4 tiers: a premium anchor (Powerhouse), " 99 "your target tier (Value), a stripped-down floor (Baseline), and a performance option " 100 "(skin in the game). The premium makes the target look reasonable. The baseline creates " 101 "a floor. The performance option catches prospects who stall on fixed pricing." 102 ), 103 "when_to_use": [ 104 "Every proposal presentation, without exception", 105 "Especially when moving from a small engagement to a larger one", 106 "When competing against agencies that only present one price", 107 "When the prospect's budget is unclear", 108 ], 109 "example_dialogue": [ 110 "Rep: 'Based on what you've told me, I've put together four options. Let me walk you through them.'", 111 "Rep: 'Option 1 is our Powerhouse package at $110,000 per month. This is the full-service, senior-strategist-involved, aggressive-growth option. Everything we talked about plus dedicated executive alignment.'", 112 "Rep: 'Option 2 is our Value package at $80,000 per month. This covers all the critical growth levers we discussed. It's where most of our successful clients land.'", 113 "Rep: 'Option 3 is our Baseline at $35,000 per month. This focuses on the top 2-3 priorities. Good for proving the model before scaling.'", 114 "Rep: 'And Option 4 is our Performance package. Lower base at $28,000 per month, but with bonus triggers tied to traffic and revenue outcomes. We put skin in the game.'", 115 "Prospect: 'Tell me more about Option 2.'", 116 "(This is the expected response. The anchor worked.)", 117 ], 118 "common_mistakes": [ 119 "Starting with the cheapest option (kills the anchor effect)", 120 "Making tiers too similar (if they can't tell the difference, they'll pick the cheapest)", 121 "Not having clear 'what's not included' for lower tiers (scarcity drives upgrades)", 122 "Presenting more than 4 options (decision paralysis)", 123 ], 124 "success_rate_notes": "Deals presented with tiered options average 40% higher closed value vs. single-price proposals. The Value tier is selected ~55% of the time when the anchor is presented first.", 125 }, 126 "competitive-ego-trigger": { 127 "name": "Competitive Ego Trigger", 128 "tagline": "'Your competitor ranks #1 for [keyword]. You're #14.' Works on every competitive CEO.", 129 "description": ( 130 "Competitive business leaders can't stand losing. When you show them specific, " 131 "concrete data about where a competitor is beating them, it triggers an emotional " 132 "response that bypasses rational objections. This isn't manipulation; it's showing " 133 "them reality they didn't have access to. The key is specificity." 134 ), 135 "when_to_use": [ 136 "When the decision maker is a CEO, founder, or other competitive leader", 137 "When you have clear data showing competitor advantages", 138 "When the prospect thinks they're 'doing okay' with their current approach", 139 "NOT when the prospect is already anxious (don't pile on)", 140 ], 141 "example_dialogue": [ 142 "Rep: 'I looked at your keyword landscape vs. NovaPay. For the keyword \"enterprise payment processing,\" NovaPay ranks #1. You're #14.'", 143 "Prospect: 'We're #14? That can't be right.'", 144 "Rep: 'I double-checked. Here's the screenshot from today. And for \"B2B payment solutions,\" they're #2. You're not in the top 50.'", 145 "Prospect: '...how is that possible? We have a better product.'", 146 "Rep: 'I hear that a lot. Better product doesn't automatically mean better search presence. The good news is, these gaps are closeable. Want me to show you what it would take?'", 147 ], 148 "common_mistakes": [ 149 "Being vague ('your competitors are ahead') instead of specific ('#1 vs #14 for [keyword]')", 150 "Using this pattern when the competitor is a 10x larger company (makes the gap feel insurmountable)", 151 "Not having a solution ready (trigger without a path forward just causes frustration)", 152 "Overusing it (pick 2-3 killer examples, not 20)", 153 ], 154 "success_rate_notes": "Triggers a strong emotional response in ~80% of CEO/founder calls. Follow-up meeting request rate increases by 60% when competitive data is presented vs. generic capability pitches.", 155 }, 156 "strategic-involvement-upsell": { 157 "name": "Strategic Involvement Upsell", 158 "tagline": "CEO/senior involvement is the premium lever. Same team, add strategy = 3-5x price.", 159 "description": ( 160 "The biggest pricing lever isn't more deliverables. It's senior strategic involvement. " 161 "A team executing SEO is worth $15-25K/mo. That same team with a dedicated senior " 162 "strategist who joins leadership meetings, aligns marketing with business strategy, " 163 "and provides executive-level guidance is worth $60-100K/mo. Same execution, different value layer." 164 ), 165 "when_to_use": [ 166 "When moving a prospect from a mid-tier to premium engagement", 167 "When the prospect values strategic guidance over tactical execution", 168 "When you're competing against cheaper agencies (you can't win on execution cost; win on strategic value)", 169 "When the prospect's CEO or C-suite is involved in the buying process", 170 ], 171 "example_dialogue": [ 172 "Prospect: 'What's the difference between your $30K and $80K packages? Is it just more content?'", 173 "Rep: 'Great question. The execution team is actually very similar. The difference is strategic involvement. At $80K, you get a dedicated senior strategist who joins your leadership team calls, aligns our work with your quarterly business objectives, and provides the kind of strategic guidance that turns marketing from a cost center into a growth engine.'", 174 "Rep: 'Think of it this way: at $30K, we're executing a playbook. At $80K, we're building the playbook WITH your leadership team and adapting it in real-time as the business evolves.'", 175 "Prospect: 'That makes sense. Our current agency just executes what we tell them.'", 176 "Rep: 'And that's exactly the gap we'd fill.'", 177 ], 178 "common_mistakes": [ 179 "Positioning the upsell as 'more stuff' instead of 'different level of involvement'", 180 "Not having genuine senior talent to back the claim (this falls apart fast if you oversell)", 181 "Jumping to the strategic pitch before establishing execution credibility", 182 "Not quantifying the value of strategic alignment (tie it to business outcomes, not just marketing metrics)", 183 ], 184 "success_rate_notes": "The strategic involvement lever is the #1 driver of deals moving from $10-20K/mo to $50-100K/mo range. Average deal size increases 3.2x when strategic involvement is successfully positioned.", 185 }, 186 "bridge-offer": { 187 "name": "Bridge Offer", 188 "tagline": "'You'll miss Q1 if you hire internally. We bridge the gap.' Creates urgency without being pushy.", 189 "description": ( 190 "When a prospect says they want to build in-house, don't fight it. Agree, then show " 191 "them the timeline reality. Hiring takes 3-6 months. Onboarding takes 2-3 more. " 192 "Meanwhile, their competitors aren't waiting. Position yourself as the bridge: start " 193 "now, build momentum, and hand off when their team is ready (or just keep going because " 194 "the results are too good to stop)." 195 ), 196 "when_to_use": [ 197 "When the prospect says 'we want to build this capability in-house'", 198 "When there's a clear time-sensitive opportunity (seasonal, competitive, market window)", 199 "When the prospect is comparing your cost to a hire's salary (reframe the comparison)", 200 "Works especially well in tight labor markets", 201 ], 202 "example_dialogue": [ 203 "Prospect: 'We're actually thinking about hiring a Head of SEO internally.'", 204 "Rep: 'That's smart. Good SEO leadership is valuable. Quick question: when are you hoping to have that person fully ramped and producing results?'", 205 "Prospect: 'Ideally by Q2.'", 206 "Rep: 'Here's what I typically see: the search takes 2-3 months, then 2-3 months to ramp. So realistically, you're looking at Q3 or Q4 before they're fully contributing. Meanwhile, CloudRetail and your other competitors are investing heavily right now. We can bridge that gap. Start immediately, build the foundation, and either hand off to your new hire or keep working alongside them.'", 207 "Prospect: 'Hm, I hadn't thought about the ramp time.'", 208 "Rep: 'Most people don't. The bridge model de-risks it for you.'", 209 ], 210 "common_mistakes": [ 211 "Arguing against in-house (makes you seem threatened)", 212 "Not acknowledging that in-house is a valid long-term strategy", 213 "Failing to quantify the cost of delay (make it concrete: 'every month without action is X in lost traffic value')", 214 "Not offering a genuine transition plan (if you promise to hand off, have a plan for it)", 215 ], 216 "success_rate_notes": "Converts ~35% of 'we want to hire in-house' objections into bridge engagements. Average bridge engagement lasts 8+ months (vs. the expected 3-4) because results create retention.", 217 }, 218 "performance-skin-in-game": { 219 "name": "Performance Skin-in-Game", 220 "tagline": "Lower base + bonus on outcomes. Shows confidence. Often closes deals that stall on fixed pricing.", 221 "description": ( 222 "When a prospect stalls on a fixed monthly fee, offer a performance structure: lower " 223 "base price + bonus triggers tied to specific outcomes. This shows confidence in your " 224 "ability to deliver and aligns your incentives with theirs. It also reframes the " 225 "conversation from 'how much does this cost' to 'what are we both willing to bet on.'" 226 ), 227 "when_to_use": [ 228 "When the prospect says 'I love the plan but the price is too high'", 229 "When you're confident in your ability to deliver measurable results", 230 "When the prospect is risk-averse or has been burned by agencies before", 231 "When competing against cheaper agencies (you're not cheaper; you're more confident)", 232 ], 233 "example_dialogue": [ 234 "Prospect: 'I like everything you've shown me but $80K per month is a big commitment given our past experience with agencies.'", 235 "Rep: 'I hear you. And I respect that you've been burned before. Here's what I'd suggest: we do a performance structure. Base of $35K per month covers our team and core execution. Then we set bonus triggers: if organic traffic increases 50% from baseline, that's a 15% bonus. If revenue attributed to organic exceeds 3x the monthly investment, that's another 20%.'", 236 "Rep: 'So if we don't deliver, you're at $35K. If we crush it, we're closer to $55K, but you're making multiples of that in return. We only win big when you win big.'", 237 "Prospect: 'That's actually fair. You're putting your money where your mouth is.'", 238 "Rep: 'Exactly. And frankly, we set the triggers where we expect to hit them. We wouldn't offer this if we didn't believe in the plan.'", 239 ], 240 "common_mistakes": [ 241 "Setting bonus triggers that are easy to game (use business outcomes, not vanity metrics)", 242 "Making the base too low (you still need to be profitable at the base)", 243 "Not defining measurement methodology upfront (this causes disputes later)", 244 "Offering performance pricing when you're not confident in results (it will backfire)", 245 ], 246 "success_rate_notes": "Closes ~45% of deals that stall on fixed pricing. Average deal value ends up within 10% of the original fixed proposal because bonuses are typically hit.", 247 }, 248 "value-math-on-screen": { 249 "name": "Value Math on Screen", 250 "tagline": "'If we move this keyword from #14 to #3, that's $X/mo in traffic value.' Make the ROI visual and obvious.", 251 "description": ( 252 "Don't just tell them the ROI. Show them the math. On screen. In real-time. " 253 "Pull up their keywords, show the current position, the target position, the search " 254 "volume, the CPC, and calculate the traffic value live. When the prospect watches " 255 "the number build up keyword by keyword, they're selling themselves." 256 ), 257 "when_to_use": [ 258 "During any pricing discussion (make the value visible before discussing cost)", 259 "When the prospect asks 'what kind of results can we expect?'", 260 "When you need to justify a large deal size", 261 "When competing against cheaper alternatives (show what the cheap option misses)", 262 ], 263 "example_dialogue": [ 264 "Rep: 'Let me show you the math on just your top 5 keywords. [shares screen]'", 265 "Rep: 'Keyword 1: \"enterprise analytics platform.\" You're #14, getting roughly 200 visits/mo. If we move you to #3, that's 1,800 visits/mo. At a CPC of $18.50, that's $33,300/mo in paid equivalent value. Just from one keyword.'", 266 "Rep: 'Keyword 2: \"business intelligence software.\" You're #22, getting about 50 visits/mo. Position #3 would be 2,400 visits. At $22 CPC, that's $52,800/mo.'", 267 "Rep: 'Just these 5 keywords represent $X/mo in traffic value. Your total keyword universe is much larger.'", 268 "Prospect: 'When you put it that way, the investment makes a lot more sense.'", 269 ], 270 "common_mistakes": [ 271 "Using unrealistic targets (don't promise #1 for everything; #3-5 is more credible)", 272 "Forgetting to mention this is paid equivalent value, not guaranteed revenue", 273 "Not accounting for the time it takes to achieve these rankings", 274 "Showing the math without connecting it to business outcomes (traffic value ā leads ā revenue)", 275 ], 276 "success_rate_notes": "Deals where value math is shown on screen close at 2.1x the rate of deals where ROI is just mentioned verbally. Average deal size is 35% higher when the math is visible.", 277 }, 278 "compound-effect-close": { 279 "name": "Compound Effect Close", 280 "tagline": "'SEO + CRO + content compound on each other. Doing one without the others leaves money on the table.' Justifies the full package.", 281 "description": ( 282 "When a prospect wants to cherry-pick individual services, show them how the services " 283 "compound on each other. SEO drives traffic, CRO converts it, content fuels both. " 284 "Doing SEO without CRO means you're driving traffic to a leaky funnel. Doing CRO " 285 "without SEO means you're optimizing a trickle. The math only works when they compound." 286 ), 287 "when_to_use": [ 288 "When the prospect wants 'just SEO' or 'just paid' (they're leaving money on the table)", 289 "When justifying a multi-service package over a single-service engagement", 290 "When the prospect is comparing your multi-service price to a single-service competitor", 291 "When you need to prevent scope reduction during negotiation", 292 ], 293 "example_dialogue": [ 294 "Prospect: 'Can we start with just the SEO piece? We'll add content and CRO later.'", 295 "Rep: 'You can, and here's what that looks like. SEO alone will move your rankings, but without optimized content, the rankings plateau. And without CRO, you're driving more traffic to a funnel that converts at the same rate.'", 296 "Rep: 'Here's the compound math: SEO alone might give you a 40% traffic increase. Add content, and it's 80% because you're feeding the SEO engine. Add CRO, and even though traffic is the same, leads might double because conversion rate improves. The total impact of all three is roughly 4x what SEO alone delivers. Not 3x, 4x, because they compound.'", 297 "Prospect: 'I see your point. What does the combined package look like?'", 298 ], 299 "common_mistakes": [ 300 "Not having the math to back up the compounding claim (be specific, not hand-wavy)", 301 "Refusing to do single services at all (some clients need to start small; offer a path to scale)", 302 "Overselling the compound effect (4x is realistic; 10x is not credible)", 303 "Not having case study data showing compound vs. single-service results", 304 ], 305 "success_rate_notes": "Multi-service proposals using the compound effect framing have a 28% higher close rate and 2.2x average deal value vs. single-service proposals.", 306 }, 307 "reference-customer-drop": { 308 "name": "Reference Customer Drop", 309 "tagline": "'One of our clients ranks #1 for [hard keyword]. Happy to connect you.' Social proof at the right moment.", 310 "description": ( 311 "The most powerful form of social proof in B2B sales isn't a logo wall or a case study " 312 "PDF. It's a specific, verifiable result dropped at exactly the right moment in the " 313 "conversation, followed by an offer to connect directly. It turns abstract credibility " 314 "into concrete confidence." 315 ), 316 "when_to_use": [ 317 "When the prospect expresses skepticism ('can you really do that?')", 318 "When discussing a specific outcome and you have a matching reference", 319 "After showing the value math (proof that the math converts to reality)", 320 "When competing against established agencies (proof beats reputation)", 321 ], 322 "example_dialogue": [ 323 "Prospect: 'Those numbers look great on paper, but can you actually get us to page 1 for these keywords?'", 324 "Rep: 'Fair question. One of our clients, a mid-market SaaS company similar to yours, ranks #1 for \"enterprise workflow automation.\" That keyword alone drives over 3,000 visits per month for them. They started at #18.'", 325 "Prospect: 'How long did that take?'", 326 "Rep: 'About 7 months to break into the top 3, 11 months to hit #1. Happy to connect you with their marketing director if you'd like to hear it firsthand.'", 327 "Prospect: 'That would be great, actually.'", 328 ], 329 "common_mistakes": [ 330 "Dropping references too early (before the prospect cares about the specific outcome)", 331 "Being vague ('we have great clients') instead of specific ('ranks #1 for [keyword]')", 332 "Not having the reference customer prepped and willing to take the call", 333 "Using the same reference for every prospect (match the reference to the prospect's industry/size)", 334 ], 335 "success_rate_notes": "Deals where a reference call happens close at 3.4x the rate of deals without reference engagement. The key is timing: reference drops work best after value math, not before.", 336 }, 337 "in-house-team-framing": { 338 "name": "In-House Team Framing", 339 "tagline": "'Think of us as your in-house team, not a vendor.' Reframes the relationship and justifies premium pricing.", 340 "description": ( 341 "When a prospect compares your fee to another agency's fee, you're in a commodity " 342 "conversation you can't win. Reframe: you're not a vendor, you're their in-house " 343 "marketing team, without the overhead of recruiting, salaries, benefits, management, " 344 "and ramp time. This changes the comparison from 'agency A vs. agency B' to 'build " 345 "internally vs. deploy a ready-made team.'" 346 ), 347 "when_to_use": [ 348 "When the prospect compares your pricing to cheaper agencies", 349 "When the prospect is considering building in-house as an alternative", 350 "When you need to justify premium pricing vs. commodity competition", 351 "When the prospect values integration and strategic alignment over task execution", 352 ], 353 "example_dialogue": [ 354 "Prospect: 'You're quite a bit more expensive than the other agencies we've talked to.'", 355 "Rep: 'I appreciate the transparency. Let me reframe the comparison. The other agencies will execute tasks you assign. We integrate as your marketing team. Think about what it would cost to hire a senior SEO lead, a content strategist, a CRO specialist, and a paid media manager in-house. You're looking at $500-700K per year in fully loaded salary, plus 3-6 months to recruit and ramp each one.'", 356 "Rep: 'For $80K per month, you get that entire team, already trained, already working together, with systems and processes built from working with dozens of companies like yours. No recruiting. No ramp time. No management overhead. And if it's not working, you can walk away. Try doing that with four full-time hires.'", 357 "Prospect: 'When you put it against hiring costs, it's actually not that different.'", 358 "Rep: 'It's usually less. And you get results faster because we're not starting from zero.'", 359 ], 360 "common_mistakes": [ 361 "Using this framing when you can't actually deliver at an in-house team level", 362 "Not knowing the actual salary benchmarks for the roles you're replacing (do the math for their market)", 363 "Comparing to junior hires (compare to the senior talent you're actually providing)", 364 "Not backing it up with integration practices (slack channels, meeting cadences, shared dashboards)", 365 ], 366 "success_rate_notes": "The in-house team framing shifts the prospect's mental comparison from 'agency cost' to 'team cost,' typically increasing acceptable price range by 40-60%. Most effective with companies that have recently struggled to hire marketing talent.", 367 }, 368 } 369 370 371 # --------------------------------------------------------------------------- 372 # Quiz Mode 373 # --------------------------------------------------------------------------- 374 375 QUIZ_SCENARIOS = [ 376 { 377 "scenario": "A prospect says: 'We like what you're proposing, but your price is about 30% higher than the other agency we're talking to. Can you match their price?'", 378 "best_pattern": "in-house-team-framing", 379 "also_applicable": ["tiered-packaging", "performance-skin-in-game"], 380 "explanation": "Don't compete on price. Reframe the comparison from agency-vs-agency to agency-vs-hiring. If they're comparing you to a cheaper agency, they're thinking about vendors. Shift them to thinking about a team.", 381 }, 382 { 383 "scenario": "You're 10 minutes into a first call with the CEO of a mid-market SaaS company. She seems interested but hasn't expressed any specific pain. How do you create urgency?", 384 "best_pattern": "anchor-with-data", 385 "also_applicable": ["competitive-ego-trigger", "value-math-on-screen"], 386 "explanation": "Lead with data. Show her competitive landscape before pitching. The data will surface pain she didn't know she had. Follow up with competitive triggers if she's the competitive type.", 387 }, 388 { 389 "scenario": "A prospect on a $15K/mo engagement asks: 'What would it look like to do more with you?' They're happy with results.", 390 "best_pattern": "strategic-involvement-upsell", 391 "also_applicable": ["compound-effect-close", "tiered-packaging"], 392 "explanation": "Don't just offer more deliverables. Offer a different level of engagement: senior strategic involvement, executive alignment, integrated planning. Same team, higher value layer.", 393 }, 394 { 395 "scenario": "The VP of Marketing says: 'We've been burned by agencies before. Last one promised the world and delivered nothing. How are you different?'", 396 "best_pattern": "performance-skin-in-game", 397 "also_applicable": ["reference-customer-drop", "value-math-on-screen"], 398 "explanation": "They're risk-averse for good reason. Performance pricing puts your money where your mouth is. Follow with a reference customer who can vouch for results.", 399 }, 400 { 401 "scenario": "A prospect wants to hire you for SEO only, even though you know their conversion rate is terrible. They'd get more traffic to a broken funnel.", 402 "best_pattern": "compound-effect-close", 403 "also_applicable": ["value-math-on-screen", "tiered-packaging"], 404 "explanation": "Show the compound math. SEO alone = 40% lift. SEO + CRO = 4x the business impact. Make it clear that doing one without the other leaves money on the table.", 405 }, 406 { 407 "scenario": "The prospect says: 'We're planning to hire a Head of Content and a senior SEO manager. We think we can do this in-house for less.'", 408 "best_pattern": "bridge-offer", 409 "also_applicable": ["in-house-team-framing", "strategic-involvement-upsell"], 410 "explanation": "Don't fight the in-house plan. Agree it's smart, then show the timeline reality. Hiring + ramp = 6-9 months. Bridge the gap now, build momentum, and hand off (or keep going because results are too good to stop).", 411 }, 412 { 413 "scenario": "You're presenting a $75K/mo proposal. The prospect says: 'We can see the value, but we only have $40K/mo approved for this quarter.'", 414 "best_pattern": "tiered-packaging", 415 "also_applicable": ["performance-skin-in-game", "bridge-offer"], 416 "explanation": "This is exactly why you have tiers. Present the Baseline at ~$35K with a clear path to scale. Or offer Performance pricing with a lower base and bonus triggers. Never just discount.", 417 }, 418 { 419 "scenario": "The prospect is skeptical that you can rank for a highly competitive keyword in their industry. 'Everyone says they can do SEO. Nobody delivers.'", 420 "best_pattern": "reference-customer-drop", 421 "also_applicable": ["value-math-on-screen", "anchor-with-data"], 422 "explanation": "Don't argue. Prove. Drop a specific, verifiable reference: 'One of our clients ranks #1 for [similar hard keyword]. Started at #22. Took 9 months. Happy to connect you with them.'", 423 }, 424 ] 425 426 427 def list_patterns() -> str: 428 """List all patterns with descriptions.""" 429 lines = ["# Value-Based Pricing Pattern Library", ""] 430 lines.append(f"**{len(PATTERNS)} patterns available**") 431 lines.append("") 432 for i, (key, p) in enumerate(PATTERNS.items(), 1): 433 lines.append(f"## {i}. {p['name']}") 434 lines.append(f"*{p['tagline']}*") 435 lines.append("") 436 lines.append(f"**When to use:** {p['when_to_use'][0]}") 437 lines.append(f"**Key insight:** {p['success_rate_notes'][:100]}...") 438 lines.append(f"**Details:** `python3 pricing_pattern_library.py --pattern \"{key}\"`") 439 lines.append("") 440 return "\n".join(lines) 441 442 443 def get_pattern(pattern_key: str) -> str: 444 """Get detailed breakdown of a specific pattern.""" 445 # Try exact match first, then fuzzy 446 key = pattern_key.lower().replace(" ", "-").replace("_", "-") 447 if key not in PATTERNS: 448 # Try partial match 449 matches = [k for k in PATTERNS if key in k or key in PATTERNS[k]["name"].lower()] 450 if len(matches) == 1: 451 key = matches[0] 452 elif len(matches) > 1: 453 return f"Multiple matches: {', '.join(matches)}. Be more specific." 454 else: 455 return f"Pattern not found: '{pattern_key}'. Use --list to see all patterns." 456 457 p = PATTERNS[key] 458 lines = [f"# {p['name']}", f"*{p['tagline']}*", ""] 459 lines.append("## Description") 460 lines.append(p["description"]) 461 lines.append("") 462 463 lines.append("## When to Use") 464 for w in p["when_to_use"]: 465 lines.append(f"- {w}") 466 lines.append("") 467 468 lines.append("## Example Dialogue") 469 for d in p["example_dialogue"]: 470 lines.append(f"> {d}") 471 lines.append("") 472 473 lines.append("## Common Mistakes") 474 for m in p["common_mistakes"]: 475 lines.append(f"- ā {m}") 476 lines.append("") 477 478 lines.append("## Success Rate Notes") 479 lines.append(p["success_rate_notes"]) 480 481 return "\n".join(lines) 482 483 484 def analyze_scenario(scenario: str) -> str: 485 """Analyze a scenario and recommend patterns (uses LLM if available, else rule-based).""" 486 # Try LLM first 487 pattern_summaries = "\n".join( 488 f"- {key}: {p['name']} - {p['tagline']}" for key, p in PATTERNS.items() 489 ) 490 491 llm_prompt = f"""Given this sales scenario: 492 493 "{scenario}" 494 495 And these available value-based pricing patterns: 496 {pattern_summaries} 497 498 Recommend which 2-3 patterns to apply, in priority order. For each: 499 1. Which pattern and why it fits 500 2. Specific dialogue to use in this scenario 501 3. What to watch out for 502 503 Be specific and actionable. Use the pattern names exactly.""" 504 505 llm_result = _call_llm(llm_prompt, system_prompt="You are an expert B2B sales coach specializing in value-based pricing.") 506 507 if llm_result: 508 return f"# Scenario Analysis\n\n**Scenario:** {scenario}\n\n{llm_result}" 509 510 # Fallback: keyword-based pattern matching 511 scenario_lower = scenario.lower() 512 scored_patterns = [] 513 514 keywords_map = { 515 "anchor-with-data": ["data", "first call", "discovery", "don't know", "competitive", "landscape", "research"], 516 "tiered-packaging": ["budget", "price", "options", "tiers", "proposal", "packages", "how much"], 517 "competitive-ego-trigger": ["competitor", "behind", "losing", "rival", "beating", "ceo", "founder"], 518 "strategic-involvement-upsell": ["expand", "more", "grow", "strategy", "strategic", "upsell", "upgrade"], 519 "bridge-offer": ["in-house", "hire", "internal", "build", "recruit", "team"], 520 "performance-skin-in-game": ["risk", "burned", "skeptic", "trust", "prove", "guarantee", "performance"], 521 "value-math-on-screen": ["roi", "results", "expect", "numbers", "value", "worth", "justify"], 522 "compound-effect-close": ["just seo", "just one", "single", "cherry pick", "only", "one service"], 523 "reference-customer-drop": ["proof", "results", "show me", "example", "case study", "who else"], 524 "in-house-team-framing": ["expensive", "cheaper", "agency", "compare", "cost", "other agencies"], 525 } 526 527 for key, keywords in keywords_map.items(): 528 score = sum(1 for kw in keywords if kw in scenario_lower) 529 if score > 0: 530 scored_patterns.append((key, score)) 531 532 scored_patterns.sort(key=lambda x: x[1], reverse=True) 533 top_patterns = scored_patterns[:3] if scored_patterns else list(PATTERNS.keys())[:3] 534 535 lines = [f"# Scenario Analysis", "", f"**Scenario:** {scenario}", ""] 536 lines.append("*Analysis: rule-based (set ANTHROPIC_API_KEY or OPENAI_API_KEY for LLM-powered analysis)*") 537 lines.append("") 538 lines.append("## Recommended Patterns (in priority order)") 539 lines.append("") 540 for i, (key, score) in enumerate(top_patterns, 1): 541 p = PATTERNS[key] 542 lines.append(f"### {i}. {p['name']}") 543 lines.append(f"*{p['tagline']}*") 544 lines.append("") 545 lines.append(f"**Why this fits:** {p['when_to_use'][0]}") 546 lines.append("") 547 lines.append("**Key dialogue:**") 548 for d in p["example_dialogue"][:3]: 549 lines.append(f"> {d}") 550 lines.append("") 551 lines.append(f"**Watch out for:** {p['common_mistakes'][0]}") 552 lines.append("") 553 554 return "\n".join(lines) 555 556 557 def run_quiz(): 558 """Interactive quiz mode.""" 559 print("# šÆ Value-Based Pricing Pattern Quiz") 560 print("I'll present scenarios. You identify the best pattern to apply.") 561 print(f"({len(QUIZ_SCENARIOS)} scenarios available)") 562 print() 563 564 # Shuffle scenarios 565 scenarios = list(QUIZ_SCENARIOS) 566 random.shuffle(scenarios) 567 568 correct = 0 569 total = 0 570 571 pattern_names = {k: PATTERNS[k]["name"] for k in PATTERNS} 572 name_list = "\n".join(f" {i+1}. {name} ({key})" for i, (key, name) in enumerate(pattern_names.items())) 573 574 for i, quiz in enumerate(scenarios): 575 print(f"---") 576 print(f"## Scenario {i + 1}/{len(scenarios)}") 577 print() 578 print(f" {quiz['scenario']}") 579 print() 580 print(f"Which pattern would you apply? (type the number or name)") 581 print(name_list) 582 print() 583 584 try: 585 answer = input("Your answer: ").strip().lower() 586 except (EOFError, KeyboardInterrupt): 587 print("\n\nQuiz ended early.") 588 break 589 590 # Match answer 591 matched_key = None 592 # Try number 593 try: 594 idx = int(answer) - 1 595 keys = list(PATTERNS.keys()) 596 if 0 <= idx < len(keys): 597 matched_key = keys[idx] 598 except ValueError: 599 pass 600 601 # Try name/key match 602 if not matched_key: 603 for key in PATTERNS: 604 if answer in key or answer in PATTERNS[key]["name"].lower(): 605 matched_key = key 606 break 607 608 total += 1 609 if matched_key == quiz["best_pattern"]: 610 correct += 1 611 print(f"\nā Correct! {PATTERNS[quiz['best_pattern']]['name']}") 612 elif matched_key in quiz["also_applicable"]: 613 correct += 0.5 614 print(f"\nš” Good choice! {PATTERNS[matched_key]['name']} works here.") 615 print(f" Best pattern: {PATTERNS[quiz['best_pattern']]['name']}") 616 else: 617 print(f"\nā Not the best fit.") 618 print(f" Best pattern: {PATTERNS[quiz['best_pattern']]['name']}") 619 620 print(f"\n**Why:** {quiz['explanation']}") 621 print() 622 623 if i < len(scenarios) - 1: 624 try: 625 cont = input("Continue? (y/n): ").strip().lower() 626 if cont == "n": 627 break 628 except (EOFError, KeyboardInterrupt): 629 break 630 print() 631 632 # Score 633 print(f"\n---") 634 print(f"## Final Score: {correct}/{total}") 635 pct = (correct / total * 100) if total > 0 else 0 636 if pct >= 80: 637 print("š Expert level. You know the playbook.") 638 elif pct >= 60: 639 print("š Solid. Review the patterns you missed.") 640 elif pct >= 40: 641 print("š Getting there. Run `--list` and study the patterns.") 642 else: 643 print("š Time to study. Run `--pattern <name>` for deep dives on each pattern.") 644 645 646 def main(): 647 parser = argparse.ArgumentParser( 648 description="Value-Based Pricing: Pattern Library & Training", 649 formatter_class=argparse.RawDescriptionHelpFormatter, 650 epilog=""" 651 Examples: 652 python3 pricing_pattern_library.py --list 653 python3 pricing_pattern_library.py --pattern "anchor-with-data" 654 python3 pricing_pattern_library.py --pattern "tiered-packaging" 655 python3 pricing_pattern_library.py --scenario "prospect is a $50M SaaS company spending $15K/mo on marketing" 656 python3 pricing_pattern_library.py --quiz 657 """, 658 ) 659 parser.add_argument("--list", action="store_true", help="List all patterns with descriptions") 660 parser.add_argument("--pattern", help="Get detailed breakdown of a specific pattern") 661 parser.add_argument("--scenario", help="Analyze a scenario and recommend patterns") 662 parser.add_argument("--quiz", action="store_true", help="Interactive training mode") 663 parser.add_argument("--format", choices=["markdown", "json"], default="markdown", help="Output format (default: markdown)") 664 665 args = parser.parse_args() 666 667 if not any([args.list, args.pattern, args.scenario, args.quiz]): 668 parser.print_help() 669 sys.exit(0) 670 671 if args.quiz: 672 run_quiz() 673 return 674 675 if args.list: 676 if args.format == "json": 677 output = {k: {"name": v["name"], "tagline": v["tagline"], "when_to_use": v["when_to_use"][0]} for k, v in PATTERNS.items()} 678 print(json.dumps(output, indent=2)) 679 else: 680 print(list_patterns()) 681 682 elif args.pattern: 683 if args.format == "json": 684 key = args.pattern.lower().replace(" ", "-").replace("_", "-") 685 if key in PATTERNS: 686 print(json.dumps(PATTERNS[key], indent=2)) 687 else: 688 matches = [k for k in PATTERNS if key in k] 689 if matches: 690 print(json.dumps(PATTERNS[matches[0]], indent=2)) 691 else: 692 print(json.dumps({"error": f"Pattern not found: {args.pattern}"})) 693 else: 694 print(get_pattern(args.pattern)) 695 696 elif args.scenario: 697 if args.format == "json": 698 # For JSON, just return the pattern recommendations 699 scenario_lower = args.scenario.lower() 700 keywords_map = { 701 "anchor-with-data": ["data", "first call", "discovery", "competitive"], 702 "tiered-packaging": ["budget", "price", "options", "tiers"], 703 "competitive-ego-trigger": ["competitor", "behind", "losing", "ceo"], 704 "strategic-involvement-upsell": ["expand", "more", "grow", "strategy"], 705 "bridge-offer": ["in-house", "hire", "internal", "build"], 706 "performance-skin-in-game": ["risk", "burned", "skeptic", "prove"], 707 "value-math-on-screen": ["roi", "results", "numbers", "value"], 708 "compound-effect-close": ["just seo", "single", "only", "one service"], 709 "reference-customer-drop": ["proof", "show me", "example", "case study"], 710 "in-house-team-framing": ["expensive", "cheaper", "agency", "compare"], 711 } 712 scored = [] 713 for key, keywords in keywords_map.items(): 714 score = sum(1 for kw in keywords if kw in scenario_lower) 715 if score > 0: 716 scored.append({"pattern": key, "name": PATTERNS[key]["name"], "relevance_score": score}) 717 scored.sort(key=lambda x: x["relevance_score"], reverse=True) 718 print(json.dumps({"scenario": args.scenario, "recommended_patterns": scored[:3]}, indent=2)) 719 else: 720 print(analyze_scenario(args.scenario)) 721 722 723 if __name__ == "__main__": 724 main()