
什么是 HEXIS?
HEXIS 是一个 Python 软件包和命令行工具,可将由 SKILL.md 文档表示的代理技能编译为扩展有限状态机。HEXIS 不要求语言模型解释整个技能并选择每一个后续步骤,而是使用程序化状态、变量、守卫条件和转换来强制执行操作顺序。
语言模型仍会在相关状态中执行推理和生成。不过,状态机决定下一步运行哪项操作、哪些变量可用、循环何时必须停止,以及最终到达哪个终止结果。这种设计降低了代理跳过、重新排序或错误应用技能中所写要求的风险。
HEXIS 采用 MIT 许可证发布,目前标记为 alpha 版本软件。它与论文 Compiling Agent Skills into Extended Finite State Machines 配套发布。
核心工作流
典型的 HEXIS 工作流包含三个阶段:
- 编译:模型读取技能文档、任务输入、工具定义和技能规则,然后起草一个
efsm-v1状态机。HEXIS 会检查其架构、守卫条件、可达性、终止性、条款覆盖情况和工具引用。无效草案会返回给模型进行修订。 - 更新:新的执行轨迹会被规范化为事件。对于轨迹中的每一步,模型、决策文件或确定性对齐器会决定是匹配现有状态、创建状态、忽略噪声,还是排除该轨迹。
- 执行:运行时执行与当前状态关联的操作,记录声明的输出,并选择第一个守卫条件计算结果为真的转换。
只有通过所需检查,并且能够重放新轨迹及所有此前已接受轨迹的更新后状态机,才会被接受。如果验证失败,现有状态机保持不变。
主要功能
- 兼容 OpenAI 的编译:可通过命令行选择模型、端点和 API 密钥环境变量。
- 基于轨迹的更新:一次纳入一个决策的成功执行行为,同时不使此前已接受的轨迹失效。
- 可读的 JSON 状态机:状态机采用纯 JSON 的
efsm-v1格式,并包含类型化变量和显式转换。 - 多种操作类型:状态可以执行
tool、model、judge、user或end操作。 - 有界控制流:有序守卫条件和循环计数器支持分支及重试次数限制。
- 生成文档:每次正常构建都会包含
GUIDE.md和PROMPT.md。 - 回退行为:回退状态会从最近的工具步骤重试,也可以将任务交给原始技能的解释执行。
- 工具后端:状态机可以使用 OpenCode 工具、本地 Bash 执行器,或由模型实现的注册表定义工具。
- 纯环境测试:仓库包含超过 350 个测试,不需要 API 密钥、模型端点或网络连接。
安装和前置条件
从 PyPI 安装
HEXIS 要求 Python 3.11 或 3.12。使用 pip 安装软件包:
pip install hexis-agent
在 Python 中导入该软件包时使用 hexis,而其命令行可执行文件名为 hexis-agent。
从代码检出目录安装
pip install .
如需 pytest、Ruff、build 和 Twine 等开发依赖,请使用可编辑安装:
pip install -e ".[dev]"
运行时要求
编译和运行由模型支持的状态机需要兼容 OpenAI 的聊天端点。默认执行后端还要求 OpenCode 位于 PATH 中。如果状态机只需要 Bash,请选择 --executor local,在本地子进程中运行命令而无需 OpenCode。
尝试离线快速开始
软件包包含一个名为 table_clean 的小型纯环境示例。它使用脚本化模型、脚本化工具和内存文件系统,因此无需网络访问即可运行。
from hexis.execution import runtime
from hexis.examples import table_clean as tc
machine = tc.reference_machine()
task = tc.gen_tasks(1, seed=0)[0]
result = runtime.run_task(
machine,
task,
model=tc.build_model(),
tools=tc.build_registry(tc.MemFS(task["files"])),
doc=tc.skill_doc(),
)
print(
result.stopped,
" -> ".join(result.path()),
tc.verify(task, result.trace),
)
该示例应以终止结果结束,打印状态路径,并报告生成的轨迹是否通过示例验证器。这是在配置外部端点之前确认安装成功的实用方法。
配置模型端点
HEXIS 从命令行选项或环境变量中读取模型标识符、基础 URL 和 API 密钥。基本的 shell 配置如下:
export API_KEY=your-key
export MODEL=qwen3.6-flash
export BASE_URL=https://your-endpoint/v1
你也可以将 MODEL、BASE_URL 和 API_KEY 放入 .env 文件。HEXIS 会从工作目录开始向上查找,环境中已存在的变量优先级更高。
如需将可复用的端点参数保存在 shell 变量中:
M="--model qwen3.6-flash --base-url https://your-endpoint/v1"
--api-key-env NAME 选项用于为密钥指定其他环境变量。API 密钥不会通过命令行传递,也不会存储在构建清单中。
将技能编译为机器
将编译器指向技能路径,并选择输出目录:
hexis-agent compile \
--skill path/to/skill \
--out build/ \
$M
技能目录应包含 SKILL.md。它还可以包含 compile.json,用于声明终端、派生事件标签、要求和终端条件。该文件中的每条规则都会引用其派生所依据的句子。
如果不存在 compile.json,编译器会要求模型从技能中提取规则,并根据文档检查引用的文本。随后,有效配置会保存为 rules.json。
构建目录包含的内容
machine.json存储当前机器。machine_init.json保存初始编译机器。build.json记录源信息、命令设置、模型详情、结果和令牌使用情况,但绝不会记录 API 密钥。skill/SKILL.md、tools.json和rules.json保存编译输入。traces/包含构建所用轨迹的哈希副本。progress.json记录轨迹结果以及保护机器的已接受轨迹。decisions.jsonl缓存更新问题及其答案。report.md、context.json和日志文件提供诊断信息。GUIDE.md说明输入、工具、状态、转换、循环和回退行为。PROMPT.md为使用工具的代理提供系统提示,使其能够逐状态执行机器。
理解机器模型
HEXIS 机器是使用 efsm-v1 格式的 JSON 文档。其主要元素包括变量、状态、动作、转换、终端和回退状态。
变量
变量可以通过 init_from 从任务输入字段初始化,也可以通过 init 从常量值初始化。动作只能将结果写入已声明的变量。
动作
- 模型:根据特定状态的提示和选定的输入变量生成已声明的变量。
- 工具:调用命名工具。运行时会替换
${command}等引用。 - 判定器:从固定集合中选择一个标签,或返回
abstain标签。 - 用户:请求用户输入。
- 结束:以终端结果停止执行。
转换和守卫条件
状态动作完成后,系统会按顺序评估转换。运行时会采用第一个守卫条件成立的转换。空守卫条件表示无条件转换,应放在最后。转换还可以通过 inc 增加计数器,从而实现有界重试循环。
守卫条件使用由 hexis.machine.cond 实现的受限表达式语言。它支持对互斥性和循环边界等属性进行静态分析,并且不会使用 Python 的 eval。
根据轨迹更新机器
执行轨迹是 JSON Lines 文件。它们以任务元数据和判定结果开头,后面每行包含一个事件。轨迹可以包含工具调用、模型输出和结束事件。
首先预览待处理轨迹,不进行模型调用,也不写入更改:
hexis-agent update \
--build build/ \
--traces traces/ \
--show 3
然后执行更新:
hexis-agent update \
--build build/ \
--traces traces/ \
$M
对于每个轨迹步骤,判定器会选择以下四种结果之一:
match复用现有状态,并在必要时添加转换。new根据所述目的创建状态。ignore将测试框架噪声排除在考虑范围之外。exclude排除整个轨迹。
模型的回答还会标识候选状态,描述该步骤的目的,并可将其关联到某条技能条款。HEXIS 会验证生成的候选机器,并在接受之前重放所有受保护轨迹。
恢复并控制更新成本
模型回答会缓存到 decisions.jsonl 中。重复执行相同命令会复用这些回答;退出状态为 3 的中断运行可以从已保存的进度恢复。只有在明确希望模型重新回答时,才使用 --no-cache。
一次更新通常每个轨迹步骤需要调用模型一次。使用 --max-traces N 限制运行范围。若要使用无模型替代方案,可以通过 --decisions FILE 提供人工或外部决策,或者使用 --decider align 选择确定性对齐。
在处理新轨迹之前,HEXIS 会检查当前机器并重放每条已接受的轨迹。如果手动编辑或工具定义发生变化导致构建损坏,命令会以状态 2 退出,且不会修改构建。
运行已编译的机器
执行前请检查 build/GUIDE.md。其中记录了所需的任务输入、可用工具、状态动作、转换顺序、重试限制和回退行为。
使用键值形式的任务输入运行机器:
hexis-agent run \
--machine build/ \
--input request="Process this task" \
--workdir work/ \
--executor local \
$M
为机器所需的每个输入传递额外的 --input KEY=VALUE 选项。要将执行结果保存为可重复使用的 JSON Lines 跟踪记录,请添加:
--json run-trace.jsonl
默认执行器使用 OpenCode 工具。本地执行器会在子进程中运行 Bash 命令。在运行时,机器只能使用其后端提供的工具或工具注册表中定义的工具;HEXIS 不会静默替换缺失的工具。
从 Python 使用机器
核心运行时入口是 hexis.execution.runtime.run_task。请提供一个已加载的机器、包含 input 对象的任务、模型适配器、工具注册表,以及在回退执行可能需要时使用的技能文档。
from hexis.execution import runtime
result = runtime.run_task(
machine,
{"input": {
"request": "Answer the question",
"output_path": "answer.txt",
}},
model=model,
tools=tools,
doc=skill_document,
)
print(result.stopped)
print(result.path())
print(result.trace)
相关 API 包括用于加载机器的 hexis.machine.schema.load_machine、用于配置端点的 hexis.llm.llm_client.client_from_env,以及用于渲染指南、提示词和 Mermaid 图表的 hexis.guide 函数。
使用随附的示例机器
仓库在 examples/machines/ 下包含四个已编译的机器:
- dabench: 使用计算结果回答关于数据文件的数据分析问题。
- livemath: 回答基于定理的数学选择题。
- sealqa: 从本地语料库中回答问题,并提供证据。
- spreadsheet: 编辑工作簿,同时不改变其结构。
这些机器通常使用模型状态编写 shell 命令,使用工具状态执行命令,根据 returncode 进行受保护的重试,使用工具步骤读回答案,再由判断状态选择已验证或未验证的终端状态。
例如,使用以下命令运行 LiveMath 机器:
hexis-agent run \
--machine examples/machines/livemath \
--input request="..." \
--input output_path=answer.txt \
--workdir work/ \
--executor local \
$M
无需模型即可加载并进行结构检查示例机器,但运行它们需要配置模型端点。
高级提示
重新生成文档
除非使用 --no-guide,否则编译和更新操作会自动生成文档。使用以下命令手动重新生成:
hexis-agent guide --build build/
也可以直接将命令指向 machine.json。如果希望生成的代理提示词包含原始技能,请添加 --embed-skill,这样回退后即可进行解释执行。
提供显式工具定义
当机器使用自定义工具时,传递 --tools registry.json。编译期间,工具名称会被视为不透明标识符。在运行时,注册表定义的工具可以由模型实现为 shell 命令,而原生工具必须由所选后端提供。
调整模型请求
编译和更新支持包括 --temperature、--max-tokens、--llm-timeout、--llm-retries、--stream 和 --extra-body JSON 在内的选项。对于兼容 Qwen 的端点,可以使用 --no-think、--think-budget 和 --judge-think-budget 控制运行时推理。
使用提供商专用的环境变量
--provider NAME 选项会读取 NAME_MODEL、NAME_BASE_URL 和 NAME_API_KEY。MiniMax 和 DeepSeek 提供商名称有内置默认值。
了解退出状态
0表示成功。2表示使用、配置或构建问题。3表示模型端点故障或中断;进度会保存以便恢复。
运行开发检查
pytest
ruff check src tests
python -m build && twine check --strict dist/*
测试套件是自包含的。当 opencode 可执行文件不可用时,特定于 OpenCode 的测试会被跳过。
安全与隐私
HEXIS 可以执行由语言模型生成的工具参数,包括 shell 命令。请在隔离环境中运行不受信任的工作负载,并且只使用你信任的机器、技能、注册表和任务文件。
更新过程会将跟踪步骤、缩短后的工具结果和技能条款发送到配置的模型端点。构建目录会保留跟踪副本和模型问题。此外,PROMPT.md 包含完整的机器以及根据技能生成的提示词。分享这些文件前请先进行检查。
运行时会将每次模型调用限制在当前执行状态的提示词范围内,而不是让每次调用都暴露整个机器。
结语
HEXIS 将自然语言代理指令转化为明确且经过验证的工作流。通过在状态中结合模型推理与程序化转换、跟踪重放、有界重试、工具限制、生成式指南和回退处理,它提供了一种让技能执行更加可预测的结构化方式。请从离线示例开始,编译一个小型且可信的技能,检查生成的指南,然后逐步引入跟踪记录,同时监控验证结果。
