Aller au contenu

Comment HagiCode a connecté 13 Agent CLI à un seul système

Modifier cette page
HagiCode for Windows Microsoft Store artwork
HagiCode for Windows is now on Microsoft Store
HagiCode for Windows is officially live on Microsoft Store. Windows users can install it directly from the storefront and stay on the store-managed update path. Open the listing and take a look.
Open Microsoft Store

Comment HagiCode a connecté 13 Agent CLI à un seul système

En fait, ce n’est ni difficile ni facile. Parlons de la façon dont nous avons utilisé une architecture en couches pour unifier la gestion d’Agent CLI aux styles très variés comme Claude Code, Codex, Copilot, Gemini, tout en pouvant en ajouter un nouveau à tout moment.

Contexte

L’histoire a commencé brusquement, à cause d’un problème assez casse-tête.

Ces deux dernières années, les Agent CLI ont poussé comme des champignons — Claude Code, OpenAI Codex, GitHub Copilot, Gemini CLI, Kimi, Qoder, Kiro… tous les quelques mois, un nouveau apparaît. En tant que projet qui veut permettre aux utilisateurs “d’installer un HagiCode et utiliser l’ensemble des Agent”, nous ne pouvions pas miser uniquement sur un seul CLI, mais nous ne pouvions pas non plus écrire une logique complète d’installation, de vérification de santé et de planification pour chaque CLI — le code gonflerait jusqu’à devenir impossible à maintenir, comme une pelote de laine emmêlée que personne n’oserait toucher.

Plus ennuyeux encore, ces CLI ont des tempéraments très différents : certains utilisent stdio, d’autres gRPC, certains ne vous donnent qu’une entrée shell, les formats de sortie en streaming sont tous différents. Si nous écrivons directement des jugements comme if (provider == ClaudeCode) dans le code métier, en moins de six mois, cela deviendra un “code ancestral” que personne n’osera toucher. Après tout, qui voudrait toucher une brique qui semble prête à s’effondrer ?

Pour contenir toutes ces douleurs, nous avons pris une décision : ajouter une fine couche d’abstraction et un runtime partagé entre la couche métier et les CLI spécifiques. Cela semble simple, mais cela détermine directement si HagiCode peut rapidement intégrer de nouveaux CLI. Je vais expliquer comment faire plus tard.

À propos de HagiCode

La solution partagée dans cet article provient de notre pratique dans le projet HagiCode. HagiCode est une plateforme d’intégration d’assistants de code IA, avec un objectif très pur — utiliser une installation, une configuration pour intégrer tous les Agent CLI mainstream pour que les utilisateurs puissent les utiliser.

D’où vient ce chiffre “13”

Parlons d’abord d’un chiffre qui a été posé plusieurs fois — pourquoi 13 Agent CLI.

En fait, la réponse se cache dans l’énumération AIProviderType, comme l’ombre de bambou à l’extérieur de la fenêtre, tant que vous voulez regarder, vous pouvez la voir. La définition originale ressemble à ceci :

public enum AIProviderType
{
ClaudeCodeCli = 0,
CodexCli = 1,
GitHubCopilot = 2,
CodebuddyCli = 3,
OpenCodeCli = 4,
IFlowCli = 5, // Déprécié
HermesCli = 6,
QoderCli = 7,
KiroCli = 8,
KimiCli = 9,
GeminiCli = 10,
DeepAgentsCli = 11,
ReasonixCli = 12,
PiCli = 13,
}

L’énumération a 14 valeurs au total, mais la route IFlowCli=5 est déjà impraticable. Dans AIProviderFactory, elle est explicitement bloquée à l’extérieur :

if (providerType == AIProviderType.IFlowCli)
{
throw new NotSupportedException("IFlowCli is no longer supported");
}

En combinant avec IsActivelySupportedProviderType() pour faire un filtrage supplémentaire, ce qui est vraiment “vivant” dans le système est 13 : Claude Code, Codex, GitHub Copilot, CodeBuddy, OpenCode, Hermes, Qoder, Kiro, Kimi, Gemini, DeepAgents, Reasonix, Pi.

