文件输出
可靠的文件生成,无论是新建还是更新,都是使用LLMs最具挑战性的部分之一。GenAIScript脚本支持几种方法和格式来生成文件:对于小文件,通常重新生成整个内容更高效。对于大文件,生成编辑更高效。
工作原理
GenAIScript会自动添加一个系统消息,用于教导大语言模型如何格式化输出文件。
让我们从一个生成诗歌并让GenAIScript将其保存到文本文件的脚本开始。
$`Generate a 1 sentence poem and save it to a text file.`
由于未指定系统提示,GenAIScript会添加默认的系统提示集,包括system.files提示。该提示指示LLM生成一个包含脚本输出的文件。 LLM会响应一个代码段,其中也提到了文件名。这是GenAIScript可以自动解析的格式。
FILE ./poem.txt:
```In twilight's gentle embrace, dreams dance like whispers on the breeze.```
默认情况下,文件编辑不会自动应用。在Visual Studio Code中,会打开重构预览,用户可以接受或拒绝更改。

在命令行界面中,除非使用--apply-edits
标志,否则更改会被静默忽略。
npx genaiscript run poet --apply-edits
更新日志格式
文件的完整重新生成仅适用于小文件。
对于大文件,GenAIScript使用自定义的changelog
格式,旨在最小化幻觉现象。
def("FILE", env.files)$`Comment every line of code and update the file. Use the changelog format.`
当我们在源文件上运行脚本时,大型语言模型会生成一个包含文件变更的更新日志。 GenAIScript将解析此输出并生成类似于完整文件更新的文件编辑。
```changelogChangeLog:1@packages/sample/src/greeter.tsDescription: Added comments to each line of code to explain functionality.OriginalCode@1-6:[1] class Greeter {[2] greeting: string[3][4] constructor(message: string) {[5] this.greeting = message[6] }ChangedCode@1-6:[1] // Define a class named Greeter[2] class Greeter {[3] // Property to hold the greeting message[4] greeting: string[5][6] // Constructor to initialize the greeting property[7] constructor(message: string) {[8] // Set the greeting property to the provided message[9] this.greeting = message[10] }OriginalCode@7-11:[7][8] greet() {[9] return "Hello, " + this.greeting[10] }[11] }ChangedCode@7-11:[7][8] // Method to return a greeting message[9] greet() {[10] return "Hello, " + this.greeting[11] }[12] }OriginalCode@12-18:[12][13] interface IGreeter {[14] greeting: string[15] greet(): string[16] }[17][18] export function hello() {}ChangedCode@12-18:[12][13] // Define an interface for a Greeter[14] interface IGreeter {[15] // Property to hold the greeting message[16] greeting: string[17] // Method to return a greeting message[18] greet(): string[19] }[20][21] // Export an empty function named hello[22] export function hello() {}OriginalCode@19-20:[19][20] let greeter = new Greeter("world")ChangedCode@19-20:[23][24] // Create a new instance of Greeter with the message "world"[25] let greeter = new Greeter("world")```
如您所见,变更日志格式在令牌方面要重得多;然而,它在大型文件中进行编辑时更加可靠。
声明文件输出
defFileOutput
函数允许您声明文件输出路径及这些文件的用途。该函数用于指定脚本生成的输出文件。
defFileOutput("src/*.md", "Product documentation in markdown format")
在我们的示例中,我们指示LLM在poem.txt
生成诗歌,同时这也允许GenAIScript验证文件位置并自动应用更改。
$`Generate a 1 sentence poem and save it to a text file.`defFileOutput("poem.txt", "the generated poem")
在后台,GenAIScript会添加一个类似这样的系统消息,告诉LLM文件应该存放在哪里。
## File generation rules
When generating files, use the following rules which are formatted as "file glob: description":
poem.txt: the generated poem
模式验证
您可以将JSON schema与文件输出关联。该模式用于在文件写入磁盘之前验证其内容。
const schema = defSchema("KEYWORDS", { type: "array", items: { type: "string", },})defFileOutput("src/rag/*.keywords.json", "An array of keywords in the file", { schema,})
文件输出后处理
您可以通过注册回调函数,使用defOutputProcessor以编程方式操作生成的文件。
系统提示
生成文件的支持由几个系统提示定义。这些提示通常会自动添加,但如果您指定了自定义的系统提示集,可能需要手动添加回来。
- system.files, 指定"完整"文件格式
- system.changelog, 说明"changelog"文件格式
- system.files,在文件生成中指定JSON模式