用LLM当脚本解释器:Shebang行让自然语言变成可执行脚本

利用shebang机制让纯英文文本文件通过LLM工具直接执行
Simon Willison展示了一种将LLM命令行工具嵌入Unix shebang行的技巧,使纯英文自然语言文本文件变成可执行脚本。借助env -S参数解决shebang多参数限制,结合LLM的fragments功能和工具调用能力,用户可以用自然语言描述任务并直接运行,甚至能集成Python函数、数据库查询等复杂操作,体现了编程抽象层级从机器码到自然语言的持续演进。
当英文文本文件也能直接执行
如果你是一名 Linux/macOS 用户,一定对脚本文件第一行的 #!/bin/bash 或 #!/usr/bin/env python3 不陌生——这就是所谓的 shebang 行,它告诉操作系统用哪个解释器来执行这个脚本。
Shebang(#!)机制是 Unix/Linux 内核级别的功能,当操作系统的 execve 系统调用检测到文件以 #! 开头时,会解析该行指定的解释器路径,并将文件自身作为参数传递给该解释器执行。这个机制诞生于 1980 年 Dennis Ritchie 在 Version 8 Unix 中的实现,至今已有 45 年历史。值得注意的是,shebang 行的长度在不同系统上有限制(Linux 内核限制为 128 字节),且传统上只支持一个参数——这个限制在后文中会变得非常关键。
现在,Simon Willison(Datasette 的作者)展示了一个大胆的想法:把 LLM 命令行工具放进 shebang 行,让纯英文的自然语言文本文件变成可执行脚本。你写一段英文描述,赋予执行权限后直接运行,LLM 就会帮你完成任务。
这个灵感来自 Hacker News 用户 Kim_Bruning 的一句评论:
"说真的,现在你可以在英文文本文件上加个 shebang 了(如果你足够勇敢的话)。"
最简形式:自然语言即脚本
最基础的用法利用了 LLM 工具的 fragments 功能。创建一个文件,内容如下:
#!/usr/bin/env -S llm -f
Generate an SVG of a pelican riding a bicycle
给文件加上执行权限(chmod +x),然后直接运行它,LLM 就会生成一只骑自行车的鹈鹕的 SVG 图像。整个文件除了 shebang 行之外,就是一句纯粹的英文指令。
这里的关键在于 env -S 参数——它允许将多个参数传递给指定的程序。传统的 shebang 机制有一个著名的限制:#! 之后的内容会被当作单个参数传递给解释器。例如 #!/usr/bin/env python3 -u 在某些系统上会将 python3 -u 整体当作一个参数,导致执行失败。GNU coreutils 8.30(2018 年发布)引入的 env -S(split-string)选项解决了这个问题,它会将后续字符串按空格拆分为多个独立参数。这个看似微小的改进,恰好为 LLM shebang 脚本提供了技术基础——没有它,就无法在 shebang 行中同时传递 llm 命令和 -f 标志。
-f 标志告诉 LLM 将文件剩余内容作为 fragment(提示片段)来处理。LLM 是 Simon Willison 开发的开源命令行工具,支持通过统一接口调用 OpenAI、Anthropic、本地模型等多种大语言模型。Fragments 是 LLM 0.26 版本引入的功能,允许通过 -f 标志从文件、URL 或标准输入中读取内容作为提示的一部分。在 shebang 场景中,-f 标志不带额外参数时,会将脚本文件自身的剩余内容(shebang 行之后的部分)作为 fragment 读入,这正是自然语言脚本得以工作的核心机制。
进阶用法:集成工具调用
LLM 命令行工具的强大之处在于它不只是生成文本,还能调用工具(tools)。通过 -T 参数,你可以在 shebang 脚本中启用工具调用能力:
#!/usr/bin/env -S llm -T llm_time -f
Write a haiku that mentions the exact current time
这个脚本会调用 llm_time 工具获取当前时间,然后生成一首包含精确时间的俳句。LLM 自主决定何时调用工具、如何将工具返回的结果融入最终输出。
工具调用(也称 Function Calling)是现代大语言模型的关键能力之一,最早由 OpenAI 在 2023 年 6 月随 GPT-3.5/GPT-4 API 引入。其工作流程是:开发者向模型描述可用工具的名称、参数和功能;模型在推理过程中判断是否需要调用工具,如果需要则生成结构化的调用请求(包含函数名和参数);客户端执行实际调用并将结果返回给模型;模型基于工具返回的结果继续生成最终回答。这种机制让 LLM 能够突破自身局限——例如精确数学计算、获取实时信息、访问外部数据库——同时保持自然语言交互的流畅性。Anthropic、Google 等厂商随后也实现了类似的工具调用协议。
高阶玩法:YAML模板 + 自定义Python函数
更复杂的场景可以使用 YAML 模板格式,直接在脚本中定义 Python 函数作为工具:
#!/usr/bin/env -S llm -t
model: gpt-5.4-mini
system: |
Use tools to run calculations
functions: |
def add(a: int, b: int) -> int:
return a + b
def multiply(a: int, b: int) -> int:
return a * b
将其保存为 calc.sh 并执行:
./calc.sh 'what is 2344 * 5252 + 134' --td
--td 是工具调试选项,可以看到 LLM 的完整推理过程:
Tool call: multiply({'a': 2344, 'b': 5252})
12310688
Tool call: add({'a': 12310688, 'b': 134})
12310822
2344 × 5252 + 134 = **12,310,822**
LLM 正确地将数学表达式拆解为两步操作——先乘后加——并通过工具调用得到精确结果,而非依赖自身的数学计算能力。这种模式巧妙地结合了 LLM 的语言理解能力和确定性工具的精确执行能力。这也是当前 AI 应用设计中的一个重要范式:让 LLM 负责理解意图和编排流程,让传统代码负责精确执行,各取所长。
实际应用:用自然语言查询数据库
Simon 还展示了一个更贴近日常工作的例子:通过 Datasette SQL API 用自然语言查询博客内容。你可以写一个脚本,用英文问"我去年写了多少篇关于 AI 的文章",LLM 会自动构造 SQL 查询、调用 API、解析结果并返回人类可读的答案。
Datasette 是 Simon Willison 的另一个知名开源项目,它能将 SQLite 数据库即时发布为可交互的 Web 应用和 JSON API。Datasette 的设计哲学是让数据探索和发布变得极其简单——只需一个 SQLite 文件就能启动完整的数据浏览、查询和 API 服务。其 SQL API 允许通过 HTTP 请求执行任意 SQL 查询并获取 JSON 格式的结果。在自然语言脚本的场景中,LLM 充当了用户意图与 SQL 查询之间的翻译层:用户用英文描述需求,LLM 理解语义后生成对应的 SQL 语句,通过工具调用 Datasette API 执行查询,最后将结构化结果转化为人类可读的自然语言回答。
这种模式本质上是将 LLM 变成了一个通用的自然语言接口层,连接着各种后端工具和数据源。
自然语言脚本意味着什么
从技术角度看,这个技巧本身并不复杂——它只是巧妙地利用了 Unix 的 shebang 机制和 LLM CLI 工具的参数设计。但它传递的信号值得关注:
编程的抽象层级正在发生变化。 从机器码到汇编,从汇编到高级语言,从高级语言到脚本语言,现在自然语言也开始成为一种"可执行"的表达方式。回顾这段历史:1940 年代程序员直接编写二进制机器码;1950 年代汇编语言引入助记符;1957 年 Fortran 开创了高级语言时代,让程序员可以用接近数学的表达式编程;1980-90 年代 Perl、Python 等脚本语言进一步降低了编程门槛,强调快速开发和可读性;2010 年代低代码/无代码平台试图用可视化方式替代文本编程。每一次抽象层级的提升都伴随着对精确控制的部分让渡——汇编程序员曾质疑编译器生成的代码效率,C 程序员曾质疑脚本语言的性能。
当然,LLM 的非确定性输出意味着你不会想在生产环境中依赖这种方式——至少现在还不行。自然语言作为编程接口面临的最大挑战正是这种非确定性:同样的英文指令可能产生不同的输出,这与传统编程的确定性执行形成根本性张力。
但作为快速原型、一次性任务、或者个人工作流自动化的工具,"自然语言脚本"确实降低了与计算机交互的门槛。你不需要记住 curl 的参数格式,不需要查 jq 的语法,只需要用英文描述你想要什么。
正如 Kim_Bruning 所说,你只需要"足够勇敢"就行。
相关推荐
教程攻略Cursor+Codex双IDE协同:开源项目二开实战方法论
基于实战经验总结的开源项目二次开发完整方法论,详解Cursor+Codex双IDE协同工作流,涵盖二开七环节、MVP验证、AI读源码技巧,帮助开发者三天跑通项目、两周完成业务集成。
教程攻略Cursor多Agent实战:50分钟搭建Next.js全栈博客
使用Cursor IDE多Agent协作模式,50分钟内从零搭建全栈博客。涵盖Next.js、Clerk认证、Supabase数据库集成,详解4个AI Agent分阶段开发流程与关键避坑经验。
教程攻略从零搭建AI软件工厂:Cursor工程师的多Agent协作实战经验
Cursor工程师Eric分享AI软件工厂构建实战:从自动化六层级、护栏设计、并行Agent管理到规模化扩展,详解如何用多Agent协作实现7×24小时高效软件开发。