Irrational Exuberancehttps://lethain.com/Recent content on Irrational ExuberanceHugo -- gohugo.ioen-usWill LarsonTue, 16 Jul 2024 20:00:00 -0700Developing domain expertise: get your hands dirty.https://lethain.com/domain-expertise/Tue, 16 Jul 2024 20:00:00 -0700https://lethain.com/domain-expertise/<p>Recently, I’ve been thinking about developing domain expertise, and wanted to collect my thoughts here. Although I covered some parts of this in <a href="https://lethain.com/first-ninety-days-cto-vpe/">Your first 90 days as CTO</a> (understanding product analytics, shadowing customer support, talking to customers, and talking with your internal experts), I missed the most important dimension of effective learning: getting your hands dirty.</p> <p>At Carta, I’m increasingly spending time focused on our fund financials business, which requires a deep understanding of accounting. I did not join Carta with a deep understanding of accounting.Initially, I hoped that I would learn enough accounting through customer escalations, project review, and so on, but recently decided I <em>also</em> needed to work through <em><a href="https://www.amazon.com/dp/1119594596">Financial Accounting, 11th Edition</a></em> by Weygandt, Kimmel, and Kieso.</p> <p>The tools for building domain expertise vary quite a bit across companies, and I found the same tools ranged from excellent to effectively useless when applied across Stripe (an increasingly expansive platform for manipulating money online), SocialCode (a Facebook advertising optimization company), and Carta (a platform for fund administration and a platform for cap table management). Here are some notes about approaches taken at specific companies, followed by some generalized recommendations.</p> <h2 id="uber">Uber</h2> <p>Uber likely had the simplest and most effective strategy of any product I’ve worked on: each employee got several hundred dollars of Uber credits every month to use the product. This, combined with the fact that almost all early hires lived in markets that had an active Uber marketplace going, meant that our employees intimately experienced the challenges.</p> <p>This was particularly impactful for folks who traveled to other cities or countries and experienced using Uber there. Often the experience was pretty inconsistent across cities, and experiencing that inconsistency directly was extremely valuable.</p> <h2 id="carta">Carta</h2> <p>Returning to my starting paragraph on Carta, Carta operates in a series of deep, complex domains: equity management is a complex legal domain, and fund administration is a complex accounting domain. Ramping in either, let alone both, is difficult.</p> <p>Carta has an unlimited individual book budget, and they pay for the Certified Equity Professional (CEP) test. These are good educational benefits, but are more a platform that you can build on than the actual learning itself. Teams working on products tend to develop deep domain expertise by building in that domain, but that approach is difficult to apply as an executive as I’m typically simultaneously engaging with so many different products and problems.</p> <p>In addition to the standard foundation of domain learning (talking to customers, digging into product and business analytics, etc), I’ve found three mechanisms particularly helpful: our executive sponsor program, reading textbooks, and initiative-specific deep dives.</p> <p>For our executive sponsor program, we have a C-level executive assigned to key customers, who are involved in every escalation, periodic check-ins and advocating for those customers in our roadmap planning. By design, being a sponsor is painful when things don’t go well, and that is a very pure, effective learning mechanism: figure out the customer’s problem, and then track resolving it through the company. Some days I don’t <em>enjoy</em> being a sponsor, but it’s the most effective learning mechanism I’ve found for our exceptionally deep domains, and I’m grateful we rolled the program out.</p> <p>Second, I’ve found book learning very effective at creating a foundation to dig into product and technical considerations in the accounting domain. For example, soon after joining I found a short refresher on accounting, reading <em><a href="https://www.amazon.com/dp/0981454224">Accounting Made Simple</a></em> by Mike Piper in a couple of hours. Later, I worked through the <a href="https://www.udemy.com/course/partnership-accounting/?couponCode=LETSLEARNNOWPP">Partnership Accounting</a> course on Udemy, and now I’m working through two textbooks, <em><a href="https://www.amazon.com/dp/1119594596">Financial Accounting, 11th Edition</a></em> and <em><a href="https://www.amazon.com/gp/product/093118701X/">Understanding Partnership Accounting</a></em>.</p> <p>Finally, initiative-specific deep dives have been a good opportunity to work directly with a team on a narrow problem until we solved a complex problem together. This taught me a lot about the domain, the individuals, and hopefully provided them with a better sense and relationship with me as an executive sponsoring a project they also cared about. My first big project was working with our payments infrastructure team to support automated money movement in our fund administration product, and I learned <em>so much</em> from the team on that project. I also know there’s no chance I’d understand the complexities at the intersection of money movement and fund administration so well if I hadn’t gotten to work with them on that project.</p> <h2 id="stripe">Stripe</h2> <p>At the time I joined Stripe, all new employees were encouraged to read <em><a href="https://www.amazon.com/Payments-Systems-U-S-Third-Professional/dp/0982789742">Payment Systems in the US</a></em>. More ambitious folks usually built a straightforward Stripe store of some sort: <a href="https://blog.singleton.io/">David Singleton</a> created a site to sell journals, and <a href="https://michellebu.com/">Michelle Bu</a> maintained a store that sold t-shirts with the seconds since epoch printed on them. Building a store was a great educational experience, but maintaining the store live was significantly more valuable in understanding the friction that bothered our users. Things like forced upgrades or late tax forms are abstract when imposed on others, and illuminating when you experience them directly.</p> <p>As Stripe got increasingly broad and complex, it became increasingly difficult for anyone to maintain a deep understanding of the entire stack. To combat that trend, executives relied more on mechanisms like project-driven learning on high-priority projects, and executive sponsors for key customers. They certainly also relied on standard mechanisms like talking to customers frequently, frequently reviewing product data, and so on.</p> <h2 id="intercom">Intercom</h2> <p>I met <a href="https://www.linkedin.com/in/scanlanb/">Brian Scanlan</a> some years back, who told me that executives at <a href="https://www.intercom.com/">Intercom</a> would start each offsite by doing a quick integration of their product into a new website. The goal wasn’t to do a novel integration, but to stay close to the integration experience of their typical user. I still find this a fairly profound idea, and I tried a variation of this idea at Carta’s most recent executive offsite, making every executive start the offsite by performing a handful of fund administration tasks on a demo fund’s data.</p> <h2 id="felt">Felt</h2> <p>Chatting with one of the founders at <a href="https://felt.com/">Felt</a>, <a href="https://duruk.net/">Can Duruk</a>, about this topic, he mentioned that they maintain an <a href="https://gisfundamentals.felt.com/Fundamentals-of-GIS-0fb2a768ff37420cabe7d10b6cac98c2">introduction to Geographic Information Systems</a> for both employees and users to understand the domain. They also hired an in-house cartographer who helps educate the team on the details of map making.</p> <h2 id="recommendations">Recommendations</h2> <p>The recommendations I would make are embedded in the specific stories above, but I’ll compact them into a list as well for easier reference. Some particularly useful mechanism for senior leaders to develop domain expertise are:</p> <ul> <li><strong>Reviewing product analytics on a recurring basis</strong>. Your goal is to build an intuition around how the data should move, and then refine that intuition against how the data moves in reality.</li> <li><strong>Shadow customer support</strong> to see customer issues and how those issues are resolved.</li> <li><strong>Assign named executive sponsors for key customers.</strong> Those sponsors should meet with those customers periodically, be a direct escalation point for those customers, be aware of issues impacting those customers, and be an advocate for those customers’ success.</li> <li><strong>Directly use or integrate with the product</strong>. Try to find ways that more closely different customer cohorts rather than just what you find most common. For example, if you only used Uber in San Francisco in 2014, you had a radically misguided intuition about how well Uber worked.</li> <li><strong>Make an executive offsite ritual around using the product.</strong> Follow Intercom’s approach to routinely integrate the core parts of your product from scratch, experiencing the challenges of your new users over and over to ensure they don’t degrade.</li> <li><strong>Use executive initiatives as an opportunity to dig deep into particular areas of the business.</strong> Over the past year, the areas at Carta that I’ve learned the best are the ones where I embedded myself temporarily into a team dealing with a critical problem and kept with them until the problem was resolved.</li> <li><strong>Use a textbook or course driven approach</strong> to understand the underlying domain that you’re working in. This applies from Uber’s marketplace management to Carta’s accounting.</li> </ul> <p>The details of ramping up on a specific domain will always vary a bit, but hopefully something in there gives you a useful starting point for digging into yours. So often executives take a view that the constraints are a problem for their teams, but I think great executive leadership only exists when individuals can combine the abstract mist of grand strategy with the refined nuance of how things truly work. If this stuff seems like the wrong use of your time, that&rsquo;s something interesting to reflect on.</p>Physics and perception.https://lethain.com/physics-perception/Sat, 29 Jun 2024 07:00:00 -0700https://lethain.com/physics-perception/<p>At one point in 2019, several parts of Stripe’s engineering organization were going through a polite civil war. The conflict was driven by one group’s belief that Java should replace Ruby. Java would, they posited, address the ongoing challenge of delivering a quality platform in the face of both a rapidly growing business and a rapidly growing engineering organization. The other group believed Stripe’s problems were driven by <a href="https://lethain.com/quality/">a product domain with high essential complexity</a> and numerous, demanding external partners ranging from users to financial institutions to governments; switching programming languages wouldn’t address any of those issues. I co-wrote the internal version of <a href="https://lethain.com/magnitudes-of-exploration/">Magnitudes of exploration</a> in an attempt to find a useful framework for navigating that debate, but nonetheless the two groups struggled to make much progress in understanding one another.</p> <p>I was reminded of those discussions while reading Steven Sinofsky&rsquo;s <em><a href="https://www.amazon.com/Hardcore-Software-Inside-Rise-Revolution-ebook/dp/B0CYBS9PFY">Hardcore Software</a></em>’s chapter on <a href="https://hardcoresoftware.learningbyshipping.com/p/020-innovation-versus-shipping-the">Innovation versus Shipping: The Cairo Project</a>:</p> <blockquote> <p>Landing on my desk early in 1993 was the first of many drafts of Cairo plans and documents. Cairo took the maturity of the NT product process—heavy on documentation and architectural planning—and amped it up. Like a well-oiled machine, the Cairo team was in short order producing reams of documents assembled into three-inch binders detailing all the initiatives of the product. Whenever I would meet with people from Cairo, they would exude confidence in planning and their processes. … While any observer should have rightfully taken the abundance of documentation and confidence of the team as a positive sign, the lack of working code and ever-expanding product definition seemed to set off some minor alarms, especially with the Apps person in me. While the Cairo product had the appearance of the NT project in documentation, it seemed to lack the daily rigorous builds, ongoing performance and benchmarking, and quality and compatibility testing. There was a more insidious dynamic, and one that would prove a caution to many future products across the company but operating systems in particular.</p> </blockquote> <p>The simple narrative regarding both the Cairo development and Java migration is that there&rsquo;s a group doing the &ldquo;right&rdquo; thing, and another group doing the &ldquo;wrong&rdquo; thing. The Cairo team was shipping vaporware. The Java team was incorrectly diagnosing the underlying problems. These sorts of descriptions are comforting because they create the familiar narrative structure of &ldquo;good&rdquo; in conflict with &ldquo;evil.&rdquo; Unfortunately, I&rsquo;ve never found these sorts of narratives very useful for understanding what causes a conflict, and they&rsquo;re worse than useless at actually resolving conflicts.</p> <p>What I have found useful is studying what each faction knows <a href="https://lethain.com/layers-of-context/">that the other doesn&rsquo;t</a>, and trying to <a href="https://lethain.com/multi-dimensional-tradeoffs/">understand those gaps deeply enough to find a solution</a>. Sometimes I summarize this as &quot; solving for both physics and perception.&quot;</p> <h2 id="solving-for-perception">Solving for perception</h2> <p>Sinofsky&rsquo;s represents Cairo as an impossibly broad project that didn&rsquo;t ship, but he also explains why it picked up so many features:</p> <blockquote> <p>Cairo tended to take this as a challenge to incorporate more and more capabilities. New things that would come along would be quickly added to the list of potential features in the product. Worse, something that BillG might see conceptually related, like an application from a third party for searching across all the files on your hard disk, might become a competitive feature to Cairo. Or more commonly “Can’t Cairo just do this with a little extra work?” and then that little extra work was part of the revised product plans.</p> </blockquote> <p>It wasn&rsquo;t ill-intentioned, rather they simply wanted to live up to their CEO&rsquo;s expectations. They wanted to be perceived as succeeding within their company&rsquo;s value system, because they correctly understood that their project would be canceled otherwise.</p> <p>Many incoming leaders find themselves immediately stuck in similar circumstances. They&rsquo;ve just joined and don&rsquo;t understand the domain or team very well, but are being told they need to immediately make progress on a series of problems that have foiled the company&rsquo;s efforts thus far. They know they need to appear to be doing something valuable, so they do <em>anything</em> that might look like progress. It&rsquo;s particularly common for leaders to begin a <a href="https://lethain.com/grand-migration/">Grand Migration</a> at that moment, which they hope will solve the problems at hand, but no matter what will be perceived as a brave, audacious initiative.</p> <p><img src="https://lethain.com/static/blog/2024/physics-perception.png" alt="Image of stacked layers, with each layer belonging to a different team. Some of these layers are grouped into perception, and some are grouped into physics. Neither perception nor physics represents the entire set."></p> <p>This isn&rsquo;t a problem unique to executives or product engineers, I frequently see platform teams make the same mistake when <a href="https://lethain.com/migrations/">they undertake large-scale migrations</a>. Many platform migrations are structured as <a href="https://lethain.com/incident-response-programs-and-your-startup/">an organizational program</a> where a platform team tells product teams they need to complete a certain task (e.g. &ldquo;move to our monorepo&rdquo;) by a certain date, along with tracking dashboards that inform executives which teams have or haven&rsquo;t completed their tasks. This does a great job of applying pressure to the underlying teams, and a good job of managing perceptions by appearing to push hard, but these migrations often fail because there&rsquo;s little emphasis on the underlying ergonomics of the migration itself. If you tell teams they are failing if they miss a date, they will try to hit the date; if it&rsquo;s hard, they&rsquo;ll still fail. Platform teams in that case often blame the product teams for not prioritizing their initiative, when instead the platform teams should have the self-awareness to recognize that they made things difficult by not simplifying the underlying physics for the product teams they asked to migrate.</p> <p>There&rsquo;s nothing wrong about solving for perception, and indeed it&rsquo;s a necessary skill to be an effective leader. Rather the lesson here is that most meaningful projects require solving for both perception <em>and</em> physics.</p> <h2 id="solving-for-physics">Solving for physics</h2> <p>When I joined Stripe, one of the first projects I wanted to take on was migrating to Kubernetes and away from hand-rolled tooling for managing VMs directly. This was heavily influenced by what I had learned migrating Uber from a monolithic Python application to polygot applications in a polyrepo. After a few months of trying to build alignment within engineering, I postponed the Kubernetes migration for a few years because I couldn&rsquo;t convince them it solved a pressing problem. (I did come back to it, and it was a success when I did.) I could have forced the team to work on that project, but it goes against my instincts: generally when engineers push back on leadership ideas, there&rsquo;s a good reason for doing so.</p> <p>Similarly, my initial push at Stripe was not toward the Ruby typing work that became <a href="https://sorbet.org/">Sorbet</a>, but rather to design an incremental migration towards an existing statically-typed language such as Java or Go. The argument I got back was that this was impractical because it required too large a migration effort, and that Facebook&rsquo;s <a href="https://hacklang.org/">Hack</a> had already proven out the viability of moving from PHP to a PHP-like typed language. I took my time to understand the pushback, and over time shifted my thinking to focus instead on sequencing these efforts: even if we wanted to move to a different language, first we needed to improve the architecture to support migrating modules, and that effort would benefit from typing Ruby.</p> <p>I was fortunate in these cases, because there were few perceptions that I needed to solve for, and I was able to mostly focus on the physics. Indeed, the opportunity to focus on physics is one of the undervalued advantages of working within infrastructure engineering. You&rsquo;ll rarely be lucky enough in senior leadership roles to focus on the physics.</p> <p>For example, when I joined Carta, there was pressure across the industry and internally to increase our investment into using LLMs. Most engineers were quite skeptical of the opportunity to use LLMs, so if I&rsquo;d listened exclusively to the physics, I would have probably ignored the pressure to adopt. However, that would have led me astray in two ways. First, I would have seriously damaged the wider executive team&rsquo;s belief in my ability to incorporate new ideas. Second, physics are anchored on how we understand the world today, and LLMs are a place where things are evolving quickly. Our approach to <a href="https://lethain.com/video-mental-model-for-how-to-use-llms-in-products/">using LLMs in our product</a> is better than anything we would have gotten to by <em>only</em> solving for physics. (And vastly better than we&rsquo;d have come up with if we&rsquo;d only solved for perception.)</p> <p>I think the LLM example is instructive because it violates the expectation that &ldquo;physics&rdquo; are real and &ldquo;perceptions&rdquo; are false. It can go both ways, depending on the circumstances. As soon as you get complacent about your perspective representing reality, you&rsquo;ll quickly be disabused of that notion.</p> <h2 id="balancing-physics-and-perception">Balancing physics and perception</h2> <p>Effective leaders meld perception and physics into approaches that solve both. This is hard to do, takes a lot of energy, and when done well often doesn&rsquo;t even look like you&rsquo;re doing that much. Many leaders try to solve both, but eventually give in to the siren&rsquo;s song of applying perception pressure without a point of view on how that pressure should be channeled into a physical plan. Applying pressure without a plan is the same issue as the infrastructure migration, where you can certainly create accountability, but it&rsquo;s pretty likely to fail.</p> <p>Pressure without a plan <em>is</em> appropriate at some level of seniority, and it&rsquo;s important to understand within a given organization where responsibility lies for appending a plan to the pressure. In a small startup (10s of people), that&rsquo;s probably the founders. In a medium-sized company (100s of people), that&rsquo;s likely the executive team. As the company grows, more and more of the plan will be devised further from the physics, but you always have to decide where planning should start.</p> <p>There is always a point where an organization will simply give up on planning and allow the pressure to cascade undeterred. In a high-functioning organization, that pressure point is quite high. In lower-functioning organizations, it will occur frequently even if there&rsquo;s little pressure.</p> <p>If you can reduce pressure too little, you can also reduce pressure too much. One of my biggest regrets from my time at Stripe is that I allowed too little pressure to hit my organization, which over time created a <a href="https://lethain.com/values-oasis/">values oasis</a> that operated with a clear plan but also limited pressure. When I left, the pressure regulator came off, and my organization had a rough patch learning to operate in the new circumstances.</p> <p>Altogether, this balance is difficult to maintain. I&rsquo;m still getting better at it slowly over time, learning mostly from mistakes. As a final thought here, respecting physics doesn&rsquo;t necessarily mean doing what engineers want you to do: those who speak for physics aren&rsquo;t necessarily right. Instead, it&rsquo;s making a deliberate, calculated tradeoff between the two that&rsquo;s appropriate to the circumstances. Sometime&rsquo;s that courageously pushing back on an impossible timeline, sometimes it&rsquo;s firing a leader who insists change is impossible.</p>How to create software quality.https://lethain.com/quality/Sun, 16 Jun 2024 16:00:00 -0700https://lethain.com/quality/<p>I’ve been reading Steven Sinofsky’s <em><a href="https://www.amazon.com/Hardcore-Software-Inside-Rise-Revolution-ebook/dp/B0CYBS9PFY">Hardcore Software</a></em>, and particularly enjoyed this quote from a memo discussed in the <a href="https://hardcoresoftware.learningbyshipping.com/p/006-zero-defects">Zero Defects</a> chapter:</p> <blockquote> <p>You <em>can</em> improve the quality of your code, and if you do, the rewards for yourself and for Microsoft will be immense. <em>The hardest part is to decide that you want to write perfect code.</em></p> </blockquote> <p>If I wrote that in an internal memo, I imagine the engineering team would mutiny, but software quality is certainly an interesting topic where I continue to refine my thinking. There are so many software quality playbooks out there, and I increasingly believe that all these playbooks work <em>in their intended context</em>, but are often misapplied.</p> <p>For example, pretty much every startup has someone on an infrastructure team who believes that all quality problems can be solved with a sufficiently nuanced automated rollout strategy. That&rsquo;s generally been true in my experience at companies with a high volume of engaged usage, and has not at all been true in environments with low or highly varied usage. Unsurprisingly, folks who&rsquo;ve only seen high volume scenarios tend to overestimate the value of rollout techniques, and folks who&rsquo;ve never seen high volume scenarios tend to underestimate the value of rollout techniques.</p> <p>This observation is the underpinning of my beliefs about creating software quality. Expanding from that observation, I&rsquo;ll try to convince you of two things:</p> <ol> <li> <p>Creating quality is context specific. There are different techniques for solving essential domain complexity, scaling complexity, and accidental complexity.</p> <p>For example, phased automated rollouts don&rsquo;t help much if there&rsquo;s little consistency among your users&rsquo; behaviors.</p> </li> <li> <p>Quality is created both within the development loop and across iterations of the development loop. Feedback within the loop, as opposed to across iterations, creates quality more quickly. Feedback across iterations tends to <em>measure</em> quality, which informs future quality, but does not necessarily create it.</p> <p>For example, bugs detected after software is nominally complete tend to be fixed locally, even if they reveal a suboptimal approach. I&rsquo;ve seen projects launch using Redis for no reason, which later causes a production incident, just because the developer was interested in learning about Redis and it was too late to rip it out without doing substantial rework.</p> </li> </ol> <p>Those are some nice words. Let’s see if I can convince you that they’re meaningful words.</p> <h2 id="defining-quality">Defining quality</h2> <p>Generally I think quality is in the eye of the beholder, but my experience writing for the internet indicates that people will be upset if I don’t supply a definition of quality, so here’s my working direction:</p> <ul> <li>Software behaves as its users anticipate it should behave</li> <li>Software is easy to modify</li> <li>Software meets reasonable non-functionality requirements (latency, cost, etc)</li> </ul> <p>There are, undoubtedly, better definitions out there, and feel free to insert yours.</p> <h2 id="kinds-of-complexity">Kinds of complexity</h2> <p>Managing quality is largely about finding useful ways to deal with complexity. For example, a codebase might be complex due to its size. Complexity in large codebases can be managed by using a strongly typed language, increasing test coverage, and so on.</p> <p>I find it useful to recognize whether complexity is mostly driven by high scale (e.g. you&rsquo;re performing 10,000s or 100,000s of requests per second) or whether complexity is mostly driven by a complex business domain (e.g. you&rsquo;re trying to capture the intent of open-ended business contracts into a structured database). I think of the former as &ldquo;scale complexity&rdquo; and the later as &ldquo;essential domain complexity&rdquo;, extending the phrase from Fred Brooks&rsquo; <a href="https://en.wikipedia.org/wiki/No_Silver_Bullet">No Silver Bullet</a>.</p> <p><img src="https://lethain.com/static/blog/2024/complexity-grid.png" alt="Two-by-two grid of complexity due to scale versus due to essential domain complexity."></p> <p>The third common sort of complexity is accidental complexity. If you&rsquo;ve used a bunch of different technologies for each part of your product because your team was excited to &ldquo;try out something new&rdquo;, then your problems are likely of the accidental variety.</p> <h2 id="creating-quality-is-context-specific">Creating quality is context-specific</h2> <p>My experience is that most folks in technology develop strongly-held opinions about creating quality that anchor heavily on their first working experiences. For example, many folks whose early jobs included:</p> <ul> <li>high-volume websites or APIs believe that automated rollbacks driven by production metrics are a fundamental mechanism to prevent a low quality release from impacting users. However, in a domain with infrequent, complex and precise user actions–very much the case for Carta’s domains of fund accounting and managing cap tables–those techniques are less helpful. They certainly might prevent <em>some</em> issues, but they’d fail to prevent many others because the volume of user actions is insufficient to test the full cardinality of potential configurations</li> <li>high-volume consumer-facing applications believe that A/B testing can determine quality. However, Michelle Bu’s <a href="https://increment.com/apis/api-design-for-eager-discerning-developers/">Eagerly discerning, discerningly eager</a> discusses how many tools for validating quality don’t apply effectively when it comes to API design. She proposes friction logs as a replacement for user interviews, pilot programs as a replacement for beta testing, and dogfooding as a replacement for A/B testing</li> <li>highly critical and narrow problem spaces might benefit from multiple heterogeneous implementations voting to determine the correct answer in the face of software errors, as described in Gloria Davis’ 1987 paper <a href="https://ntrs.nasa.gov/api/citations/19870019975/downloads/19870019975.pdf">An Analysis of Redundancy Management Algorithms for Asynchrous Fault Tolerant Control Systems</a>. However, maintaining and verifying multiple heterogeneous implementations would be extremely costly for broad problem domains that are expected to change frequently (the typical problem domain for startups)</li> </ul> <p>The key observation here is that there’s no universal solution that “just works” across all problem domains. Even the universally accepted ideal of “have a highly conscientious and high-context engineer do it all themselves” isn’t a viable solution in an environment where the current team is too small for the desired volume of work.</p> <p>Generally, I think your approach to creating quality will vary on these dimensions:</p> <ul> <li><strong>Essential domain complexity</strong> – a problem domain with few workflows and conditions can often be validated by looking at user usage (e.g. an application like Instagram, TikTok or Calm has very few workflows and conditions in the software, although the variety of mobile devices they need to run on does increase essential complexity). A problem domain with many workflows or many conditions requires a different approach, which might range from simulating usage to formal specification.</li> <li><strong>Scalability complexity</strong> – sufficient user traffic solves a lot of problems. At Calm, Uber or Stripe, the scale was high enough that errors were immediately visible in operational data, even with an incremental rollout strategy. At Carta, that would only be true in the case of an exceptionally broad error (a category of error that’s relatively straightforward to catch with automated testing), given the different user usage patterns.</li> <li><strong>Maturity and tenure of team</strong> – a team with deep context in the problem domain is able to drive quality with fewer distinct roles, more individual empowerment, and less structured process. A team with high turnover generally leans on more defined roles where it’s easier to quickly develop context. Similarly, a team that feels accountable for high-quality will behave differently than a team that feels otherwise.</li> </ul> <p>To develop my point a bit, let’s think about two combinations and how we’d approach quality differently:</p> <ul> <li><strong>Low essential complexity problem domain, high traffic, and deep team context</strong> – a thorough test suite will go a long way to validating the expected behavior, and the team has enough familiarity with the problem space for engineers to effectively test as they implement. If you do miss something, an incremental rollout mechanism, using production operating metrics to pace rollout, will probably prevent testing gaps from significantly impacting your users</li> <li><strong>High essential complexity problem domain, low traffic, and limited team context</strong> – designing effective test suites is a challenge because of your team’s limited context and the complex problem space. This means you may need dedicated individuals working on testing frameworks to encapsulate domain context into a reusable testing harness/framework rather than relying on individual team member’s context. It might also mean a focus on highly defined types that codify parts of the domain context into the typechecker itself rather than depending on the awareness of each individual writing incremental code. Incremental rollout mechanisms are unlikely to catch issues missed by testing, because conditions differ enough across users that even a small number of catastrophically failing users are unlikely to meet the necessary thresholds</li> </ul> <p>These are radically different approaches, and if you naively applied the solution for one combination to another, you will generate a lot of motion, but are unlikely to generate much impact. Once you’re aware of these combinations, you can start to see what sort of techniques are adopted by folks working on similar problems, but the awareness also helps you start to build a model for creating quality across various circumstances.</p> <h2 id="is-tolerance-for-error-an-important-dimension">Is tolerance for error an important dimension?</h2> <p>Before developing a model for reasoning about creating quality, a few comments on “tolerance for error.” I think many people would argue that your tolerance for error is an important dimension in determining your approach to creating quality, but to be honest I haven’t found that a useful dimension.</p> <p>For example, if you tell me that you highly prioritize quality at your company, and that’s why you have a very large quality assurance organization, or a very formal verification process, my first response would be skepticism. Quality assurance teams are extremely useful in many scenarios. Formal verification processes are also very useful in many scenarios. However, neither is universally ideal, and both can be done poorly.</p> <p>In my personal experience, the highest quality organizations are those with detail oriented <a href="https://lethain.com/inspection/">executives who actively inspect</a> quality in their teams’ work. That executive-driven inspection elevates quality into first-tier work done by their leadership, and so on down the chain. In those organizations, there are often teams that build quality assurance tools, but those teams support quality rather than being directly accountable for it.</p> <p>Others’ personal experiences will be the opposite, and that’s entirely the point: I’ve seen low tolerance for error drive a wide variety of different approaches. Similarly, I’ve seen organizations with a high tolerance for errors both go heavy on quality assurance and heavy on engineer-led quality. As such, I don’t think this is an important dimension when reasoning about creating quality.</p> <h2 id="iterating-on-a-model">Iterating on a model</h2> <p>My model of creating quality started as a <a href="https://lethain.com/modeling-reliability/">model for reliability</a>.</p> <p><img src="https://lethain.com/static/blog/2019/reliability-diagram-9.png" alt="Mental model for creating reliable systems."></p> <p>There&rsquo;s a lot to like about this model, I think the idea of &ldquo;latent incidents&rdquo; is a particularly useful one, because it acknowledges that even if you improve your quality practices, it may take a very long time to drain the backlog of latent incidents such that you actually feel like you&rsquo;ve improved quality. I imagine many teams actually solve their quality problem but accidentally abandon their successful approach before they drain the backlog and realize they&rsquo;ve solved it.</p> <p>I made the above model at a period when I was almost entirely focused on accidental complexity from a sprawling codebase and scaling complexity from an increasingly large volume of concurrent usage. Because of that focus, I spent too little time thinking about the third source of complexity, essential domain complexity.</p> <p>What I&rsquo;d like to do here is to develop a model that incorporates both the insights of my prior model <em>and</em> also the fact that essential domain complexity has been the largest source of quality issues in my current and prior roles at Carta and Calm.</p> <p>I think it&rsquo;s useful to start with the smallest possible loop for iterating on software, the <a href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">Read Eval Print Loop</a> (aka REPL), first popularized in 1964.</p> <p><img src="https://lethain.com/static/blog/2024/repl.png" alt="Diagram of the classic Read, Evaluate, Print loop"></p> <p>Not much modern development is done directly in a REPL, but developer-led testing provides a very similar loop, with a single developer looping from writing a piece of code, to writing tests for that code, to running the tests, to addressing the feedback raised by those tests.</p> <p><img src="https://lethain.com/static/blog/2024/code-loop.png" alt="Diagram of the writing code, writing tests for code, then reviewing output from tests"></p> <p>Now let&rsquo;s try to introduce the fact that this tight iteration loop is just one phase of shipping software. After writing software, we also need to release that software into production. After all, as Steve Jobs said, real artists ship!</p> <p><img src="https://lethain.com/static/blog/2024/dev-release-loop.png" alt="Diagram of software engineer writing code and then following a release process to release that code."></p> <p>In particular, it&rsquo;s worth noticing the loops that occur within one node versus the loops that occur across nodes. It&rsquo;s significantly faster to iterate within a node than it is to iterate across nodes.</p> <p>While we&rsquo;re starting to get a bit closer, but we&rsquo;re missing a few key things here to reason about the quality of our code. First, even after releasing code, there can be a defect rate where the implementation doesn&rsquo;t wholly solve the domain&rsquo;s essential complexity, such that there is a latent defect. Alternatively, there might be an emergent issue in production caused by either accidental complexity (e.g. sloppy environment setup) or scaling complexity (e.g. unexpected traffic spike).</p> <p>Second, sometimes engineers don&rsquo;t understand the feature they&rsquo;re trying to implement, even when they&rsquo;re trying hard to do so. This might be because they&rsquo;re new to the team and it&rsquo;s a complex problem space. Or it might be because they had a miscommunication with their product manager, who is responsible for defining the required functionality.</p> <p><img src="https://lethain.com/static/blog/2024/prod-soft-deploy-loop.png" alt="Diagram of development loop include defining feature requirements and latent errors."></p> <p>This model starts to get interesting! The first thing to note is just how delayed the feedback is from writing software to rewriting software if that feedback requires releasing the software. If the handoff of specification from product to engineer goes awry, it may take weeks to detect the issue. This is even more profound in &ldquo;high cardinality&rdquo; problem domains where there&rsquo;s a great deal of divergence in user usage and user data: it may take months or quarters for the feedback to reach the developer about something they did wrong, at which point they&ndash;at best&ndash;have forgotten much of their original intentions.</p> <p>Like any good model, you can iterate on it endlessly to capture the details that are most interesting for your situation:</p> <ul> <li>If you&rsquo;re mostly focused on scalability complexity, then the release process is likely particularly interesting for you.</li> <li>If you&rsquo;re focused on accidental complexity, then proactive and reactive controls on software design&ndash;mechanisms that gate access to and departure from the software development cluster&ndash;would be the most interesting such as <a href="https://lethain.com/scaling-consistency/">architecture reviews</a> or <a href="https://lethain.com/reclaim-unreasonable-software/">verifying properties</a> within pull requests before merging them.</li> <li>If you&rsquo;re focused on essential domain complexity, then you&rsquo;re focused on either feature specification or the software development feedback loop. Techniques to address might vary from embedding new hires onto teams with high context to requiring pull requests be reviewed by a domain expert, to developming a comprehensive test harness that makes it easy for developers to test new functionality against the full spectrum of unusual scenarios.</li> </ul> <p>The best way to get a feel for any model is to experiment with it. Delete pieces that aren&rsquo;t interesitng to you, add pieces that seem to be missing from your perspective, and see what it teaches out.</p> <h2 id="measurement-contributes-to--creates-quality">Measurement contributes to (!= creates) quality</h2> <p>One important observation from this model is that errors detected in production, or even in release, are much harder to address effectively than errors detected by the engineer writing the software initially. I think of detecting errors after the software engineer handoff primarily as <em>measuring quality</em> rather than <em>creating quality</em>. My reason for this distinction is that any improvement from this measurement occurs in a later iteration of the loop, as opposed to within the current loop.</p> <p>I think this is an important distinction because it provides the vocabulary to discuss the role of software engineering teams and the role of quality assurance (QA) teams.</p> <p>Software engineering teams write software to address problem domain and scaling complexity. Done effectively, developer-led testing happens within the small, local development loop, such that there&rsquo;s no delay and no coordination overhead separating implemention and verification In that way, developer-led testing directly contributes to quality in the stage that it&rsquo;s written.</p> <p>QA teams write software (or run manual processes) to measure the quality of that software in the problem domain. QA-led testing happens in a distinct step, even if that step occurs concurrently, and as such the software&rsquo;s initial design is not influenced by QA tests. That influences only occurs when the quality loop next repeats.</p> <p>This is an important distinction, because the later in development an issue is detected, the more likely it is that it&rsquo;s addressed tactically rather than structurally. Quality issues detected late are more likely to drive improvement in specific correctness (fix the test case) rather than in fundamental approach (redesign the architecture). It also doesn&rsquo;t mean that QA-led testing isn&rsquo;t valuable, it&rsquo;s very valuable for managing the sort of cross-feature bugs that an engineer with narrow context would not know to test for, but it does mean that developer-led testing of their current work creates quality sooner and in ways that QA-led testing does not.</p> <p>Trying to ground this observation in something specific, think about John Ousterhout&rsquo;s idea of defining errors out of existence from <em><a href="https://www.amazon.com/Philosophy-Software-Design-2nd-ebook/dp/B09B8LFKQL/">Philosophy of Software Design</a></em>. That principle argues that you can eliminate many potential software errors by designing interfaces which prevent the error from occuring. For example, instead of throwing an error when I attempt to delete a non-existent file, it might simply confirm the file does not exist. QA-led testing might ensure that the function throws the error only at the correct times, but it would only be developer-led design (potentially including developer-led testing or dogfooding) that would allow the quick iteration loop that supports changing the interface entirely to define that error out of existence.</p> <hr> <p>As an aside, this is more-or-less the same point I tried to make in <a href="https://github.com/readme/guides/incident-response">my contribution to GitHub ReadME</a>, but there I was focused on incident response. Measuring prior incidents and instances of incident response are an <em>input</em> to improving future incident response, but do not directly improve reliability: only finishing projects that increase reliability does that, and investing more into measurement when you aren&rsquo;t completing any projects doesn&rsquo;t solve anything.</p> <h2 id="what-should-you-do">What should you do?</h2> <p>The intended takeaway from all this is exactly where we started in the introduction: creating quality is context specific. Be wary of following the playbook you&rsquo;ve seen before, even if those playbook were tremendously successful. They might work extremely well, but they often don&rsquo;t unless you have a useful model for reasoning about why they worked in the former environment.</p> <h2 id="related-materials">Related materials</h2> <p>Throughout this piece, I&rsquo;ve tried to explain and references ideas as I&rsquo;ve invoked them, but here are some of the materials that might be worth reading through if this is an interesting topic to you:</p> <ul> <li>“Define errors out of existence” is an idea from John Ousterhout’s <em><a href="https://www.amazon.com/Philosophy-Software-Design-2nd-ebook/dp/B09B8LFKQL/">Philosophy of Software Design</a></em>, and described with some great examples in <a href="https://wiki.tcl-lang.org/page/Define+Errors+Out+of+Existence">this page from the TCL Lang wiki</a></li> <li>The distinction between essential and accidental complexity, discussed in Fred Brooks&rsquo; <a href="https://en.wikipedia.org/wiki/No_Silver_Bullet">No Silver Bullet</a> from <em><a href="https://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959">Mythical Man Month</a></em> is a valuable dimension for reasoning about complexity (and consequently, quality)</li> <li><a href="https://increment.com/apis/api-design-for-eager-discerning-developers/">Eagerly discerning, discerningly eager</a> is a great piece from Michelle Bu that discusses how API design is distinct from many other sorts of product design (e.g. can&rsquo;t use A/B testing, but can work with other companies as design partners)</li> <li>Kent Beck&rsquo;s <em><a href="https://www.amazon.com/Tidy-First-Personal-Exercise-Empirical/dp/1098151240">Tidy First?</a></em> discusses a number of strategies for addressing accidental quality issues within a codebase, mostly those caused by inconsistent implementations across a large codebase. I <a href="https://lethain.com/notes-on-tidy-first/">wrote up some notes on this book</a> a while back</li> <li><a href="https://lethain.com/reclaim-unreasonable-software/">Reclaim unreasonable software</a> captures my thinking about creating quality in a codebase that has become challenging to reason about. In this piece&rsquo;s vocabulary, it&rsquo;s most interested in solving accidental and scaling complexity</li> <li><a href="https://staffeng.com/guides/manage-technical-quality/">Manage technical quality</a> is a chapter from <em>Staff Engineer</em> which describes many of the tools you can use to improve quality. Most of the discussion here is composition-agnostic, e.g. useful techniques that might or might not apply to various compositions, and certainly you can use the quality model to evaluate which might apply well for your circumstances</li> <li><em><a href="https://www.amazon.com/Domain-Driven-Design-Distilled-Vaughn-Vernon/dp/0134434420">Domain-Driven Design Distilled</a></em> by Vaughn Vernon is a good overview of domain-driven design, which is an approach to software development that applies particularly well to working in problem domains with high essential complexity</li> <li><em><a href="https://www.amazon.com/Practical-TLA-Planning-Driven-Development/dp/1484238281">Practical TLA+</a></em> by Hillel Wayne is a useful introduction to formal specification, which is a topic that not many software engineers spend time thinking about, but an interesting one nonetheless</li> <li><em><a href="https://www.amazon.com/Building-Evolutionary-Architectures-Automated-Governance-dp-1492097543/dp/1492097543/">Building Evolutionary Architectures</a></em> by Ford, Parsons, Kua and Sadalage has a number of ideas about guided evolution of codebases (here are <a href="https://lethain.com/building-evolutionary-architectures/">my notes on the 1st edition</a>). Generally composition-agnostic in their recommendations</li> </ul> <p>These are all well worth your time.</p>Video of Using LLMs in your product.https://lethain.com/video-mental-model-for-how-to-use-llms-in-products/Fri, 14 Jun 2024 07:00:00 -0700https://lethain.com/video-mental-model-for-how-to-use-llms-in-products/<p>A month ago, I wrote up some notes on <a href="https://lethain.com/mental-model-for-how-to-use-llms-in-products/">using LLMs in your product</a>, and yesterday I got to present an iteration on those notes to the folks at the Sapphire Venture&rsquo;s <a href="https://events.sapphireventures.com/hypergrowthengineeringsummit24/">2024 Hypergrowth Engineering Summit</a>.</p> <iframe width="560" height="315" src="https://www.youtube.com/embed/EVPY9koFceU?si=nACUFx02cS7hC8nZ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> <p>If you&rsquo;re interested, you can watch <a href="https://youtu.be/EVPY9koFceU">a recording of my talk on Youtube</a>. There&rsquo;s a lot of overlap with the notes, but I also go into Carta&rsquo;s approach thus-far to incorporating LLMs into our product. (Note that it&rsquo;s a recording of a practice run I did earlier in the week, not a recording from the venue itself, so it&rsquo;s definitely amateur quality but the content is still all there!)</p>No Wrong Doors.https://lethain.com/no-wrong-doors/Wed, 22 May 2024 16:00:00 -0700https://lethain.com/no-wrong-doors/<p>Some governmental agencies have started to <a href="https://nwd.acl.gov/our-initiatives.html">adopt No Wrong Door policies</a>, which aim to provide help–often health or mental health services–to individuals even if they show up to the wrong agency to request help. The core insight is that the employees at those agencies are far better equipped to navigate their own bureaucracies than an individual who knows nothing about the bureaucracy’s internal function.</p> <p>For the most part, technology organizations are not complex bureaucracies, but sometimes they do seem to operate that way. A particularly common pattern is along the lines of:</p> <ul> <li><strong>Product Engineer joins #observability</strong></li> <li><strong>Product Engineer</strong>: Hey, I’m having trouble with alerts, can you help me with that?</li> <li><strong>Obs Engineer</strong>: Oh yeah, for sure, what alerts?</li> <li><strong>Product Engineer</strong>: Ok, so there at this Datadog link…</li> <li><strong>Obs Engineer</strong>: Got it. Yeah, so that’s in the SRE Obs team now. We do observability for the product analytics data lake, not production observability.</li> <li><strong>Obs Engineer</strong>: Ok. Yeah, good. Let me find SRE Obs</li> <li><strong>Product Engineer joins #sre-obs</strong></li> <li><strong>Product Engineer</strong>: Hi, I got steered here by #observability, I think this is where I can get help with issues like Datadog link…</li> <li><strong>SRE Engineer</strong>: Oh, absolutely. That looks misconfigured. Where is your app completed Observability Checklist and when did you review it with us?</li> <li><strong>Product Engineer</strong>: …how would I know that?</li> </ul> <p>In that example, the product engineer is first forced to navigate the unintuitive organizational design to find the right team for questions about Datadog. After they find the right team, they are forced to figure out how the SRE Observability team records when a checklist is completed. In almost all cases, the product engineer ends up frustrated, but it’s not just them. Almost every time, the observability engineer and SRE engineer also probably feel frustrated that the product engineer didn’t know enough to navigate their bureaucracy successfully.</p> <p>Something I’ve been thinking about recently is how engineering organizations can adopt a variant of the No Wrong Doors policy to directly connect folks with problems with the right team and information. Then the first contact point becomes a support system for navigating the bureaucracy successfully.</p> <p>For example, imagine if this had happened instead:</p> <ul> <li><strong>Product Engineer joins #observability</strong></li> <li><strong>Product Engineer</strong>: Hey, I’m having trouble with alerts, can you help me with that?</li> <li><strong>Obs Engineer</strong>: Oh yeah, for sure, what alerts?</li> <li><strong>Product Engineer</strong>: Ok, so there at this Datadog link…</li> <li><strong>Obs Engineer</strong>: Got it. Yeah, let me start a thread in #sre-obs to help get this sorted</li> <li><strong>Product Engineer joins #sre-obs</strong></li> <li><strong>Obs Engineer</strong>: Hey all, Product Engineer is having trouble with Datadog (see link here). Product Engineer: if you look into this spreadsheet you can find the Observability Checklist entry for your app to add to this thread to help with debugging</li> <li><strong>SRE Engineer</strong>: OK, so..</li> </ul> <p>Now the product engineer gets support from the same two folks as before, but because they’re helping the product engineer navigate the process, they get to a better situation.</p> <p>Beyond being helpful to your colleagues, which is an obvious goal in some companies and not-at-all a cultural priority in others, I think there are a number of other advantages to think about here. First, being helpful creates positive relationships across organizations. Second, it makes it more obvious where you do have genuine areas of ambiguous ownership, and makes it possible for informed parties to escalate that rather than relying on folks with the least context to know to escalate the ambiguities. Third, it educates folks asking for help about the right thing to do, because a knowledgeable person helping is a great role model of the best way to solve a problem. Finally, if you happen to route to the wrong person–it happens!&ndash;then you learn that immediately rather than forcing someone without context to navigate the confusion.</p> <p>The most effective mechanism I’ve found for rolling out No Wrong Door is initiating three-way conversations when asked questions. If someone direct messages me a question, then I will start a thread with the question asker, myself, and the person I believe is the correct recipient for the question. This is particularly effective because it’s a viral approach: rolling out No Wrong Door just requires any one of the three participants to adopt the approach. Even the question asker can do it, although the power dynamics of the interaction do make it a bit harder for them.</p>Making engineering strategies more readablehttps://lethain.com/readable-engineering-strategy-documents/Sat, 18 May 2024 04:00:00 -0700https://lethain.com/readable-engineering-strategy-documents/<p>As discussed in <a href="https://lethain.com/components-of-eng-strategy/">Components of engineering strategy</a>, a complete engineering strategy has five components: explore, diagnose, refine (map &amp; model), policy, and operation. However, it&rsquo;s actually quite challenging to read a strategy document written that way. That&rsquo;s an effective sequence for <em>creating</em> a strategy, but it&rsquo;s a challenging sequence for those trying to quickly <em>read and apply</em> a strategy without necessarily wanting to understand the complete thinking behind each decision.</p> <p>This post covers:</p> <ul> <li>Why the order for writing strategy is hard to reading strategy</li> <li>How to organize a strategy document for reading</li> <li>How to refactor and merge components for improved readability</li> <li>Additional tips for effective strategy documents</li> </ul> <p>After reading it, you should be able to take a written strategy and rework it into a version that&rsquo;s much easier for others to read.</p> <hr> <p><em>This is an exploratory, draft chapter for a book on engineering strategy that I&rsquo;m brainstorming in <a href="https://lethain.com/tags/eng-strategy-book/">#eng-strategy-book</a>.</em> <em>As such, some of the links go to other draft chapters, both published drafts and very early, unpublished drafts.</em></p> <h2 id="why-writing-structure-inhibits-reading">Why writing structure inhibits reading</h2> <p>Most software engineers learn to structure documents early in their lives as students writing academic essays. Academic essays are focused on presenting evidence to support a clear thesis, and generally build forward towards their conclusion. Some business consultancies explicitly train their new hires in business writing, such as McKinsey teaching Barbara Minto&rsquo;s <em><a href="https://www.amazon.com/Pyramid-Principle-Logic-Writing-Thinking/dp/0273710516">The Pyramid Principle</a></em>, but that&rsquo;s the exception.</p> <p>While academic essays want to develop an argument, professional writing is a bit different. Professional writing typically has one of three distinct goals:</p> <ul> <li><strong>Refining thinking about a given approach</strong> (&ldquo;how do we select databases for our new products?&rdquo;) &ndash; this is an area where the academic structure can be useful, because it focuses on the thinking behind the proposal rather than the proposal itself</li> <li><strong>Seeking approval from stakeholders or executives</strong> (&ldquo;what database have we selected for our new analytics product?&rdquo;) &ndash; this is an area where the academic structure creates a great deal of confusion, because it focuses on the thinking rather than the specific proposal, but the stakeholders view the specific proposal are the primary topic to review</li> <li><strong>Communicating a policy to your organization</strong> (&ldquo;databases allowed for new products&rdquo;) &ndash; helping engineers at your company understand the permitted options for a given problem, and also explaining the rationale behind the decision for the subset who may want to undrstand or challenge the current policy</li> </ul> <p>The ideal format for the first case is generally at odds with the other two, which is a frequent cause of strategy documents which struggle to graduate from brainstorm to policy. I find that most strategy writers are resistent to the idea that it&rsquo;s worth their time to restructure their initial documents, so let me expand on challenges I&rsquo;ve encountered when I&rsquo;ve personally tried to make progress without restructuring:</p> <ul> <li> <p><strong>Too long, didn&rsquo;t read.</strong> Thinking-orienting structures leave policy recommendations at the very bottom, but the vast majority of strategy readers are simply trying to understand that policy so they can apply it to their specific problem at hand. Many of those readers, in my experience a majority of them, will simply give up before reading the sections that answer their questions and assume that the document doesn&rsquo;t provide clear direction because finding that direction took too long.</p> <p>This is very much akin to the core lesson of Steve Krug&rsquo;s <a href="https://www.amazon.com/Dont-Make-Think-Revisited-Usability/dp/0321965515">Don&rsquo;t Make Me Think</a>: users (and readers) don&rsquo;t understand, they muddle through. Assuming that they will take the time to deeply understand is an act of hubris.</p> </li> <li> <p><strong>Approval meeting to nowhere.</strong> There are roughly three types of approval meetings. The first, you go in and no one has any feedback. Maybe someone gripes that it could have been done asynchrously instead of a meeting, but your docuemnt is approved. The second, the are two sets of stakeholders with incompatible goals, and you need a senior decision-maker to mediate between them. This is a very useful meeting, because you generally can&rsquo;t make progress without that senior decision-maker breaking the tie.</p> <p>The third sort of meeting is when you get derailed early with questions about the research, whether you&rsquo;d considered another option, and whether this is even relevant. You might think this is because your strategy is wrong, but in my experience it&rsquo;s usually because you failed to structure the document to present the policy upfront. Stakeholders might disagree with many elements of your thinking but still agree with your ultimate policy, but it&rsquo;s only useful to dig into your rationale if they actually disagree with the policy itself. Avoid getting stuck debating details when you agree on the overarching approach by presenting the policy <em>first</em>, and only digging into those details when there&rsquo;s disagreement.</p> </li> <li> <p><strong>Transient alignment.</strong> Sometimes you&rsquo;ll see two distinct strategy documents, with the first covering the full thinking, and the second only including the policy and operations sections. This tends to work quite well initially, but over time existing members of the team depart and new members are hired. At some point, a new member will challenge the thinking behind the strategy as obviously wrong, generally because it&rsquo;s a different set of policies than they used at the previous employer. If you omit the diagnosis and exploration sections entirely, then they can&rsquo;t trace through the decision making to understand the reasoning, which will often cause them to leap to simplistic conclusions like the ever popular, &ldquo;I guess the previous engineers here were just dumb.&rdquo;</p> </li> </ul> <p>As annoying as each of these challenges is, the solution is simple: use the writing structure for writing, and invert that structure for reading.</p> <h2 id="invert-structure-for-reading">Invert structure for reading</h2> <p>Reiterating a point from <a href="https://lethain.com/components-of-eng-strategy/">Components of engineering strategy</a>: it&rsquo;s always appropriate to change the structure that you use to develop or present a strategy, as long as you are making a deliberate, informed decision.</p> <p>While I&rsquo;ve generally found explore, diagnose, refine, policy, and operation to work well for writing policy, I&rsquo;ve consistently found it a poor format for presenting strategy. Whether I&rsquo;m presenting a strategy for review or rolling the strategy out to be followed by the wider organizaton, I recommend an inverted structure:</p> <ul> <li><strong>Policy</strong>: what does the strategy require or allow?</li> <li><strong>Operation</strong>: how is the strategy enforced and carried out, how do I get exceptions for the policy?</li> <li><strong>Refine</strong>: what were the load-bearing details that informed the strategy?</li> <li><strong>Diagnose</strong>: what are the more generalized trends and observations that steered the thinking?</li> <li><strong>Explore</strong>: what is the high-level, wide-ranging context that we brought into creating this strategy?</li> </ul> <p>When seeking approval, you&rsquo;ll probably focus on the <strong>Policy</strong> section. When rolling it out to your organization, you&rsquo;ll probably focus on the <strong>Operation</strong> section more. In both cases, those are the critical components and you want them upfront. Very few strategy readers want to understand the full thinking behind your strategy, instead they just want to understand how it impacts the specific decision they are trying to answer.</p> <p>The vast majority of strategy readers want the answer, not to understand the thinking behind the answer, and these are your least motivated readers. Someone who wants to really understand the thinking will invest time reading through the document, even if it isn&rsquo;t perfectly structured for them. Someone who just wants an answer will frequently give up and make up an answer rather than reading all the way through to where the document does infact answer their question.</p> <p>Zooming out a bit, this is a classic &ldquo;lack of user empathy&rdquo; problem. Folks authoring the document are so deep in the details that they can&rsquo;t put themselves in the readers&rsquo; mindset to think about how overwhelming the document would be if you were simply trying to pop in, get an answer, and then pop out. This lack of empathy also means that most strategy writers refuse to structure their documents to support the large population of answer seekers over the tiny population of strategy authors, but just try it a few times and I think you&rsquo;ll see it helps a great deal. Even faster, go read someone else&rsquo;s strategy document that you aren&rsquo;t familiar with, and you&rsquo;ll quickly appreciate how challenging it can be to identify the actual proposal if they follow the academic structure.</p> <h2 id="strategy-refactoring">Strategy refactoring</h2> <p>Inverting the structure is the first step of optimizing a document for readability, but you don&rsquo;t have to stop there. Often you&rsquo;ll find that even the inverted strategy structure is somewhat confusing to read for a given document. I think of this process as &ldquo;strategy refactoring.&rdquo;</p> <p>For example, <a href="https://lethain.com/llm-adoption-strategy/">How should you adopt LLMs?</a> makes two refactors to the inverted format. First, it merges <em>Refine</em> into <em>Diagnose</em>, which keeps the map and models closer to the specific topics thet explore. Second, it discards the <em>Operation</em> sectiom entirely, and includes the relevant details with the policies they apply to in the <em>Policy</em> section.</p> <p>Strategy refactoring is about discarding structure where it interferes with usability. The strategy structure is very effective at separating concerns while reasoning through decision making, but most readers benefit more from engaging with the full implications at once. Once you&rsquo;re done thinking, refactor away the thinking tools: don&rsquo;t let the best tools for one workflow mislead you into thinking they&rsquo;re the best for an entirely different one.</p> <h2 id="additional-tips-for-effective-strategy-docs">Additional tips for effective strategy docs</h2> <p>In addition to the above advice, there are a handful of smaller tips that I&rsquo;ve found helpful for creating readable strategy documents:</p> <ul> <li>Before releasing a document widely, find someone entirely uninvolved with the strategy thus far and have them point out areas that are difficult to understand. Anyone who&rsquo;s been thinking about the strategy is going to gloss over areas that might be inscrutinable to those who are approaching it with fresh eyes.</li> <li>Every strategy document should be rolled out with an explicit commenting period where you invite discussion, as well as office hours where you are available to explain how to apply the strategy correctly. These steps help with adoption, but even more importantly they help you identify disenters who disagree with the strategy such that you can follow up to better understand their concerns.</li> <li>Every company should maintain its own internal engineering strategy template, along the lines of this book&rsquo;s <a href="https://lethain.com/engineering-strategy-template/">engineering strategy template</a>.</li> <li>Your template should include consistent metadata, particularly when it was created, the current approval status, and where to ask questions. Of these, a clear, durable place to ask questions is the most important, as it slows the rate that these documents rot.</li> <li>After you release your strategy, disable in-document commenting. This isn&rsquo;t intended to prevent further discussion, but rather to move the discussion outside of the document. Nothing creates the impression of an unapproved, unfinished strategy document faster then a long string of open comments. Open comments also make it difficult to read the strategy document, as often the reader will get distracted from reading the document to read the comments.</li> </ul> <h2 id="summary">Summary</h2> <p>After reading this chapter, you know how to escape the rigid structures imposed during the creation of a strategy to create a readable document that is easier for others to both approve and apply. Beyond initially inverting the structure for easier reading, you also understand how to refactor sections away entirely that may have been essential for creation but interfere for understanding how to apply the strategy, which is by far the most common task for strategy readers.</p> <p>Most importantly, I hope you finish this chapter agreeing that it&rsquo;s worth your time to rework your thinking-optimized draft rather than leaving it as is. The deliberate refusal to structure documents for readers is the root cause of a surprising number of good strategies that utterly fail to have their intended impact.</p>How should you adopt LLMs?https://lethain.com/llm-adoption-strategy/Tue, 14 May 2024 06:00:00 -0700https://lethain.com/llm-adoption-strategy/<p>Whether you’re a product engineer, a product manager, or an engineering executive, you’ve probably been pushed to consider using Large Language Models (LLM) to extend your product or enhance your processes. 2023-2024 is an interesting era for LLM adoption, where these capabilities have transitioned into the mainstream, with many companies worrying that they’re falling behind despite the fact that most integrations appear superficial.</p> <p>That context makes LLM adoption a great topic for a strategy case study. This document is an engineering strategy document determining how a hypothetical company, Theoretical Ride Sharing, could adopt LLMs.</p> <p>Building out the scenario a bit before diving into the strategy: Theoretical has 2,000 employees, 300 of which are software engineers. They’ve raised $400m, are doing $50m in annual revenue, and are operating in 200 cities across North America and Europe. They are a ride sharing business, similar to Uber or Lyft, but have innovated on the formula by using larger vehicles (also known as, they’ve reinvented public transit).</p> <hr> <p><em>This is an exploratory, draft chapter for a book on engineering strategy that I&rsquo;m brainstorming in <a href="https://lethain.com/tags/eng-strategy-book/">#eng-strategy-book</a>.</em> <em>As such, some of the links go to other draft chapters, both published drafts and very early, unpublished drafts.</em></p> <h2 id="reading-this-document">Reading this document</h2> <p>To apply this strategy, start at the top with <em>Policy</em>. To understand the thinking behind this strategy, read sections in reserve order, starting with <em>Explore</em>, then <em>Diagnose</em> and so on. Relative to the default structure, this document has been refactored in two ways to improve readability: first, <em>Operation</em> has been folded into <em>Policy</em>; second, <em>Refine</em> has been embedded in <em>Diagnose</em>.</p> <p>More detail on this structure in <a href="https://lethain.com/readable-engineering-strategy-documents">Making a readable Engineering Strategy document</a>.</p> <h2 id="policy">Policy</h2> <p>Our combined policy for using LLMs at Theoretical Ride Sharing are:</p> <ul> <li> <p><strong>Develop an LLM-backed process for verifying <em>I-9</em> and <em>US Driver License</em> documents such that we can wholly automate driver onboarding in the United States.</strong> Moving from an average onboarding delay of seven days to near-instant onboarding will increase driver supply and allow us to reprioritize the team on servicing rider complaints, which are a major source of concern.</p> <p>Verifying <em>I-9 Forms</em> and <em>US Drivers Licenses</em> will be directly useful for accelerating onboarding, and also establish the framework for us to perform document extraction on in other jurisdictions outside the US to the extent that this experiment outperforms our current hybrid automation/services model for onboarding.</p> <p>Report on progress monthly in <em>Exec Weekly Meeting</em>, coordinated in #exec-weekly</p> </li> <li> <p><strong>Start with Anthropic.</strong> We use Anthropic models, which are available through our existing cloud provider via <a href="https://aws.amazon.com/bedrock/">AWS Bedrock</a>. To avoid maintain multiple implementations, where we view the underlying foundational model quality to be somewhat undifferentiated, we are not looking to adopt a broad set of LLMs at this point.</p> <p>Exceptions will be reviewed by the <em>Machine Learning Review</em> in #ml-review</p> </li> <li> <p><strong>Developer experience team (DX) must offer at least one LLM-backed developer productivity tool.</strong> This tool should enhance the experience, speed, or quality of writing software in TypeScript. This tool should help us develop our thinking for next year, such that we have conviction increasing (or decreasing!) our investment. This tool should be available to all engineers. Adopting one tool is the required baseline, if DX identifies further interesting tools, e.g. Github Copilot, they are empowered to bring the request to the <em>Engineering Exec</em> team for review. Review will focus on balancing our rate of learning, vendor cost, and data security. We&rsquo;ve <a href="https://lethain.com/dx-llm-model/">modeled options for measuring LLMs impact on developer experience</a>.</p> <p>Vendor approvals to be reviewed in #cto</p> </li> <li> <p><strong>Internal Toolings team (INT) must offer at least one LLM-backed ad-hoc prompting tool.</strong> This tool should support arbitrary non-engineering use cases for LLMs, such as text extraction, rewriting notes, and so on. It must be usable with customer data while also honoring our existing data processing commitments. This tool should be available to all employees.</p> <p>Vendor approvals to be reviewed in #coo</p> </li> <li> <p><strong>Refresh policy in six months.</strong> Our foremost goal is to learn as quickly as possible about a new domain where we have limited internal expertise, then review whether we should increase our investment afterwards.</p> <p>Flag questions and suggestions in #cto</p> </li> </ul> <h2 id="diagnose">Diagnose</h2> <p>The synthesis of the problem at hand regarding how we use LLMs at Theoretical Ride Sharing is:</p> <ol> <li> <p>There are, at minimum, <strong>three distinct needs</strong> that folks internally are asking us to solve (either separately or with a shared solution):</p> <ol> <li><em>productivity tooling for non-engineers</em>, e.g. ad-hoc document rewriting,document summarization</li> <li><em>productivity tooling for engineers</em>, e.g. advanced autocomplete tooling like Github Copilot</li> <li><em>product extensions</em>, e.g. high-quality document extraction in driver onboarding workflows</li> </ol> </li> <li> <p>Of the above, <strong>we see product extensions are potential strategic differentiation</strong>, and the other two as workflow optimizations that improve our productivity but don’t necessarily differentiate us from wider industry. Some of the opportunities for strategic differentiation we see are:</p> <ol> <li><em>Faster driver onboarding</em> by processing driver documentation without human involvement, making it possible to bring new driver supply online more quickly, particularly as we move into new regions. We&rsquo;ve sized the potential impact by <a href="https://lethain.com/driver-onboarding-model/">developing a model of faster driver onboarding</a></li> <li><em>Improved customer support</em> by increasing the response speed and quality of our responses to customer inquiries</li> </ol> </li> <li> <p><strong>We currently have limited experience or expertise in using LLMs in the company and in the industry.</strong> Prolific thought leadership to the contrary, there are very few companies or products using LLMs in scaled, differentiated ways. That’s currently true for us as well</p> </li> <li> <p><strong>We want to develop our expertise without making an irreversible commitment.</strong> We think that our internal expertise is a limiter for effective problem selection and utilization of LLMs, and that developing our expertise will help us become more effective in iterative future decisions on this topic. Conversely, we believe that making a major investment now, prior to developing our in-house expertise, would be relatively high risk and low reward given no other industry players appear to have identified a meaningful advantage at this point</p> </li> <li> <p><strong>Switching across foundational models and foundational model providers is cheap</strong>. This is true both economically (low financial commitment) and from an integration cost perspective (APIs and usage is largely consistent across providers)</p> </li> <li> <p><strong>Foundational models and providers are evolving rapidly, and it’s unclear how the space will evolve.</strong> It’s likely that current foundational model providers will train one or two additional generations of foundational models with larger datasets, but at some point they will become cost prohibitive to train (e.g. the next major version of OpenAI or Anthropic models seem likely to cost $500m+ to train). Differentiation might move into developer-experience at that point. Open source models like LLaMa might become significantly cost-advantaged. Or something else entirely. The future is wide open.</p> <p>We&rsquo;ve built a Wardley map to understand the <a href="https://lethain.com/wardley-llm-ecosystem/">possible evolution of the foundational model ecosystem</a>.</p> </li> <li> <p><strong>Training a foundational model is prohibitively expensive for our needs.</strong> We’ve raised $400m, and training a competitive foundational model would cost somewhere between $3m to $100m to match the general models provided by Anthropic or OpenAI</p> </li> </ol> <h2 id="explore">Explore</h2> <p>Large Language Models operate on top of a foundational model. Training these foundational models is exceptionally expensive, and growing more expensive over time as competition for more sophisticated models accelerates. <a href="https://www.cnbc.com/2023/10/16/metas-open-source-approach-to-ai-puzzles-wall-street-techies-love-it.html">Meta allegedly spent $20-30m training LLaMa 2</a>, up from about $3m training costs for LLaMa 1. OpenAI’s GPT-4 <a href="https://www.wired.com/story/openai-ceo-sam-altman-the-age-of-giant-ai-models-is-already-over/">allegedly cost $100m to train</a>. With some nuance related to the quality of corpus and its relevance to the task at hand, <a href="https://arxiv.org/abs/2309.16583">larger models outperform smaller models</a>, so there’s not much incentive to train a smaller foundational model unless you have a large, unique dataset to train against, and even in that case you might be better off fine-tuning or in-context learning (ICL).</p> <p><a href="https://www.anthropic.com/api">Anthropic charges</a> between $0.25 and $15 per million tokens of input, and a bit more for output tokens. <a href="https://openai.com/api/pricing">OpenAI charges</a> between $0.50 and $60 per million tokens of input, and a bit more for output tokens. The average English word is about 1.3 tokens, which means you can do a significant amount of LLM work while spending less than most venture funded startups spend on snacks.</p> <p>There’s <a href="https://garymarcus.substack.com/p/evidence-that-llms-are-reaching-a">significant debate on whether LLMs have reached a point where their performance improvements will slow</a>. Much like the ongoing debate around whether Moore’s Law has died, it’s unclear how much LLM performance will improving going forward. From a cost to train perspective, it’s unlikely that companies can continue to improve foundational models merely by spending more money on compute. A few companies can tolerate a $1B training cost, fewer still a $10B training cost, but it’s hard to imagine a world where any companies are building $100B models. However, algorithmic improvements and investment in datasets may well drive improvements without driving up compute costs. The only high confidence prediction you can make in this space is that it’s likely model improvement will double one or two more times over the next 3 years, after which it <em>might</em> continue doubling at that rate or it <em>might</em> plateau at that level of performance: either outcome is plausible.</p> <p>For some decisions, there’s a strategic imperative to get it right from the beginning. For example, migrating from AWS to Azure is very expensive due to the degree of customization and lock-in. However, LLMs don’t appear to be in this category. Talking with industry peers, the majority of companies are experimenting with a variety of models from Anthropic, OpenAI and elsewhere (e.g. <a href="https://mistral.ai/">Mistral</a>). Behaviors do vary across models, but it’s also true that behavior of existing models varies over time (e.g. <a href="https://arstechnica.com/information-technology/2023/12/is-chatgpt-becoming-lazier-because-its-december-people-run-tests-to-find-out/">GPT 3.5 allegedly got “lazier” over time</a>), which means the overhead of dealing with model differences is unavoidable even if you only adopt one. Altogether, vendor lock-in for models is very low from a technical perspective, although there is some lock-in created by regulatory overhead, for example it’s potentially painful to update your Data Processing Agreement multiple times, combined with the notification delay, to support multiple model vendors.</p> <p>Although there’s an ongoing investment boom in artificial intelligence, most scaled technology companies are still looking for ways to leverage these capabilities beyond the obvious, widespread practices like adopting <a href="https://github.com/features/copilot">Github Copilot</a>. For example, <a href="https://podcasts.apple.com/us/podcast/build-ai-products-at-on-ai-companies-with-emily/id1668002688?i=1000644619725">Stripe is investing heavily in LLMs for internal productivity</a>, including presumably relying on them to perform some internal tasks that would have previously been performed by an employee such as verifying a company’s website matches details the company supplied in their onboarding application, but it’s less clear that they have yet found an approach to meaningfully shift their product, or their product’s user experience, using LLMs.</p> <p>Looking at ridesharing companies more specifically, there don’t appear to be any breakout industry-specific approaches either. Uber is similarly adopting LLMs for internal productivity, and some operational efficiency improvements as documented in their <a href="https://www.uber.com/blog/the-transformative-power-of-generative-ai/">August, 2023 post describing their internal developer and operations productivity investments using LLMs</a> and <a href="https://www.uber.com/blog/from-predictive-to-generative-ai/">May, 2024 post describing those efforts in more detail</a>.</p>