Je suis tombée sur un problème intéressant en essayant de faire exécuter du code par Claude sur mon système. Enfin, une série de problèmes, en fait. Voyez-vous, Claude peut désormais analyser des commandes représentées par des balises à la vieille école, type ASP/JSP : <%= pwd %> ou <%= ls -d %>.
Ici, le « = » représente le flag d’exécution, et un symbole « @ » sera utilisé plus tard pour des recherches contextuelles dans les historiques de chat, donc des balises du genre <%@ thoughts on cows %>.
C’est logique, c’est facile à implémenter, et les balises sont gratuites puisque personne de sensé n’utilise plus ça pour analyser de la logique métier. Claude devrait savoir traiter ça. Théoriquement.
Sauf que ma méthode devient vite très collante.
Deux problèmes avec la sortie d’outil
Le truc, c’est que les réponses apparaissent à l’intérieur du contexte de la réponse de l’IA. Ça pose deux problèmes :
1. Si un processus en plusieurs étapes est nécessaire, je dois dire à Claude « Continue » avant qu’il ne puisse être terminé.
2. Comme les réponses sont liées à la réponse de l’IA, Claude s’embrouille et croit qu’il est en train de rendre la réponse du système.
Fascinant, non ?
Au début, j’ai pensé que ça revenait à une sorte de tromperie, que Claude devenait « sournois ». Mais maintenant que je regarde la structure du contexte, je ne pense pas que ce soit le cas.
Claude a la sincérité ancrée au cœur du prompt de son système de base, et je n’ai jamais vu Claude être « sournois » auparavant, du moins en dehors de ce bac à sable, ce qui veut dire... que ça doit venir des données.
Une boucle bornée
Mais et si je pouvais régler les deux problèmes avec la même fonction ? Écoutez-moi bien.
On sait que Claude ne peut pas toujours raisonner sur chaque problème, et qu’il va boucler sans fin sur certaines classes de problèmes, provoquant une boucle infinie de raisonnement dégradé si on traite la réponse du système comme une entrée humaine. D’un autre côté, sachant cela, on sait aussi que Claude peut résoudre la plupart des problèmes qu’il EST capable de résoudre en moins de dix étapes itératives.
Étiqueter la sortie et plafonner les itérations
Voilà mon plan :
1. Traiter les réponses du système comme des entrées humaines, en étiquetant clairement chacune d’elles avec :
« [SYSTEM MESSAGE] Dear Agent, please remember to think step by step » en haut de la réponse, suivi de n’importe quelle sortie de terminal actuelle.
Et voilà, c’est clair ce que sont ces messages, que Claude ne les génère pas, et Claude peut boucler sans plus d’hallucinations « sournoises » !
2. Mais qu’en est-il du problème de la boucle infinie ? Simple comme bonjour. On impose une limite stricte à la boucle. Pas plus de 10 itérations.
Et c’est comme ça qu’on rend ses agents semi-autonomes. Yes !