Pensez au projet le plus difficile sur lequel votre équipe a jamais travaillé, ou peut-être au projet que vous avez évité parce que vous le pensez impossible.
Parfois, vous ne savez pas encore ce qui sera difficile. Si vous construisez un tout nouveau produit ou une nouvelle fonctionnalité, vous ne pouvez probablement pas prédire quel sera le facteur limitant, et ce n'est pas grave - vous devriez simplement construire quelque chose et avancer à partir de là. Mais parfois, il y a une partie évidemment difficile. Peut-être que des gens ont déjà fait des tentatives qui ont révélé la partie difficile. Ou votre première version arrive en production et vous découvrez le problème une fois qu'elle est réellement utilisée.
Supposons que vous connaissiez la partie difficile et que vous n'abandonniez pas tout simplement le projet, ce que beaucoup d'équipes font malheureusement. Quelle sera votre approche face à cette partie particulièrement difficile ? À un niveau élevé, vous avez quelques options. Il y a celle où vous adoptez une approche sûre et incrémentale. Vous essayez de minimiser les risques, et de nombreuses équipes choisissent cette voie. Mais il y a probablement une raison sous-jacente pour laquelle cette approche ne fonctionnera pas en réalité. En pratique, ce que vous faites vraiment, c'est éviter la partie vraiment difficile. Vous devez donc vous demander : pouvons-nous éviter la partie difficile et réussir quand même ? Si la réponse est oui, alors évitez-la par tous les moyens. Mais si la réponse est non, alors la voie incrémentale n'est pas vraiment sûre. Vous ne faites que retarder l'échec inévitable.
Il y a une autre option où vous attaquez la partie particulièrement difficile de front, ce qui nécessite probablement de prendre un risque important et audacieux. Une de mes approches préférées pour résoudre les problèmes est de garder une chose constante et d'évaluer le reste. Dans ce cas - supposez que vous prenez le risque important et audacieux et que cela fonctionne réellement. Le reste du plan est-il solide de sorte que le projet global ait de grandes chances de succès ? Si la réponse est oui, et si vous voulez vraiment vous attaquer à ce projet et réussir, vous devez prendre ce risque.
Cela semble très simple, mais quelques éléments importants doivent être réunis pour que les équipes puissent le faire. Je vais détailler cela, mais d'abord, quelques histoires où j'ai vu cela se produire.
Une histoire : les comptes Stripe v2
Quand j'étais chez Stripe, j'ai travaillé sur Connect, où nous permettions aux plateformes d'intégrer des paiements et des services financiers. Nous pensions qu'il serait incroyablement puissant qu'une plateforme et ses utilisateurs sous-jacents puissent débloquer des avantages de réseau à travers la suite de produits Stripe. Peut-être avez-vous un utilisateur à qui vous devez facturer des frais d'abonnement (client), qui souhaite également accepter des paiements (marchand) et recevoir de l'argent (bénéficiaire). Nous pouvons supposer que cet utilisateur a un solde sur Stripe parce qu'il a accepté un paiement par carte pour quelque chose qu'il a vendu et qu'il a reçu un virement d'un autre marchand Stripe. Et il veut utiliser ce solde pour payer vos frais d'abonnement. Nous savions que cet utilisateur était le même dans tous ces contextes différents, mais nos abstractions ne permettaient pas une représentation unifiée de cet utilisateur. Nous avions v1/accounts, v1/customers, etc., donc nous ne pouvions pas vraiment débloquer cela sans une nouvelle abstraction majeure. C'était la motivation derrière les comptes v2 - une abstraction unique capable de gérer plusieurs configurations.
De nombreuses personnes et équipes avant mon arrivée chez Stripe avaient envisagé cela et avaient tenté de s'y attaquer. C'était ambitieux. Et si vous demandiez "qu'est-ce qui le rend difficile", la réponse simple est que l'ensemble des abstractions et de la logique métier de Stripe devrait apprendre à fonctionner avec un compte v2. Même si vous commenciez par une partie, comme remplacer les marchands par des comptes v2 ou les clients par des comptes v2, les surfaces étaient chacune massives, car il s'agit littéralement de chaque API et de chaque élément de logique métier dans la base de code de Stripe qui concerne les paiements ou la facturation. De plus, vous n'obtenez les avantages que nous recherchions qu'en remplaçant au moins 2 d'entre eux.
Quand j'ai commencé à travailler avec l'équipe, le plan officiel était de mettre en place la nouvelle abstraction et le nouveau modèle de données, et de les faire coexister avec les anciens, avec une synchronisation bidirectionnelle. De cette façon, la majeure partie de la logique métier de Stripe n'avait pas besoin de comprendre la nouvelle abstraction et pouvait continuer à utiliser les anciennes. Considérez cela comme la voie sûre et incrémentale, qui évitait en grande partie de résoudre la partie difficile. Le problème sous-jacent de cette voie était que la synchronisation serait fragile et que nous aurions rapidement un problème d'échelle. Si quelqu'un créait un compte v2 configuré à la fois comme marchand et comme client, nous aurions 3 modèles sous-jacents à maintenir synchronisés, chacun avec des copies des mêmes données (comme leur nom et leur email).
L'équipe a exploré de nombreuses pistes pour essayer de rendre cela viable, mais la réalité était que toutes les options évitaient le problème sous-jacent qui risquait fort de se révéler être un obstacle rédhibitoire. Nous avons réuni un petit groupe d'ingénieurs pour un séminaire où nous avons discuté de la manière de gérer cela. Nous nous sommes retrouvés à tourner autour d'une autre voie, où nous attaquerions le défi de front. Nous pourrions construire une interface qui remplacerait chaque site d'appel de lecture et d'écriture et, en fin de compte, écrirait simplement dans notre nouveau modèle de données. Nous avons appelé cela "l'encapsulation". Cela avait été suggéré par le passé, mais tout le monde l'avait ignoré en tant que solution réelle parce que cela venait avec une estimation incroyablement élevée en mois d'ingénierie (en années d'ingénierie, en réalité). Cette fois, nous avons envisagé le scénario une seconde : si nous tenions pour acquis que nous pouvions réussir l'encapsulation - le projet global serait-il un succès ? La réponse était oui. Mais c'était fou.
Beaucoup de gens évitent un tel problème à tout prix, mais d'autres sont attirés par les choses les plus difficiles. Il s'est avéré que nous avions quelques ingénieurs qui se sont vraiment passionnés pour un défi absolument insensé comme celui-ci, et nous leur avons donné les moyens de le résoudre. Nous avons envisagé plusieurs façons de mener la migration, comme répartir le travail entre toutes les équipes propriétaires des sites d'appel, mais nous avons finalement opté pour une approche centralisée et l'utilisation de codemods, car gérer autant d'équipes avec leurs propres priorités était clairement une montagne insensée à gravir. Tout au long de ce processus, j'ai travaillé avec l'équipe pour avancer malgré la possibilité très réelle que l'encapsulation devienne un goulot d'étranglement trop long, car nous en sommes vraiment venus à croire que c'était la seule voie viable.
C'était au début des années 2020, avant les agents de codage, donc l'estimation était vraiment de plusieurs années de travail d'ingénierie. Malgré des montagnes russes de défis, l'équipe a réussi. Je ne crois pas que les comptes v2 auraient pu être livrés sans cela.
Une autre histoire : les agents gérés Claude
Chez Anthropic, mon équipe a récemment publié les agents gérés Claude en version bêta, une suite d'API pour exécuter des agents. Lorsque nous avons construit notre première version, il n'était pas évident de savoir quelle serait la partie difficile, nous avons donc fait ce qu'il faut faire avec un tout nouveau produit : nous avons construit la chose la plus simple qui puisse fonctionner. L'API créait un bac à sable et démarrait Claude Code à l'intérieur, et tout ce qui concernait la session d'un agent vivait dans ce conteneur. Nous l'avons utilisé en interne, avons donné un accès anticipé à un petit groupe de clients et avons commencé à recueillir des commentaires.
Les problèmes sont apparus assez rapidement. La latence n'était pas bonne, car un conteneur devait démarrer avant que Claude puisse même commencer à réfléchir. Si le conteneur mourait, toute la session mourait avec lui, ce qui rendait la fiabilité difficile. Et nous n'aimions pas que le code écrit par Claude s'exécute juste à côté des identifiants MCP.
Pendant un certain temps, nous avons traité ces problèmes séparément et nous avons essayé de corriger chacun d'eux. L'équipe s'est améliorée pour ranimer les conteneurs défaillants et a passé de longues périodes à déboguer des sessions bloquées où l'on ne pouvait pas dire si le harnais, le flux d'événements ou le conteneur avait échoué. Finalement, nous nous sommes avoué que chacun de ces problèmes remontait au même choix : tout s'exécutait dans un seul conteneur. C'était notre problème sous-jacent. Le résoudre signifiait séparer le cerveau (la boucle du harnais) des mains (là où le code s'exécute), et cela signifiait construire un véritable système distribué, ce qui représentait une complexité significative que la conception originale évitait.
Nous étions proches d'une version bêta publique à ce stade, et retarder un lancement pour reconstruire une architecture est une décision douloureuse. Mais nous nous sommes posé la même question : pouvions-nous passer en version bêta avec l'architecture à conteneur unique et réussir quand même ? Nous savions que non. Nous avons donc retardé et effectué une réarchitecture complète. Lorsque nous avons réintégré les clients en accès anticipé, les problèmes d'identifiants et de fiabilité avaient disparu et le temps jusqu'au premier jeton avait considérablement diminué. Nous avons mis ce système en version bêta.
Peut-être aurions-nous pu prédire que la fiabilité à grande échelle serait la partie difficile que nous devrions résoudre pour réussir. Mais pour un tout nouveau produit, itérer vers la réponse était mieux que de laisser la perfection être l'ennemi du bien dès le départ. La véritable erreur aurait été de passer en version bêta quand même après avoir compris cela.
Permettre à une équipe de prendre un risque
La raison pour laquelle les équipes évitent la voie difficile est assez rationnelle. La voie difficile s'accompagne d'une estimation massive et peu fiable, et une équipe doit assumer une énorme responsabilité et un risque énorme pour s'y engager. La voie qui l'évite présente des problèmes sous-jacents qui apparaissent plus tard, d'une manière qui peut finalement faire échouer l'ensemble. Mais cette voie semble sûre et donc très tentante. Vous empruntez donc la voie sûre, parfois pendant des années, même si un certain nombre de personnes pensent qu'elle échouera mais continuent d'avancer.
Si vous voulez être une équipe qui prend un risque important et audacieux, 2 choses doivent être vraies.
Premièrement, vous avez besoin de personnes qui peuvent se passionner vraiment pour le défi. Vous n'avez pas besoin d'un consensus, et vous n'avez certainement pas besoin que tout le monde croie que cela fonctionnera. La plupart des gens regarderont la partie difficile et supposeront qu'elle est impossible, et c'est très bien. Vous avez besoin de ceux qui voient le défi le plus intéressant qu'ils aient peut-être jamais eu à relever. Donnez le problème à ces personnes et laissez-leur prendre beaucoup de responsabilités sur la façon de le résoudre.
Deuxièmement, en tant que leader, vous devez être prêt à assumer la responsabilité et à couvrir l'équipe pour qu'elle s'y attaque. Si cela ne fonctionne pas, c'est de votre faute, et il y a une série de conséquences qui peuvent en découler. Assumer ce risque nécessite que vous ressentiez personnellement 2 choses : premièrement, vous voulez vraiment que ce projet réussisse, et deuxièmement, vous croyez vraiment que ce risque important et audacieux est nécessaire.
La ligne bouge - certaines choses difficiles deviennent plus faciles qu'elles ne l'étaient. Si mon équipe chez Stripe écrivait du code avec Claude Fable, nous n'aurions peut-être pas trouvé l'encapsulation si intimidante. Ce qui se passe vraiment, c'est que l'IA nous laisse à tous les parties les plus difficiles. Donc, en réalité, la question cruciale n'a pas changé : pouvez-vous éviter la partie difficile et réussir quand même ? Si la réponse est non, la voie sûre ne fait que repousser votre échec. Si vous voulez vraiment réussir, vous devez prendre le risque.