C’est l’origine du “13”. Ce n’est pas un chiffre marketing, c’est réellement compté dans le code. Après tout, les chiffres ne mentent pas, ce sont nous qui mentons.

Architecture en couches : enfermer le changement dans une cage

L’idée centrale pour connecter 13 CLI est en fait une phrase : laisser le code métier ne pas se soucier de celui qu’il appelle.

Nous l’avons divisé en six couches, en regardant de haut en bas :

1. Couche d’identité — AIProviderType

L’énumération est le “numéro d’identité” de chaque CLI. N’importe où, mentionner un CLI utilise cette valeur d’énumération, entre la chaîne et l’énumération, on utilise ToStringValue() / ToAIProviderType() pour se convertir mutuellement. Simple, mais indispensable.

2. Couche de contrat métier — IAIProvider / IAIProviderFactory

Le côté métier ne reconnaît que l’interface IAIProvider, qui définit des actions génériques comme “envoyer un prompt, recevoir une réponse en streaming”. Quant à savoir si c’est Claude ou Codex en dessous, le métier ne s’en soucie pas — comme quand vous écrivez une lettre, vous la remettez simplement, peu importe le nom du facteur, qui s’en soucie ?

3. Couche d’adaptateur — *CliProvider

Chaque CLI correspond à un fin adaptateur, comme PiCliProvider, ReasonixCliProvider, ClaudeCodeCliProvider. Ces adaptateurs ont très peu à faire : traduire les requêtes métier génériques en paramètres que le CLI spécifique peut comprendre, puis traduire la sortie du CLI spécifique. Ils sont intentionnellement très fins, pour ajouter un nouveau CLI, on copie essentiellement un existant, on modifie un peu.

4. Couche de runtime partagé — ICliProvider<TOptions>

Cette couche dans HagiCode.Libs est l’endroit où l’on fait vraiment le sale travail : lancer des processus multiplateforme, gérer les transports stdio, analyser les sorties en streaming, gérer les délais d’attente et les nouvelles tentatives. Tous les adaptateurs réutilisent le même runtime, donc lors de l’intégration d’un nouveau CLI, la gestion des processus n’a pratiquement pas besoin d’être réécrite.

Pour faire une analogie, la couche d’adaptateur est le “traducteur”, la couche de runtime partagé est la “société de livraison”. Le traducteur ne fait que s’exprimer clairement ; comment le paquet est livré, s’il y a des embouteillages en route, c’est l’affaire de la société de livraison. Chacun fait son travail, le monde devient calme.

5. Couche de routage d’usine — AIProviderFactory

Dans CreateProvider, un switch, instancie l’adaptateur correspondant selon AIProviderType, et vérifie IsConfigured en même temps. C’est le seul endroit qui “connaît le type concret”, isolé strictement dans l’usine. Les changements ne sont autorisés que dans un coin, le reste reste propre.

6. Couche de projection de catalogue / UI — main-professions.yaml

Cette couche est intéressante, ce n’est pas du code, ce sont des données.

La liste des professions principales (“Je suis un frontend”, “Je suis un backend”, “Je suis un fullstack”, ce genre de portrait de rôle) est pilotée par le fichier préréglé main-professions.yaml, lu via HeroPrimaryProfessionPresetProvider, puis projeté sur l’UI frontend. Ajouter une nouvelle profession principale ne nécessite pas de modifier une seule ligne de code, modifier le YAML suffit. Les données remplacent le code, c’est rassurant.

Au fait, c’est la plus grande refonte de HagiCode. Dans les versions précédentes, il y avait un registre d’inscription dans le code appelé AgentCliInstallRegistry, mais nous avons constaté que le coût de maintenance était trop élevé — plus de code, plus de fatigue — le tout a été démoli et remplacé par une solution pilotée par les données + surveillance de santé. C’est aussi pourquoi HagiCode peut maintenant étendre rapidement les types de professions.

Comment résoudre le problème d’installation

