Cet article montre une évolution de la fonctionnalité "rechercher et remplacer" de l'éditeur de texte,
où l'étape "remplacer" a été remplacée par une transformation LLM.
L'exemple utilise GenAISCript.
Il peut être utile d'appliquer par lots des transformations de texte qui ne sont pas faciles à réaliser avec
expressions régulières.
Par exemple, lorsque nous avons ajouté la possibilité d'utiliser une commande de chaîne dans
la commande exec, nous devions convertir tous les appels utilisant des tableaux d'arguments vers cette nouvelle syntaxe :
host.exec("cmd", ["arg0", "arg1", "arg2"])
à
host.exec(`cmd arg0 arg1 arg2`)`
Bien qu'il soit possible de faire correspondre cet appel de fonction avec une expression régulière
host\.exec\s*\([^,]+,\s*\[[^\]]+\]\s*\)
il n'est pas facile de formuler la chaîne de remplacement... à moins de pouvoir la décrire en langage naturel :
Convert the call to a single string command shell in TypeScript
Voici quelques exemples de transformations où le LLM a correctement géré les variables.
- const { stdout } = await host.exec("git", ["diff"]) + const { stdout } = await host.exec(`git diff`)
- const { stdout: commits } = await host.exec("git", [ - "log", - "--author", - author, - "--until", - until, - "--format=oneline", - ]) + const { stdout: commits } = + await host.exec(`git log --author ${author} --until ${until} --format=oneline`)
L'étape de recherche se fait avec le workspace.grep
qui permet de rechercher efficacement un motif dans des fichiers (c'est le même moteur de recherche
qui alimente la recherche Visual Studio Code).
const { pattern, glob } = env.vars const patternRx = new RegExp(pattern, "g") const { files } = await workspace.grep(patternRx, glob)
La deuxième étape consiste à appliquer l'expression régulière au contenu du fichier
et précalculez la transformation LLM de chaque correspondance à l'aide d'une invite en ligne.
const { transform } = env.vars ... const patches = {} // map of match -> transformed for (const file of files) { const { content } = await workspace.readText(file.filename) for (const match of content.matchAll(patternRx)) { const res = await runPrompt( (ctx) => { ctx.$` ## Task Your task is to transform the MATCH with the following TRANSFORM. Return the transformed text. - do NOT add enclosing quotes. ## Context ` ctx.def("MATCHED", match[0]) ctx.def("TRANSFORM", transform) }, { label: match[0], system: [], cache: "search-and-transform" } ) ...
Puisque le LLM décide parfois de mettre la réponse entre guillemets, nous devons les supprimer.
... const transformed = res.fences?.[0].content ?? res.text patches[match[0]] = transformed
Enfin, avec les transformations pré-calculées, nous appliquons un remplacement final d'expression régulière à
corrigez l'ancien contenu du fichier avec les chaînes transformées.
const newContent = content.replace( patternRx, (match) => patches[match] ?? match ) await workspace.writeText(file.filename, newContent) }
Le script prend trois paramètres : un fichier global, un modèle à rechercher et une transformation LLM à appliquer.
Nous déclarons ces paramètres dans les métadonnées du script et les extrayons de l'objet env.vars.
script({ ..., parameters: { glob: { type: "string", description: "The glob pattern to filter files", default: "*", }, pattern: { type: "string", description: "The text pattern (regular expression) to search for", }, transform: { type: "string", description: "The LLM transformation to apply to the match", }, }, }) const { pattern, glob, transform } = env.vars
Pour exécuter ce script, vous pouvez utiliser l'option --vars pour transmettre le modèle et la transformation.
genaiscript run st --vars 'pattern=host\.exec\s*\([^,]+,\s*\[[^\]]+\]\s*\)' 'transform=Convert the call to a single string command shell in TypeScript'
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!