Show HN: Jacquard —— 一种专为AI编写、人工审核代码设计的编程语言

Hacker News Top 工具

摘要

Jacquard是一种专为AI编写、人工审核代码而设计的编程语言,内置效果跟踪、概率模拟和规范标识,帮助人类信任AI生成的程序。

我对席卷而来的生成式AI浪潮深感着迷,好奇AI是否能创造一种它自己更偏好的语言,而不是那些由人类创造并为人类设计的语言。 为了完成设计,我让AI分析了多种主流语言以及一些概念上具有突破性但较为晦涩的语言(列在README中)的AST,然后构建了新的结构和语法。它以Jacquard织机(<a href="https://en.wikipedia.org/wiki/Jacquard_machine" rel="nofollow">https://en.wikipedia.org/wiki/Jacquard_machine</a>)命名,这种织机是巴贝奇分析引擎(以及穿孔卡片)的前身。 结果复用了许多现有理念,但我认为以一种有趣的方式将它们结合在一起。外部/世界效应在函数签名中可见,运行时需要显式权限才能触碰文件系统、网络等。效应交互可以被记录和重放,以观察在不同条件或代码下会发生什么。由于代码内在拥有内容寻址的语义标识,重命名和格式化更改无需重新编译或重新测试。 另一个由此衍生出的成果是名为Warp的测试框架,它结合了重放、结果缓存、处理器替换以及其他一些工具——坦白说,我在写Python时真希望有这些工具。demos目录中有一些示例。 还有很多工作要做,但它已经可以安装和使用。我希望人们能让他们的智能体消化docs/SKILL.md文件,或许能编写一些程序,或看看它在他们的项目中能发挥什么作用。它在智能体系统中应该特别有用。如果某个智能体说某件事很麻烦,或者作为人类你发现代码难以理解,我很想听听意见,以便我加以改进。 更多详情: 仓库:<a href="https://github.com/jbwinters/jacquard-lang" rel="nofollow">https://github.com/jbwinters/jacquard-lang</a> 更深入的/面向人类的介绍:<a href="https://research.friendmachine.co/jacquard/" rel="nofollow">https://research.friendmachine.co/jacquard/</a>
查看原文
查看缓存全文

缓存时间: 2026/07/13 22:56

jbwinters/jacquard-lang

来源:https://github.com/jbwinters/jacquard-lang

Jacquard

持续集成(https://github.com/jbwinters/jacquard-lang/actions/workflows/ci.yml) 发布(https://github.com/jbwinters/jacquard-lang/releases)

Jacquard 是 FriendMachine 的一个研究项目,用于运行、审查、模拟和信任由模型编写并由人类审查的程序。请从面向人类的 Jacquard 介绍(https://research.friendmachine.co/jacquard/)开始。

具体来说,它是一种小型编程语言,具有紧凑的 .jac 表面语法、一个 OCaml 编写的检查器和 CPS 解释器、一个 C 语言输出的原生 AOT 后端(目前编译内核 .jqd 载体)、一个命令行工具、一个用 Jacquard 编写的标准库,以及一个名为 Warp 的测试框架。0.1 版本端到端可用,但仍是研究原型,并非生产语言;docs/release/0.1/LIMITS.md 是其诚实边界。

无需 OCaml 或 opam 即可安装 0.1 候选发布版:

curl -fsSL https://raw.githubusercontent.com/jbwinters/jacquard-lang/jacquard-core-0.1-rc3/scripts/install.sh | sh
~/.local/bin/jac run ~/.local/share/jacquard/demos/basics/m1-fact.jac

预期输出为 120。已发布 Linux x86-64、macOS Intel 和 macOS Apple Silicon 二进制文件;从源码开发的方法见下文。

然后在一个具体世界和概率世界下运行某个策略,接着执行抽样和穷举 Warp 检查:

sh ~/.local/share/jacquard/demos/case-studies/release-risk/run.sh

面向人类

大多数语言告诉你程序计算什么。Jacquard 还揭示了它可能执行的效应、有限的离散不确定性以及规范的程序身份。工具可以检查所有这些,因为它们存在于语言中,而不只是存在于注释、日志或你对代码库的记忆中。

以下是一些这里能做、而大多数语言无法提供的事情:

  • 阅读一行就能看到函数可能执行的效应。像 (text) ->{net} text 这样的签名表示该函数可能执行 net 效应。Jacquard 运行时拒绝未处理的世界效应,除非使用 --allow 显式授权,包括动态代码执行的效应。这是研究运行时中的语言级强制,不能替代操作系统沙箱。
  • 对同一程序运行多个世界。同一份代码可以针对真实网络、脚本模拟的假数据、上周流量的录制回放,或者关于服务器通常行为方式的概率模型来运行。处理器(handler)是回答程序对外部世界的请求的组件;你只需替换处理器,而代码本身从不改变。这可以取代许多在效应边界上的传统模拟(mocking),并使“如果 API 宕机我的代理会怎么做”成为一次普通的测试。
  • 为有限的离散模型枚举精确概率。程序可以对带权重的选择进行采样并记录证据,枚举会列出每个可达结果及其精确概率。下面的修复演示将失败的测试视为证据,并计算哪些补丁仍然可能及其可能性大小。
  • 重命名和重新格式化而不改变规范身份。Jacquard 对规范解析后的结构进行哈希,而不是对源码字节进行哈希。注释、格式、来源以及普通局部或项的重命名都会被忽略;纯测试仅在规范代码或依赖内容发生变化时重新运行。这是结构身份,而非任意程序行为等价的证明。

这一切背后的赌注是:当大多数代码由机器编写时,审查代码的人类需要语言本身来回答“这段代码能接触到什么,我们有多确定”,而不必逐行阅读。

面向智能体

首先阅读 docs/SKILL.md。它将内核、CLI、前导、Warp 测试以及已知陷阱压缩成一个文件,并从 docs/SKILL.md 作为项目技能加载。操作规则见 AGENTS.md。以下内容可以节省你的时间:

  • 行为由 pin 固定:test/cli/ 下的 cram 转录、语料库的金标准、演示脚本以及 docs/release/0.1/CLAIMS.md。如果 pin 失败,将其视为关于你的变更的信息,永远不要为了通过 diff 而削弱 pin。
  • 内核有 27 种形式(docs/ast.md);.jac 是这些形式的一个投影,引导程序 .jqd 将永久支持。将已发布的表面边界及其搁置的后续改进视为发布证据,而不是冻结的语法;不要添加超出范围的功能(AGENTS.md 中列出了这些功能)。
  • 开发关卡是 dune build @all && dune runtest && dune fmt,然后是一个干净的 git diff --exit-code

核心要素

对于懂编程语言的读者:

  • 统一的表示:每种形式都是一个 (head, meta, args) 三元组,内核语法有 27 种形式。引用的代码是普通数据。
  • 带深度、多次恢复的处理器的代数效应。处理器可以零次、一次或多次恢复计算,这正是穷举搜索和精确推理成为普通库代码的原因。
  • 显式能力授权。运行时仅为那些你用 --allow 传递的效应安装处理外部世界的处理器;没有环境权限。
  • 类型与效应行。每个箭头都携带函数可能执行的一组效应,因此程序推断出的行就是它的权限清单。
  • 离散概率编程作为库:sampleobserve 是效应操作,每个推理算法都是一个处理器。
  • 内容寻址定义。身份是对规范解析后的结构(去除非身份元数据)的哈希,因此格式、注释以及普通的局部或项重命名不会影响下游。
  • 基于上述的工具:格式化器、结构感知差异比较器、带内容寻址缓存的 Warp 测试、录制/回放,以及可复现的发布证据包。
  • 原生 AOT 路径:输出 C 语言,按内容哈希对单元进行专门化和缓存,并在 clang 和 gcc 下与解释器进行差异测试。

原型已按最初的核心计划完成,并随后添加了公开表面语法、环形标准库、Warp 属性和缓存、原生编译、打包二进制文件以及产品规模的案例研究。RC1 的语义边界由 554 个 Alcotest/QCheck 用例、32 个 cram 转录、21 个文档示例、原生 sanitizer/泄漏/fuzz 通道以及一个全新克隆的证据工作流固定。RC2 修复了二进制演示打包问题;RC3 增加了显式的运行时/输出许可例外,并打包了原生运行时。当前后续版本将 Jacquard 重新许可为 Apache License 2.0,并将该运行时/输出权限作为显式声明保留。这些许可和打包变更不会改变 RC1 固定的语言语义。

示例

以下是一个处理器一次恢复两次延续的示例。该代码块逐字节复制到 test/docs-doctest/fixtures/readme-multishot.jac,并由文档测试通道运行:

effect Choice where {
  choose : () -> Bool
}

handle {
  match choose() {
    | True -> 1
    | False -> 2
  }
} {
  | return x -> x
  | choose() resume continue -> add(continue(True), continue(False))
}
$ jac run test/docs-doctest/fixtures/readme-multishot.jac
3

处理器将程序的剩余部分运行了一次(传入 true)和一次(传入 false),然后收集了两个结果。这种能够多次恢复的能力,正是精确贝叶斯推理在这里以库处理器而非运行时特性的形式存在的原因。修复演示建立在此之上:将有 bug 程序的引号 AST 变异为候选补丁,将失败的测试视为观察,然后读取更新后的概率。运行候选代码是一种权限,因此纯步骤仍然运行(它计数了八个候选补丁),然后演示拒绝继续,直到你授予权限:

$ jac run demos/tooling/repair.jac
8
error[E0814]: this program requires the `eval` effect, which is not granted (performed via `posterior-over-patches`)
  hint: grant it with --allow eval, or handle the effect in the program
$ jac run demos/tooling/repair.jac --allow eval

在授予权限后,一次失败的测试留下了两个幸存补丁:预期的修复(概率 0.75)和另一个欺骗测试套件的补丁(概率 0.25)。添加一个回归测试即可剔除冒名顶替者,幸存修复打印为一行规范 diff:- sub + add。完整转录见 sh demos/tooling/repair.sh

安装发布二进制文件

大多数用户不需要 OCaml 或 opam。使用以下命令安装已审查的 0.1 RC 二进制文件:

curl -fsSL https://raw.githubusercontent.com/jbwinters/jacquard-lang/jacquard-core-0.1-rc3/scripts/install.sh | sh

安装程序会检测你的操作系统和 CPU,下载匹配的存档和 SHA-256 校验和,在校验和不匹配时拒绝安装,并默认安装到 ~/.local。确保 ~/.local/binPATH 中,然后运行:

jacquard --version
jac --version

jacjacquard 的短别名。两个命令都会从安装包中设置 JACQUARD_PRELUDE,因此普通运行无需环境变量:

jac run ~/.local/share/jacquard/demos/basics/m1-fact.jac

叙事性演示自带启动脚本,自动选择已安装的二进制文件和前导。它们不需要 Dune:

DEMO_ROOT="$HOME/.local/share/jacquard/demos"
sh "$DEMO_ROOT/case-studies/release-risk/run.sh"
sh "$DEMO_ROOT/worlds/agent-dream.sh"
sh "$DEMO_ROOT/worlds/escrow/run.sh"

请使用这些启动脚本,而不是直接运行概率模型或多文件入口点。启动脚本会在需要观察时选择 infer 模式,并在隔离的临时空间中组装相关文件。

要安装到不同的用户拥有的前缀下:

curl -fsSL https://raw.githubusercontent.com/jbwinters/jacquard-lang/jacquard-core-0.1-rc3/scripts/install.sh \
  | JACQUARD_INSTALL_PREFIX="$HOME/.jacquard" sh

设置 JACQUARD_INSTALL_VERSION 以安装不同的发布标签。支持的二进制目标包括 linux-x86_64macos-x86_64macos-arm64;其他平台目前需要开发环境。

发布归档文件附加在 jacquard-core-* GitHub 版本中。每个归档包含 bin/jacquardbin/jaclibexec/jacquard/jacquardshare/jacquard/preludeshare/jacquard/demos、原生 C 运行时以及许可、声明、例外和商标文档。

快速开发指南

以下命令假设全新克隆且已安装 asdf 用于安装 opam。如果你已经有 opam 2.5.x,从本地 switch 步骤开始。如果 opam 已在你的机器上初始化,跳过 opam init

git clone https://github.com/jbwinters/jacquard-lang.git
cd jacquard-lang

asdf plugin add opam https://github.com/asdf-community/asdf-opam.git
asdf install opam 2.5.1
asdf set opam 2.5.1
asdf reshim opam 2.5.1

opam init -y --no-setup --bare
opam switch create . ocaml-base-compiler.5.1.1 -y
eval "$(opam env)"

opam install --deps-only . --with-test --with-dev-setup --with-doc -y
opam exec -- dune build @all
opam exec -- dune runtest
opam exec -- dune fmt
git diff --exit-code

switch 步骤会从源码编译 OCaml 5.1.1,因此首次设置预计需要大约十分钟。

最后的 git diff --exit-code 是开发契约的一部分:格式化必须保持工作目录干净,除非你有意提交格式化差异。

设置后的预期版本:

  • opam 2.5.1(来自 .tool-versions
  • OCaml 5.1.1(来自仓库本地的 _opam/ switch)
  • duneocamlformatalcotestqcheckdigestifmenhircmdlinerodocutopocaml-lsp-server(来自 jacquard.opam

在现有检出目录中的新 shell 里运行:

eval "$(opam env)"

_opam/ 被有意忽略。它是本地构建产物,而非源码。

运行 Jacquard

在开发期间,通过 Dune 使用构建的二进制文件:

opam exec -- dune exec jac -- --help
opam exec -- dune exec jac -- --version

许多直接 CLI 命令需要前导。从仓库根目录:

export JACQUARD_PRELUDE=$PWD/prelude
opam exec -- dune exec jac -- run demos/basics/m1-fact.jac

主要命令如下:

jac run FILE.jac [--allow fs] [--allow net] [--dry-run]
jac check FILE.jac [--print-sigs] [--manifest fs,net,console]
jac hash FILE.jac
jac fmt FILE.jac
jac diff FILE_A.jac FILE_B.jac
jac diff STORE_A STORE_B
jac infer enumerate MODEL.jac
jac infer lw MODEL.jac --seed 42 --samples 100000
jac replay TRACE.jqd PROGRAM.jqd [--fork '1=(response 500 "down")']
jac test TESTS.jac [TESTS.jqd ...] [--exhaustive] [--cache-dir CACHE]
jac build FILE.jqd -o PROG

.jac 是面向用户的表面载体。引导程序 .jqd 仍然完全支持,作为内部/调试语法、引号表示法和记录格式。runcheckhashfmtdiffinfertest 通过扩展名选择表面语法;原生构建、重放程序、前导以及许多内部固定测试继续使用 .jqd

普通程序和演示仅需要 .jac 源文件。不要手动编写 .jqd 对等文件,除非一致性测试特别需要证明两个载体都能降低到相同的内核和哈希。保留在语料库和选定演示中的成对文件是证据固定测试,而不是创作要求。

原生编译

jacquard build 目前接受内核 .jqd 载体,并将程序及其可达声明编译为独立的二进制文件,其输出与 jacquard run 逐字节相同——标准输出、标准错误和退出码,由 CI 中的差异测试框架固定(scripts/native-diff.sh)。完整的效应语言都能编译,包括捕获和多次恢复的处理器,以及从任务 73 开始的值代码(引号、拼接和结构代码操作)。只有 eval 保留在解释器层级(E1102 策略:动态加载的代码在权限模型所在处运行)。

export JACQUARD_PRELUDE=$PWD/prelude
export JACQUARD_RUNTIME=$PWD/runtime
jac build demos/tooling/word-count.jqd -o word-count
echo "some words some" | ./word-count --allow console

要求和配置:

  • 发布二进制文件会自动发现打包的前导和 C 运行时。源代码检出可以通过设置上述两个变量。
  • C 工具链:clang(任何较新版本)或 gcc。尾调用在所有工具链上都是 O(1) 栈:clang 和 gcc 15+ 使用 musttail,更低版本使用 trampoline(两种方式产生的 C 代码相同)。
  • 二进制文件解析 --allow EFFECT(目前支持 console、clock、fs、dist、infer),--seed N 用于采样授权,并拒绝 --infer-cache--dry-run(解释器工具)并给出明确的错误。
  • JACQUARD_STACK_MB 设置程序栈大小(默认 1024):深度非尾递归在这个后端中就是真实的 C 递归。
  • 编译后的单元在 .jacquard-native/ 下缓存,以内容为键,因此未变动的程序无需重新编译即可重新链接。
  • 测量性能存在于 docs/benchmarks.md 中——九个场景,包含解释器、原生(两种工具链)、Python 和手写 C 列——声明边界在 docs/native-compilation.md 中(使用 scripts/native-bench.sh 可重现)。

演示

dune build @all 之后,从仓库根目录开始查看这些演示。同样的脚本也可以在已安装的 bundle 中运行,无需 opam 或 Dune:

opam exec -- sh demos/case-studies/stormglass/run.sh
opam exec -- sh demos/case-studies/release-risk/run.sh
opam exec -- sh demos/basics/m1.sh
opam exec -- sh demos/inference/m3.sh
opam exec -- sh demos/worlds/agent-dream.sh
opam exec -- sh demos/worlds/preflight.sh
opam exec -- sh demos/tooling/repair.sh

它们展示的内容:

  • case-studies/stormglass/:一个结账策略在模拟网络和时钟定律下的运行、精确事故预测以及覆盖所有 27 个世界的 Warp 证明。
  • case-studies/release-risk/:一个发布策略在具体世界和概率世界下的运行。

相似文章

Jam 编程语言

Lobsters Hottest

Raphael Amorim 宣布了 Jam,一种旨在结合 Rust 的安全性和 Zig 的简洁性的新编程语言,解决了在 AI 生成代码时代现有系统语言的复杂性和验证开销。