13 CLI doivent être installés, et chaque méthode d’installation officielle est différente, c’est une autre montagne.

Notre approche est préinstallation Docker Compose + secours par gestion externe. L’image préinstalle les CLI mainstream (Claude Code, Codex, Copilot, CodeBuddy, OpenCode, Qoder, Kiro, Kimi, Gemini, Pi), les utilisateurs tirent l’image et peuvent l’utiliser, sans taper de commande une par une. Une fois installé, l’humeur est naturellement meilleure.

Pour ceux qui doivent être installés séparément dans l’environnement local, la matrice de commandes d’installation est à peu près comme ça (vérifiée avec la documentation officielle) :

CLIMéthode d’installation officielle
Claude Codenpm install -g @anthropic-ai/claude-code
Codexnpm install -g @openai/codex
GitHub Copilotnpm install -g @github/copilot
CodeBuddynpm install -g @tencent-ai/codebuddy-code
OpenCodenpm i -g opencode-ai@latest
Qodernpm install -g @qoder-ai/qodercli
Kirocurl -fsSL https://cli.kiro.dev/install | bash
Kimicurl -LsSf https://code.kimi.com/install.sh | bash
Gemininpm
HermesScript officiel, conserve docs-only comme secours
DeepAgents / ReasonixVoir documentation officielle respective

Le côté frontend PrimaryProfessionCard.tsx a aussi changé — il n’a maintenant pas de bouton “installer CLI”, mais affiche la disponibilité du CLI, les résultats de détection de version, et le message de secours “ce CLI est géré par externe”. C’est-à-dire que l’installation est de la responsabilité de la couche système, l’UI ne fait que refléter fidèlement l’état. Écrire l’état et la logique séparément, tôt ou tard ils ne correspondront pas, alors pourquoi le faire ?

Que faut-il faire pour ajouter un nouveau CLI

En pratique, ajouter un nouveau CLI dans HagiCode, environ ces quelques étapes :

  1. Ajouter une valeur d’énumération dans AIProviderType
  2. Copier un *CliProvider existant, modifier pour les paramètres et l’analyse de sortie du nouveau CLI
  3. Ajouter une ligne de routage dans le switch de AIProviderFactory
  4. Si on veut entrer dans le catalogue des professions principales, configurer dans main-professions.yaml
  5. Ajouter une commande d’installation dans l’image (ou passer par la gestion externe comme secours)

L’ensemble du processus, les modifications principales ne dépassent pas deux cents lignes de code — c’est la vraie valeur de cette abstraction. Plus on connecte de CLI, le coût marginal est très faible, le code métier n’a pas besoin d’être modifié d’une seule ligne. Tous les chemins mènent à Rome, c’est juste que notre chemin est un peu plus facile à emprunter.

Résumé

En regardant en arrière, “connecter 13 CLI” semble effrayant, mais si on le décompose, en fait ce sont deux couches de travail :

Une couche est isoler le changement — via l’énumération AIProviderType + le contrat IAIProvider + fins adaptateurs + runtime partagé, laisser le code métier et les CLI spécifiques découplés ; l’autre couche est rendre la configuration basée sur les données — utiliser des préréglages YAML comme main-professions.yaml pour piloter le catalogue et l’UI, éviter de devoir modifier le code à chaque fois qu’on ajoute quelque chose.

Cette solution est ce que nous avons stabilisé après avoir traversé des obstacles et itéré plusieurs tours dans le développement réel de HagiCode. Si vous êtes en train de faire un système similaire d‘“intégration multi Provider”, j’espère que cette idée de couches pourra vous donner une référence. Après tout, les Agent CLI continueront à sortir ces deux prochaines années, une architecture qui peut rapidement intégrer de nouveaux CLI est beaucoup plus importante que “combien sont supportés maintenant”…

开始使用 HagiCode

一次安装,几分钟上手

HagiCode for Windows 在 Microsoft Store 免费提供。打开商店即可安装并保持更新;也可以先对比各版本与定价,再决定从哪个渠道开始。