Open Interpreter 钩子(Hooks)机制完全指南:在代理生命周期关键节点执行受信任的确定性脚本
导读
Open Interpreter 的钩子(Hooks)机制允许你在代理(Agent)运行生命周期的特定时点,以确定性的方式触发外部命令或脚本——例如在模型调用 shell / 补丁 / MCP 工具之前做策略检查、在会话启动时注入自定义上下文、对用户提示做扫描与记录、或在回合结束后做运行验证。本文以 docs/zh/hooks.md 为主体骨架,结合仓库中 hooks 模块 的 Rust 实现与 配置模块 的源码细节,完整覆盖钩子的启用方式、存放位置与信任模型、全部生命周期事件、JSON/TOML 两种配置形态、匹配器规则,以及命令钩子与宿主之间的输入输出协议。读完本文,你将能够独立编写、托管并安全运维自己的钩子脚本,把策略与治理能力精确嵌入 Open Interpreter 的每一步动作。
钩子机制概述与适用场景
钩子让你能够在 Open Interpreter 事件的前后运行确定性的命令。文档明确列举了四类典型诉求:
- 策略检查(policy checks):在危险命令真正执行前拦下它;
- 日志记录(logging):把模型每次调用的工具、参数与结果落盘留痕;
- 提示扫描(prompt scanning):在用户提示进入模型之前做敏感信息过滤;
- 自定义上下文注入(custom context injection):把仓库状态、环境信息等注入到模型可见的上下文里;
- 运行后验证(post-run validation):工具执行完成后做结果校验。
关键设计定位:钩子是可选的“生命周期脚本”,是安全护栏(guardrails),而不是沙箱(sandboxing)与批准(approvals)机制的替代品。若你期望强隔离与强授权,仍需依赖 Open Interpreter 自身的沙箱与权限批准体系,二者应组合使用。
默认启用与特性开关
钩子在配置中以特性开关控制,默认启用:
[features]
hooks = true
只有在明确不希望有任何生命周期脚本的情况下才应关闭:
[features]
hooks = false
features.hooks 也收录在 docs/zh/config-reference.md 的特性开关表中(默认值为 on)。关闭它意味着本次运行完全不会发现、校验或执行任何钩子。
钩子存放在哪里:配置层级与发现规则
Open Interpreter 在活动配置层旁边(next to active config layers)发现钩子。也就是说,钩子不是散落在任意目录,而是跟随用户级与项目级(受信任的)配置层一起被发现:
| 位置 | 作用域 |
|---|---|
~/.openinterpreter/hooks.json |
用户 |
~/.openinterpreter/config.toml |
用户内联钩子 |
.openinterpreter/hooks.json |
受信任的项目 |
.openinterpreter/config.toml |
受信任的项目内联钩子 |
| Enabled plugins | 插件捆绑的钩子 |
两个要点:
- 多来源并存时全部运行。文档明确:如果匹配到多个来源,它们全部运行;
- 高优先级配置不会替代低优先级层。即使上层配置中存在同名钩子组,低层来源的钩子依旧会被执行。
这一点在源码的“发现”流程中也有对应结构:钩子发现逻辑会遍历配置层栈(ConfigLayerStack,从低到高逐层收集 handlers),再叠加 config.toml 内联钩子、同目录的 hooks.json,以及由已启用插件声明的插件钩子来源(PluginHookSource)。每个来源最终都会转换为一个或多个 ConfiguredHandler 参与调度,相关实现见 codex-rs/hooks/src/engine/discovery.rs。
内联配置与独立文件:两种写法等价
钩子既可以内联写在 config.toml 的 [hooks] 段下,也可以放在与配置层同目录的 hooks.json 中(见 docs/zh/config-reference.md “钩子”小节)。两种格式的数据模型完全一致(事件名 → 匹配器组 → 处理函数列表),下文给出 JSON 与 TOML 的对应写法。
信任模型:未受管理的命令钩子必须先审查、后信任
钩子会以你的权限执行外部命令,因此 Open Interpreter 对“非受管理(non-managed)的命令钩子”建立了信任门槛:
- 运行前必须经过审查并获得信任;
- Open Interpreter 针对“精确的钩子定义”记录信任状态——换句话说,只要钩子的命令、参数或定义有任何一处变更,就需要重新审查、重新信任。
在会话内,你可以使用斜杠命令管理钩子:
/hooks
对于已经通过外部自动化流程验证过钩子的场景,可以传入命令行参数跳过信任交互,但这应当很少使用:
--dangerously-bypass-hook-trust
从配置源码看,信任状态沉淀在钩子状态表(HookStateToml)中,每条记录包含 enabled(是否启用)与 trusted_hash(定义哈希,用于探测定义变更)两个字段,见 codex-rs/config/src/hook_config.rs。这正是“定义变更即需重新信任”的底层依据:状态以定义哈希为键,哈希不匹配便视为新的待信任定义。
插件声明的钩子
“Enabled plugins(插件捆绑的钩子)”属于被信任来源的一部分。从源码测试可以看到插件钩子会生成带来源标识的持久化键(hook key),其格式形如:
{plugin_id}:{source_relative_path}:{event}:{group_index}:{handler_index}
例如 demo@test:hooks/hooks.json:pre_tool_use:0:0,把“哪个插件、哪个文件、哪个事件、哪一组、第几个处理器”精确地编码进信任记录,声明逻辑见 codex-rs/hooks/src/declarations.rs。
生命周期事件一览
Open Interpreter 把钩子挂在代理生命周期的多个“事件”上。文档给出的事件表如下:
| Event | 触发时机 |
|---|---|
SessionStart |
会话启动、恢复、清除或压缩时。 |
UserPromptSubmit |
用户提示即将发送时。 |
PreToolUse |
在支持的 shell、patch 或 MCP 工具运行之前。 |
PermissionRequest |
在显示批准提示之前。 |
PostToolUse |
在支持的 shell、patch 或 MCP 工具完成之后。 |
PreCompact |
在上下文压缩之前。 |
PostCompact |
在上下文压缩之后。 |
SubagentStart |
子代理启动时。 |
SubagentStop |
子代理停止时。 |
Stop |
回合即将结束时。 |
源码层面的补充:从配置数据结构 HookEventsToml 与事件实现目录看,实际事件集合还会出现 SessionEnd(会话结束)一项——它被定义在 codex-rs/config/src/hook_config.rs 的枚举字段中,并有独立的输入协议 codex-rs/hooks/schema/generated/session-end.command.input.schema.json 与实现文件 codex-rs/hooks/src/events/session_end.rs(其实现中还定义了 SESSION_END_DEFAULT_TIMEOUT_SEC / SESSION_END_MAX_TIMEOUT_SEC 等专用超时常量)。因此在配置事件时,除上述表格中的事件外,SessionEnd 也是一个合法的配置键(配置解析见 into_matcher_groups 对 11 个事件的一一映射)。
事件在架构上大致可以分为三类能力:
- 可阻断/拦截型:如
PreToolUse可以拒绝一次工具调用,SessionStart可通过输出协议中止本轮; - 可注入上下文型:部分事件(如
SessionStart、SubagentStart)可以把 stdout 或additionalContext变成模型可见的上下文; - 纯观测/记录型:多数事件都可用于把运行信息输出到日志/审计通道。
每类事件的触发结构都有独立的 Rust 事件实现文件(PreToolUse、PostToolUse、SessionStart、SessionEnd、UserPromptSubmit、PermissionRequest、Compact、Stop、子代理起止等),统一放在 codex-rs/hooks/src/events/ 下。
配置文件格式:JSON 形态与 TOML 形态
JSON Form(hooks.json)
{
"hooks": {
"PreToolUse": [
{
"matcher": "^Bash$",
"hooks": [
{
"type": "command",
"command": "python3 .openinterpreter/hooks/pre_tool_use.py",
"timeout": 30,
"statusMessage": "Checking command"
}
]
}
]
}
}
TOML Form(config.toml 内联,与 hooks.json 完全等价)
[[hooks.PreToolUse]]
matcher = "^Bash$"
[[hooks.PreToolUse.hooks]]
type = "command"
command = "python3 .openinterpreter/hooks/pre_tool_use.py"
timeout = 30
statusMessage = "Checking command"
上面的 TOML 写法原样出现在 docs/zh/config-reference.md 的“钩子”小节中,说明它可以直接作为 config.toml 内联配置使用。
处理函数(handler)字段详解
从 codex-rs/config/src/hook_config.rs 的配置模型看,type = "command" 的处理函数支持以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
type |
字符串 | 处理器类型,command(执行外部命令)。配置枚举中还存在 prompt、agent 两种声明类型。 |
command |
字符串 | 要执行的命令,例如 python3 .openinterpreter/hooks/pre_tool_use.py。 |
commandWindows(别名 command_windows) |
字符串(可选) | 可选。为 Windows 平台单独指定的命令变体,便于跨平台部署同一份配置。 |
timeout(配置字段 timeout_sec) |
整数(可选) | 可选。命令执行超时(秒)。默认没有限制时依赖引擎侧约定;钩子命令若超过超时会被终止并按失败处理。 |
statusMessage(配置字段 status_message) |
字符串(可选) | 可选。运行期间的进度提示文案,例如 Checking command,会在交互界面展示给用户。 |
async |
布尔 | 是否异步执行,默认 false。 |
additionalContextLimit |
整数(可选) | 可选。该钩子 additionalContext 溢出落盘的近似 token 阈值。未设置时使用 2500 token;0 表示禁止该钩子落盘;阈值按原始上下文计算,落盘的预览内容还会附带恢复元数据。 |
对应的 JSON 反序列化模型同样支撑这些字段(字段序列化采用小驼峰,与上文 TOML 示例中的 statusMessage、commandWindows 一致),完整结构见 codex-rs/config/src/hook_config.rs。
结构提示:一组“匹配器 + 若干处理器”被称为
MatcherGroup(matcher为可选项,可省略),同事件下可配置多个MatcherGroup。从源码结构看,省略matcher意味着该组钩子对该事件的所有实例生效;而命中同一事件同一 matcher 的多个来源(用户层、项目层、插件层)会全部运行而非互相覆盖。
匹配器(Matchers):用正则精确圈定触发范围
匹配器是正则表达式,用于把事件限制到你关心的子集。文档明确支持的匹配目标包括:
- 工具事件(
PreToolUse/PostToolUse/PermissionRequest等与工具相关的):匹配工具名称; SessionStart:匹配startup|resume|clear|compact四种触发来源;- 压缩事件(
PreCompact/PostCompact):匹配manual|auto。
从源码实现看,SessionStart 的四种来源对应枚举 SessionStartSource(Startup / Resume / Clear / Compact,其 as_str() 恰为 startup / resume / clear / compact),并被作为该事件的 matcher 输入参与调度,见 codex-rs/hooks/src/events/session_start.rs。
文档给出的正则示例:
Bash
^apply_patch$
Edit|Write
mcp__filesystem__read_file
startup|resume
manual|auto
其中:
Bash匹配工具名为Bash的工具调用(未锚定,等价于“名称中包含 Bash”也能命中,可用^Bash$精确限定);^apply_patch$精确匹配apply_patch补丁工具;Edit|Write匹配文件编辑类工具(Edit或Write);mcp__filesystem__read_file演示了 MCP 工具在事件中的命名形态(MCP 工具前缀 + 服务器名 + 工具名);startup|resume让SessionStart钩子只在新会话启动与恢复时触发;manual|auto让压缩钩子同时覆盖手动压缩与自动压缩。
由于是正则表达式,你也可以组合使用,例如 ^(Bash|apply_patch)$ 同时圈住 shell 与补丁两类工具。事件实现中,调度器(dispatcher)会先按“事件名 + matcher 输入”选出命中的处理器(handlers),再逐个执行——匹配失败则该事件下没有任何钩子运行(见 codex-rs/hooks/src/events/session_start.rs 的 run 函数中 matched.is_empty() 早退分支)。
命令钩子的输入与输出协议
输入:一行 stdin JSON
命令钩子会在 stdin 上收到一个 JSON 对象,包含通用字段与会话/事件相关字段。文档列出的通用字段包括:session_id、cwd、hook_event_name、model,以及事件特有字段。
以 PreToolUse 的输入协议为例,其 JSON Schema 定义在 codex-rs/hooks/schema/generated/pre-tool-use.command.input.schema.json,完整字段如下:
| 字段 | 类型 | 说明 |
|---|---|---|
session_id |
string | 会话/线程 ID |
cwd |
string | 工作目录 |
hook_event_name |
string | 固定为 PreToolUse |
model |
string | 当前使用的模型 |
permission_mode |
string(枚举) | default / acceptEdits / plan / dontAsk / bypassPermissions |
tool_name |
string | 工具名称(如 Bash、apply_patch 或 MCP 工具名) |
tool_use_id |
string | 本次工具调用的唯一 ID |
tool_input |
object | 工具入参。shell 类工具形如 { "command": "..." },MCP 工具为解析后的 JSON 参数 |
turn_id |
string | 当前轮次 ID |
agent_id / agent_type |
string | 子代理场景下的代理标识(PreToolUseRequest 的 subagent 上下文中序列化而来) |
transcript_path |
string/null(可选) | 会话转录文件的路径 |
实现上,PreToolUse 的 stdin 由 codex-rs/hooks/src/events/pre_tool_use.rs 的 command_input_json 序列化:handler 选择时可能使用内部 matcher 别名,但 stdin 中始终保留规范化的 tool_name,从而保证审计日志与下游策略判定稳定。
一个典型的钩子脚本开头可以这样解析输入(Python 示例,对应文档中的 python3 .openinterpreter/hooks/pre_tool_use.py):
import json
import sys
payload = json.load(sys.stdin)
print(f"[hook] {payload['hook_event_name']} "
f"session={payload['session_id']} tool={payload['tool_name']}",
file=sys.stderr)
输出:stdout 的含义取决于事件与解析器
钩子退出后,引擎会根据退出码、stdout/stderr 内容与事件类型做统一解释,规则可归纳为:
- 退出码 0:命令成功。此时对 stdout 的解读取决于事件:
- 若 stdout 为空:无副作用;
- 若 stdout 是合法的事件 JSON 输出:按事件协议处理(阻断、注入上下文、改写入参等);
- 若 stdout 形似 JSON 但非法:该次钩子运行会被标记为失败(错误信息如
hook returned invalid pre-tool-use JSON output),避免把损坏的 JSON 当普通文本注入; - 在支持“上下文注入”的事件(如
SessionStart/SubagentStart)中,普通纯文本 stdout 会被直接当作模型上下文(源码测试plain_stdout_becomes_model_context即验证了此行为)。
- 退出码 2:对
PreToolUse而言是一种内置阻断语义——stderr 中的非空文本会被作为阻断原因(见 codex-rs/hooks/src/events/pre_tool_use.rsSome(2)分支;文档未显式描述,属于实现层约定,可直接理解为“以退出码表达拒绝”的轻量写法); - 其他非零退出码:钩子运行失败,按该事件策略记录错误(错误文本形如
hook exited with code {exit_code}); - 进程被信号终止或无状态码:记为失败。
这些解析规则沉淀在钩子引擎的 output_parser 与各事件的 parse_completed 中,并有成体系的单元测试(如 codex-rs/hooks/src/events/pre_tool_use.rs 内的 tests 模块、codex-rs/hooks/src/events/session_start.rs 内的 tests 模块)逐条验证退出码与 JSON 组合的判定结果。
事件特定输出示例:PreToolUse 拒绝一次调用
某些事件可以阻止或拒绝工具调用。 例如,PreToolUse 钩子可以拒绝一次命令,只需在 stdout 输出如下 JSON:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Blocked by repository policy."
}
}
该行为的官方输出协议见 codex-rs/hooks/schema/generated/pre-tool-use.command.output.schema.json,其关键字段包括:
- 顶层:
systemMessage(告警文案)、suppressOutput、stopReason、continue(默认true); - 顶层兼容字段:
decision(approve/block)、reason(旧版兼容形态); hookSpecificOutput下:hookEventName(必填,PreToolUse);permissionDecision:allow/deny/ask;permissionDecisionReason:决策原因,会作为反馈展示给模型/用户;additionalContext:注入模型可见上下文的文本;updatedInput:改写后的工具入参。
对照事件实现的解析逻辑与单元测试,可以确认以下可验证行为(codex-rs/hooks/src/events/pre_tool_use.rs):
permissionDecision = "deny"→ 本次调用被阻断(should_block = true),permissionDecisionReason作为阻断原因与反馈记录(测试permission_decision_deny_blocks_processing);permissionDecision = "allow"并携带updatedInput→ 放行,且用改写后的入参执行(测试permission_decision_allow_can_update_input,例如把{"command":"echo hello"}改写为{"command":"echo rewritten"});- 多个钩子同时给出
updatedInput时,按实际完成顺序取最后完成的那个改写(latest_updated_input,测试last_completed_updated_input_wins用completion_order验证),而非按配置顺序——用于审计展示的顺序保持稳定,但改写竞争以完成时序为准; - 返回不支持的决策组合(如
permissionDecision = "ask",或旧版decision: approve而无有效 allow 语义)→ 运行被记录为失败,但不阻断本次调用(测试中命名为 fails open); - 旧版形态
decision: "block"+reason仍然有效,会被映射为阻断。
一句话总结:deny 是硬阻断,allow + updatedInput 是软改写,其余非法组合按失败记录但放行(fail-open)。
事件特定输出示例:SessionStart 注入上下文与停止
SessionStart / SubagentStart 属于“可以向模型可见上下文添加内容”的事件。其输出协议见 codex-rs/hooks/schema/generated/session-start.command.output.schema.json,hookSpecificOutput 内含 additionalContext(模型可见的注入文本),顶层另有 stopReason、suppressOutput、systemMessage、continue 等字段。
实现层的行为(codex-rs/hooks/src/events/session_start.rs):
- 普通 stdout 直接成为模型上下文:只要退出码为 0 且 stdout 不是 JSON,stdout 全文(去空白)即注入为上下文(测试
plain_stdout_becomes_model_context); continue: false可以停止本轮:SessionStart钩子返回{"continue":false,"stopReason":"pause",...}时,会话会暂停(HookRunStatus::Stopped),同时additionalContext仍被保留供后续轮次使用(测试continue_false_preserves_context_for_later_turns注释“do not inject”恰好演示了这一点);SubagentStart只做上下文注入:从实现注释与测试看,SubagentStart忽略continue:false(测试subagent_start_continue_false_is_ignored),即子代理启动钩子仅负责注入子代理上下文,不承担中止职责。
大上下文溢出处理(additional context spilling)
当钩子注入的上下文很大时,Open Interpreter 并不会无限膨胀模型上下文。实现里存在一个“溢出落盘(spill)”通道(codex-rs/hooks/src/output_spill.rs):在输出 schema 允许 additionalContext 的事件中,注入文本会先按 token 阈值评估——未显式配置时阈值默认约 2500 token(DEFAULT_HOOK_OUTPUT_TOKEN_LIMIT,常量在引擎中发现/执行路径中引用),超出部分被溢出保存,模型侧只保留带恢复元数据的预览。你可以在命令处理器上通过 additionalContextLimit 字段覆盖阈值(0 表示禁止溢出、始终全量注入),这也是“确定性 + 可控性”的体现。
结合仓库源码理解整体架构
hooks 功能对应的主要源码位置(仓库根目录下相对路径):
| 关注点 | 路径 |
|---|---|
| 官方中文文档(本文主体) | docs/zh/hooks.md |
| 英文原档 | docs/hooks.md |
| 钩子引擎:发现、调度、命令执行、输出解析 | codex-rs/hooks/src/engine/(discovery.rs / dispatcher.rs / command_runner.rs / output_parser.rs) |
| 各生命周期事件实现 | codex-rs/hooks/src/events/ |
| 钩子输入/输出 JSON Schema | codex-rs/hooks/schema/generated/ |
| 钩子配置数据模型(JSON/TOML/内联/状态) | codex-rs/config/src/hook_config.rs |
| 插件钩子声明与持久化键 | codex-rs/hooks/src/declarations.rs |
| 上下文溢出落盘 | codex-rs/hooks/src/output_spill.rs |
配置参考文档(含内联钩子示例与 features.hooks) |
docs/zh/config-reference.md |
从源码结构可以勾勒出一次钩子运行的完整链路:
- 发现(discovery):
discover_handlers遍历配置层栈,把内联config.toml钩子、同目录hooks.json、受管理钩子要求(managed hooks)与插件钩子全部物化为ConfiguredHandler(每个处理器携带事件名、matcher、命令、超时、来源与展示顺序),见 codex-rs/hooks/src/engine/discovery.rs; - 选择(dispatch):事件触发时,调度器按“事件名 + matcher 输入”筛选命中的处理器(事件实现中以
preview()生成待运行摘要、run()实际执行),见 codex-rs/hooks/src/events/session_start.rs 与 codex-rs/hooks/src/engine/dispatcher.rs; - 执行与解析(execute & parse):
command_runner以 cwd 为基准运行命令并把 stdin JSON 交给脚本,随后按上文输出规则解析退出码/stdout,产出每一条HookCompletedEvent(含状态Completed/Failed/Blocked/Stopped)与最终结果(是否阻断、注入哪些上下文、是否改写入参)。
这些“事件 → 匹配器组 → 处理器 → 结果聚合”的每一步都有对应单元测试覆盖,例如 codex-rs/hooks/src/events/session_start.rs 的 tests 模块、codex-rs/hooks/src/events/pre_tool_use.rs 的 tests 模块(含插件钩子键格式验证、permissionDecision 语义矩阵、改写竞争等),可作为你自建钩子的行为参考。
实操建议与边界提醒
- 把钩子当作“策略层”而非“功能层”:日志、审计、扫描、注入这类确定性职责非常适合钩子;而应当由模型自主决策的内容不建议硬编码进钩子。
- 为钩子命令显式设置超时:为每个
type = "command"处理器配置合理的timeout,避免某个钩子脚本卡死整轮代理动作;跨平台部署时可用commandWindows为 Windows 提供等价命令。 - 正确理解 trust 边界:修改钩子定义后记得重新执行
/hooks审查并信任新定义;仅在外部已做同等验证时才使用--dangerously-bypass-hook-trust。 - 用 matcher 收敛触发面:尽量使用锚定正则(如
^Bash$)精确圈定要拦截的工具,避免宽泛匹配拖慢每一次工具调用。 - 组合使用安全体系:再次强调文档结论——钩子是安全防护措施,而不是沙箱和批准的替代方案。需要强隔离的执行环境时,应配合 Open Interpreter 的沙箱与批准机制,形成“批准先行、沙箱兜底、钩子审计/拦截”的多层防线。
掌握以上配置语法、事件语义与协议细节之后,你就可以把任意受信任的确定性逻辑(策略、日志、扫描、上下文、运行后校验)精确嵌入到 Open Interpreter 的每一步生命周期事件中。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00