Outils de développement (adk-devtools)
adk-devtools est lâensemble dâoutils de boucle interne dont un agent de codage a besoin â lire, modifier,
rechercher et exĂ©cuter â avec chaque opĂ©ration limitĂ©e Ă un rĂ©pertoire de travail. Câest
un crate autonome publiable, ne dĂ©pendant que de adk-core, donc il sâintĂšgre avec
nâimporte quel LlmAgent (le CodingAgent le configure pour vous).
Les outils
DevToolset est un Toolset regroupant six outils :
| Outil | ParamĂštres | Comportement |
|---|---|---|
read_file | path, offset?, limit? | Retourne le contenu du fichier, avec numéros de ligne |
write_file | path, content | Crée/écrase un fichier (crée les répertoires parents) |
edit_file | path, old_string, new_string, replace_all? | Remplacement exact de chaĂźne |
glob | pattern, path? | Lister les fichiers correspondant Ă un glob (par ex. src/**/*.rs) |
grep | pattern, path?, glob?, case_insensitive? | Recherche de contenu par expression réguliÚre |
bash | command, timeout_secs? | ExĂ©cuter une commande shell Ă la racine de lâespace de travail |
Deux comportements de sécurité à connaßtre :
edit_filenĂ©cessite unread_fileprĂ©alable de ce fichier dans la session, et par dĂ©faut la chaĂźne cible doit apparaĂźtre exactement une fois (replace_allpour outrepasser cela). Cela protĂšge contre les Ă©crasements aveugles.grepignore les rĂ©pertoires de build/VCS courants (target,.git,node_modules, âŠ) ainsi que les fichiers binaires/surdimensionnĂ©s.
Lâoutil bash streame sa sortie stdout/stderr ligne par ligne via
ToolContext::emit_progress pendant lâexĂ©cution de la commande, afin que les UIs puissent afficher un
terminal en direct. Chaque bloc arrive comme un Ă©vĂ©nement partiel sur le EventStream de lâagent
(détectez-le avec event.tool_progress_stream()) ; la sortie complÚte est toujours
renvoyĂ©e comme rĂ©sultat final de lâoutil. Voir lâ
streaming_bash exemple et
Streaming Progress from a Tool.
Le Workspace
Un Workspace ancre chaque opération dans un répertoire et applique une petite politique :
use adk_devtools::Workspace;
use std::time::Duration;
let ws = Workspace::new("./my-repo"); // read-write, bash enabled
let ws = Workspace::read_only("./my-repo"); // explore/plan: no writes, no bash
let ws = Workspace::new("./my-repo")
.allow_bash(false) // file edits, but no shell
.bash_timeout(Duration::from_secs(60))
.max_output_bytes(512 * 1024);
-
Contenance du chemin â tout chemin qui se rĂ©sout en dehors de la racine est rejetĂ©, donc lâagent ne peut pas lire ou Ă©crire
../../etc/.... La contenance est appliquĂ©e au chemin rĂ©solu, pas seulement au chemin littĂ©ral : un lien symbolique pointant hors de la racine est rejetĂ© mĂȘme sâil se trouve lexicalement Ă lâintĂ©rieur. Cela couvre un composant final liĂ© par symlink et un rĂ©pertoire parent liĂ© par symlink, donc la crĂ©ation via un rĂ©pertoire redirigĂ© est aussi refusĂ©e. Un symlink dont la cible reste Ă lâintĂ©rieur de lâespace de travail continue de fonctionner, puisque les dĂ©pĂŽts contiennent lĂ©gitimement des liens internes.La vĂ©rification nâest pas un verrou. Un symlink placĂ© entre la vĂ©rification et lâouverture suivante serait quand mĂȘme suivi ; pour fermer cette fenĂȘtre, il faut un parcours relatif aux descripteurs avec les sĂ©mantiques no-follow de la plateforme. ConsidĂ©rez les outils de fichiers comme une contenance face Ă un agent qui erre, et non comme une isolation face Ă un adversaire qui peut Ă©crire simultanĂ©ment dans lâespace de travail.
-
Mode lecture seule â
Workspace::read_only(..)masque entiĂšrement les outils modifiants (le modĂšle ne voit queread_file/glob/grep). -
Lâenvironnement de
bashest vidĂ© â la commande reçoit seulementPATH,HOME,LANG,LC_ALL,TMPDIR,TERM,USERetSHELL, donc les clĂ©s API du fournisseur dĂ©tenues par le processus de lâagent ne sont pas lisibles avecenv.Workspace::inherit_env(true)rĂ©tablit lâancien comportement consistant Ă tout transmettre, etenv_allowlistremplace lâensemble. -
DĂ©lai dâattente de
bash+ limites de sortie â les commandes longues ou bavardes sont bornĂ©es. Une commande arrivĂ©e au timeout est tuĂ©e comme un groupe de processus, donc tout ce quâelle a lancĂ© est tuĂ© aussi ; auparavant seul lâenfant direct Ă©tait signalĂ© et les descendants survivaient.
Lâutiliser directement
Attachez lâensemble dâoutils Ă nâimporte quel agent :
use adk_devtools::{DevToolset, Workspace};
use adk_agent::LlmAgentBuilder;
use std::sync::Arc;
let agent = LlmAgentBuilder::new("coder")
.model(model)
.toolset(Arc::new(DevToolset::new(Workspace::new("./my-repo"))))
.build()?;
DevToolset nâexpose que les outils autorisĂ©s par lâespace de travail, donc un espace de travail
en lecture seule donne automatiquement un agent en lecture seule.
ModĂšle de sandboxing
La phase 1 exĂ©cute bash localement sur lâhĂŽte (sh -c, rĂ©pertoire de travail fixĂ© Ă la racine) avec un
dĂ©lai dâattente et un environnement vidĂ©. Ce que cela vous apporte, et ce que cela ne vous apporte pas :
| Imposé | Non imposé |
|---|---|
| Les outils de fichiers ne peuvent pas rĂ©soudre en dehors de la racine, y compris via des liens symboliques | bash peut toujours utiliser des chemins absolus â le rĂ©pertoire de travail nâest pas une frontiĂšre du systĂšme dâexploitation |
| La commande ne peut pas lire les variables dâenvironnement de lâagent | La commande peut accĂ©der au rĂ©seau |
| Un dĂ©lai dâattente interrompt la commande et ses descendants | Rien ne limite la mĂ©moire ou le CPU |
Il est donc contenu dans le chemin, isolĂ© de lâenvironnement et bornĂ©, mais pas isolĂ© du systĂšme dâexploitation. Le vocabulaire de la politique sâaligne sur adk-code et SandboxPolicy ; pour une isolation forte, exĂ©cutez bash derriĂšre un exĂ©cuteur conteneurisĂ© (voir le
design doc).
Combinez-le avec adk-guardrail (listes dâautorisations des commandes,
redaction des secrets) et adk-auth pour les
outils avec jeton (p. ex. GitHub).
Suivant : The harness â