TL;DR : tu ne comprends vraiment un système qu'en le reconstruisant. J'ai recodé TCP à l'école, puis le protocole DNS, puis Modbus, à chaque fois pour comprendre de l'intérieur. Un collègue vient de vivre ça avec les LLM. Il a écrit un petit agent en Go, et il a enfin compris le tooling et la fenêtre de contexte. Un LLM n'est qu'un système de plus à démystifier. Reconstruis-en une version minuscule, et tu passes d'utilisateur à ingénieur.
Pour les devs qui veulent maîtriser les LLM, pas seulement les utiliser.
Un collègue, un agent en Go, un déclic
Cette semaine, j'aide un collègue à monter en compétence sur les LLM. Je lui explique les concepts. Le contexte, les tokens, les outils. Un token est un petit morceau de texte que le modèle lit et compte. Il écoute, mais quelque chose ne clique pas.
Puis il revient, tout content. Il a écrit une petite CLI en Go. Une simple boucle de chat qui appelle un modèle et exécute ses outils. Et là, il comprend. Le tooling, la fenêtre de contexte, la boucle. Pas parce que je lui ai expliqué. Parce qu'il l'a reconstruit.
Ce déclic, je le connais par cœur. Je l'ai vécu plusieurs fois, sur d'autres sujets. Toujours la même méthode. Pour comprendre un truc, je le reconstruis.
On ne comprend un système qu'en le reconstruisant
Lire une doc te donne une carte. Reconstruire te donne le terrain. Ce n'est pas pareil. La carte dit « il y a une rivière ici ». Le terrain te fait sentir le courant.
Quand tu réécris un système, tu ne peux plus tricher. Chaque octet doit être à sa place. Chaque cas limite te tombe dessus. Tu ne crois plus comprendre. Tu comprends, ou ton code ne marche pas.
Ce n'est pas un exercice d'école. C'est l'inverse. Tu reconstruis pour agir mieux ensuite. Déboguer plus vite. Détourner l'outil. Bâtir ce qu'aucune lib toute faite ne te donne.
TCP en C : la première fois
La toute première fois, c'était à l'école, en C. J'ai recodé des morceaux de TCP et d'UDP. Le fameux handshake en trois temps. Et le parsing des en-têtes, champ par champ.
TCP ouvre une connexion en trois messages. SYN, SYN-ACK, ACK. Avant, c'était une phrase dans un cours. Après, c'était des octets que je posais moi-même dans un paquet.
Je n'ai rien inventé. Le protocole existait déjà depuis quarante ans. Mais le refaire a changé ma vision du réseau. Depuis, une capture réseau n'est plus un mystère. C'est un format que j'ai déjà écrit à la main.
DNS : recoder le protocole pour détourner ses sous-domaines
Plus tard, je m'attaque au DNS. Le DNS traduit un nom comme jrobineau.com en adresse IP. Je l'ai réécrit moi-même, en Go. Le header, les questions, les réponses, octet par octet.
En le reconstruisant, tu tombes sur un détail que la doc survole. Un nom de domaine est une suite de labels. Chaque label est précédé de sa longueur. « www », c'est un 3, puis w, w, w.
Et là, une idée arrive. Si je contrôle les labels, je contrôle des octets. Je peux glisser mes propres données dans un sous-domaine. C'est le principe de l'exfiltration DNS, dans un cadre de sécurité autorisé.
Mon serveur reçoit la requête, parse le nom, et récupère les données cachées dedans. J'ai même géré la compression des noms, un coin tordu du protocole. Aucune lib clé en main ne m'aurait montré ça. Le reconstruire, si.
Modbus : reconstruire pour savoir qui a le bug
Sur une mission avec du matériel industriel, on parlait Modbus. Modbus est un vieux protocole qui pilote automates et capteurs. La lib qu'on utilisait était mauvaise. Beaucoup de bugs, beaucoup de comportements bizarres.
Impossible de savoir d'où venait le mal. Du protocole ? De la lib ? De notre code ? Alors j'ai fait la seule chose qui tranche. J'ai recodé Modbus moi-même, en Go.
Verdict : le protocole était sain. Le coupable, c'était la lib. Et une fois le protocole reconstruit, le vrai bénéfice est arrivé. Je pouvais bâtir des outils autour, à ma façon.
J'en ai tiré une petite lib Go avec une API à la Gin. Tu déclares un handler par plage de registres. Tu ajoutes des middlewares de log et de recovery. Un protocole industriel de 1979, avec le confort d'un framework web. Ça, c'est détourner la connaissance à son besoin.
Un LLM, c'est un système de plus à reconstruire
Reviens aux LLM. En 2026, on nous vend l'IA comme une magie. Une boîte noire à qui on parle. Et on reste utilisateur, un peu passif, un peu à sa merci.
Mais un agent LLM n'a rien de magique. C'est une boucle. Tu envoies des messages au modèle. Il répond, parfois en réclamant un outil. Tu exécutes l'outil. Tu renvoies le résultat. Et tu recommences.
La fenêtre de contexte, c'est tout ce que le modèle voit à cet instant. Ta boucle décide quoi mettre dedans, et quoi jeter. Le modèle ne se souvient de rien. C'est toi qui lui redonnes le passé à chaque tour.
Voici la boucle entière, en Go. Enlève le vernis, il ne reste que ça.
func runAgent(ctx context.Context, client LLM, tools map[string]Tool, goal string) (string, error) {
// La fenetre de contexte, c'est cette liste. Toi seul la remplis.
msgs := []Message{{Role: "user", Content: goal}}
for {
// 1. Tu envoies tout le contexte au modele.
reply, err := client.Complete(ctx, msgs, tools)
if err != nil {
return "", err
}
msgs = append(msgs, reply)
// 2. Pas d'outil demande ? Le modele a fini, tu sors.
if len(reply.ToolCalls) == 0 {
return reply.Content, nil
}
// 3. Tu executes chaque outil toi-meme, pas le modele.
for _, call := range reply.ToolCalls {
out := tools[call.Name].Run(ctx, call.Args)
// 4. Tu renvoies le resultat dans le contexte. On reboucle.
msgs = append(msgs, Message{Role: "tool", Content: out})
}
}
}
Une fois que tu as écrit ça, la peur tombe. Un « agent », c'est cette boucle plus quelques bons outils. Le tool calling, c'est juste le modèle qui te dit quelle fonction appeler. Rien de plus.
Reconstruire, oui, mais pas tout, pas pour toujours
Le but n'est pas de tout réécrire à vie. Je ne mets pas ma pile TCP maison en production. J'utilise celle du système, et j'ai raison de le faire.
Tu reconstruis une fois, pour comprendre. Ensuite tu fais confiance, parce que tu sais ce qu'il y a dans la boîte. C'est une confiance gagnée, pas une confiance aveugle.
Reconstruis quand l'enjeu est fort. Un protocole au cœur de ton produit. Un outil que tu vas déboguer souvent. Une techno neuve, comme les LLM, où tout le monde reste en surface. C'est là que comprendre paie.
La checklist pour apprendre une techno en la reconstruisant
La prochaine techno qui t'impressionne, ne te contente pas de l'utiliser. Reconstruis-en un bout.
- Vise le cœur, pas le confort. La boucle d'agent, pas toute l'API du fournisseur
- Fais-le en petit. Une CLI, un fichier, un après-midi suffisent souvent
- Écris le format à la main une fois. Les octets t'apprennent ce que la doc cache
- Cherche le détail qui débloque. Les labels DNS, la boucle du contexte
- Casse-le exprès. Tu vois vite où sont les limites et les pièges
- Une lib te déçoit ? Reconstruis pour savoir qui porte vraiment le bug
- Une fois compris, détourne. Bâtis l'outil que les libs toutes faites ne donnent pas
- Puis lâche ta version jouet. Reprends la lib de prod, avec un vrai modèle mental
Ce qu'il faut retenir
Le mojo du dev n'a pas bougé. Utiliser un outil sans le comprendre, c'est rester à sa merci. Le reconstruire, même en jouet, c'est reprendre la main.
TCP, DNS, Modbus, un agent LLM. À chaque fois, la même méthode. Reconstruis pour comprendre. Comprends pour détourner. Les LLM sont juste le prochain système sur la liste.
Tu formes une équipe aux LLM, ou tu veux du backend Go qui tient la route ? C'est mon métier. Écris-moi. On ne subit pas les outils. On les comprend.