<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Hook on KnightLi的博客</title>
        <link>https://knightli.com/tags/hook/</link>
        <description>Recent content in Hook on KnightLi的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Thu, 11 Jun 2026 11:57:18 +0800</lastBuildDate><atom:link href="https://knightli.com/tags/hook/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>别只会用 Codex：Hook 才是进阶玩法</title>
        <link>https://knightli.com/2026/06/11/codex-hooks-advanced-usage/</link>
        <pubDate>Thu, 11 Jun 2026 11:57:18 +0800</pubDate>
        
        <guid>https://knightli.com/2026/06/11/codex-hooks-advanced-usage/</guid>
        <description>&lt;p&gt;很多人用 Codex 时，重点都放在“让它帮我写代码、改文件、跑命令”。这当然是 Codex 最直观的能力，但如果只停留在这里，很容易忽略一个更适合进阶使用的功能：&lt;code&gt;Hook&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Hook 的价值不在于让 Codex 更会写代码，而在于让 Codex 更按规矩工作。它可以在 Codex 的关键生命周期事件里运行自定义脚本，例如用户提交提示词时、工具调用前、工具调用后、请求权限时、会话停止时等。这样一来，你可以把团队规则、安全检查、隐私保护和自动化记录放进 Codex 的工作流里，而不是每次都靠人工提醒。&lt;/p&gt;
&lt;p&gt;一个典型例子是隐私检查：当用户把 prompt 发给 Codex 前，先用 Hook 扫一遍是否包含 API key、token、私钥、手机号、内部地址或其他敏感信息。如果命中规则，就阻止这次提交，或者给出明确提示，让用户先清理内容。&lt;/p&gt;
&lt;h2 id=&#34;hook-是什么&#34;&gt;Hook 是什么
&lt;/h2&gt;&lt;p&gt;Codex Hook 可以理解为 Codex 工作流里的生命周期处理器。它会在指定事件发生时触发，并把当前上下文以 JSON 形式传给你的脚本。脚本可以返回提示信息、附加上下文，也可以在部分事件里阻止后续动作。&lt;/p&gt;
&lt;p&gt;官方文档里提到，Hook 可以用于这些场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把对话发送到自定义日志或分析系统；&lt;/li&gt;
&lt;li&gt;扫描团队 prompt，阻止误贴 API key；&lt;/li&gt;
&lt;li&gt;自动总结对话，生成持久记忆；&lt;/li&gt;
&lt;li&gt;在一轮对话结束时运行自定义校验；&lt;/li&gt;
&lt;li&gt;根据当前目录补充特定提示或规则。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以 Hook 更像一层“工作流控制”和“安全护栏”，而不是普通的提示词技巧。提示词告诉 Codex 应该怎么做，Hook 则能在 Codex 做事前后插入检查、记录和约束。&lt;/p&gt;
&lt;h2 id=&#34;hook-放在哪里&#34;&gt;Hook 放在哪里
&lt;/h2&gt;&lt;p&gt;Codex 可以从 &lt;code&gt;hooks.json&lt;/code&gt; 加载 Hook，也可以从 &lt;code&gt;config.toml&lt;/code&gt; 里的 &lt;code&gt;[hooks]&lt;/code&gt; 表加载内联配置。常用位置有四个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.codex/hooks.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.codex/config.toml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;repo&amp;gt;/.codex/hooks.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;repo&amp;gt;/.codex/config.toml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用户级 Hook 适合放个人通用规则，例如“不要把疑似密钥发送出去”“每次结束时做摘要”。项目级 Hook 适合放仓库规范，例如“禁止直接改生成目录”“提交前检查 front matter”“运行命令前拦截危险操作”。&lt;/p&gt;
&lt;p&gt;需要注意的是，项目级 &lt;code&gt;.codex/&lt;/code&gt; 配置只有在该项目层被信任后才会加载；用户级 Hook 则不依赖项目是否被信任。这个设计很重要，因为项目里的 Hook 本质上是会执行本地脚本的配置，不能对陌生仓库无条件信任。&lt;/p&gt;
&lt;h2 id=&#34;常见触发时机&#34;&gt;常见触发时机
&lt;/h2&gt;&lt;p&gt;Hook 不是只有一个触发点。不同事件适合不同用途。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;UserPromptSubmit&lt;/code&gt; 发生在用户 prompt 即将提交时。它适合做隐私检查、敏感词检查、提示词规范检查。比如发现 prompt 里疑似包含 &lt;code&gt;sk-&lt;/code&gt; 开头的 key，就直接阻止提交。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PreToolUse&lt;/code&gt; 发生在 Codex 调用工具前。它适合拦截命令、文件写入或 MCP 工具调用。例如检测到 &lt;code&gt;rm -rf&lt;/code&gt;、向系统目录写文件、读取敏感路径，就返回拒绝理由。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PermissionRequest&lt;/code&gt; 发生在 Codex 准备请求权限时。它适合自动批准或拒绝某些明确的权限请求。比如团队可以允许固定的测试命令自动通过，但拒绝访问某些目录。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PostToolUse&lt;/code&gt; 发生在工具执行后。它适合检查命令输出、扫描生成文件、提醒后续步骤。它不能撤销已经发生的副作用，但可以让 Codex 在继续前看到额外反馈。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SessionStart&lt;/code&gt; 发生在会话开始或恢复时。它适合加载项目约定、团队规范、常用上下文或本地提示。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Stop&lt;/code&gt; 发生在一轮响应准备停止时。它适合做收尾检查，例如确认是否运行测试、是否还存在 TODO、是否需要继续补一轮验证。&lt;/p&gt;
&lt;h2 id=&#34;一个隐私检查-hook-应该怎么设计&#34;&gt;一个隐私检查 Hook 应该怎么设计
&lt;/h2&gt;&lt;p&gt;隐私检查最适合放在 &lt;code&gt;UserPromptSubmit&lt;/code&gt;，因为它发生在用户内容真正进入 Codex 工作流之前。设计时不要追求一步到位，先覆盖最容易误贴的内容就够了。&lt;/p&gt;
&lt;p&gt;可以优先检查这些模式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenAI、GitHub、云厂商等 API key；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-----BEGIN PRIVATE KEY-----&lt;/code&gt; 这类私钥块；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.env&lt;/code&gt; 文件片段；&lt;/li&gt;
&lt;li&gt;访问令牌、Bearer token、JWT；&lt;/li&gt;
&lt;li&gt;内网域名、数据库连接串；&lt;/li&gt;
&lt;li&gt;身份证、手机号、邮箱等个人信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hook 脚本接收 JSON 输入后，读取其中的 &lt;code&gt;prompt&lt;/code&gt; 字段，使用正则或规则表扫描。如果发现问题，可以返回阻止结果：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;block&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;reason&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;检测到疑似 API key，请先移除敏感信息后再提交。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可以不阻止，只返回额外上下文，让 Codex 在后续回答中注意某些约束。不过对于密钥、私钥和令牌这类高风险内容，更稳妥的做法是直接阻止。&lt;/p&gt;
&lt;h2 id=&#34;hooksjson-配置示例&#34;&gt;&lt;code&gt;hooks.json&lt;/code&gt; 配置示例
&lt;/h2&gt;&lt;p&gt;如果使用仓库级配置，可以创建 &lt;code&gt;.codex/hooks.json&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;hooks&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;UserPromptSubmit&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;hooks&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;python .codex/hooks/privacy_check.py&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;timeout&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;statusMessage&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Checking prompt privacy&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;对应的脚本可以从标准输入读取 JSON：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;re&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;payload&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stdin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;prompt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;payload&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;prompt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;patterns&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;sk-[A-Za-z0-9_-]{20,}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;ghp_[A-Za-z0-9_]{20,}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;-----BEGIN [A-Z ]*PRIVATE KEY-----&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Bearer\s+[A-Za-z0-9._-]{20,}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;patterns&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prompt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dumps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;s2&#34;&gt;&amp;#34;decision&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;block&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;s2&#34;&gt;&amp;#34;reason&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;检测到疑似密钥、令牌或私钥，请先移除敏感信息。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ensure_ascii&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个示例只演示思路，实际使用时应该把规则拆成可维护的列表，并控制误报。比如普通文档里出现 &lt;code&gt;Bearer&lt;/code&gt; 示例不一定就是泄露，项目里也可能有专门用于测试的假 key。规则越严格，越容易误拦；规则越宽松，越容易漏掉真正的风险。&lt;/p&gt;
&lt;h2 id=&#34;configtoml-内联写法&#34;&gt;&lt;code&gt;config.toml&lt;/code&gt; 内联写法
&lt;/h2&gt;&lt;p&gt;如果不想单独维护 &lt;code&gt;hooks.json&lt;/code&gt;，也可以写在 &lt;code&gt;config.toml&lt;/code&gt; 里。官方文档示例中，内联 TOML Hook 和 &lt;code&gt;hooks.json&lt;/code&gt; 使用同样的事件结构：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;hooks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;PreToolUse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;matcher&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;^Bash$&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;hooks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;PreToolUse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;hooks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;command&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;python &amp;#34;.codex/hooks/pre_tool_use_policy.py&amp;#34;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;timeout&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;statusMessage&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Checking Bash command&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果同一层配置里同时存在 &lt;code&gt;hooks.json&lt;/code&gt; 和内联 &lt;code&gt;[hooks]&lt;/code&gt;，Codex 会同时加载并给出警告。实际项目里最好二选一，避免规则分散后难以排查。&lt;/p&gt;
&lt;h2 id=&#34;使用-hook-时要注意什么&#34;&gt;使用 Hook 时要注意什么
&lt;/h2&gt;&lt;p&gt;第一，Hook 会执行本地命令，所以一定要审查来源。非托管 Hook 需要被 review 和 trust 后才会运行；Hook 内容变化后，也需要重新信任。陌生仓库里的 &lt;code&gt;.codex/hooks.json&lt;/code&gt; 不应该随便放行。&lt;/p&gt;
&lt;p&gt;第二，多个匹配的 Hook 可能都会运行。不要假设只有一个 Hook 能拦住所有事情，也不要把规则写得互相冲突。团队环境里要明确哪些是用户级规则，哪些是项目级规则，哪些是管理员托管规则。&lt;/p&gt;
&lt;p&gt;第三，Hook 是护栏，不是完整安全边界。比如 &lt;code&gt;PreToolUse&lt;/code&gt; 可以拦截很多工具调用，但官方也明确提示，它还不能覆盖所有 shell 调用路径，也不能拦截所有非 shell、非 MCP 工具。真正高风险的场景仍然需要权限配置、沙箱、代码审查和最小权限配合。&lt;/p&gt;
&lt;p&gt;第四，Hook 脚本要快。隐私扫描、命令审查这类 Hook 发生在交互链路中，如果脚本每次跑几十秒，会直接拖慢体验。能用规则完成的事情，不要每次都调用大型外部服务。&lt;/p&gt;
&lt;p&gt;第五，输出格式要严格。不同事件支持的返回字段不完全一样。比如 &lt;code&gt;UserPromptSubmit&lt;/code&gt; 可以用 &lt;code&gt;decision: &amp;quot;block&amp;quot;&lt;/code&gt; 阻止 prompt，&lt;code&gt;PreToolUse&lt;/code&gt; 则有自己的 &lt;code&gt;hookSpecificOutput&lt;/code&gt; 结构。写 Hook 前先看对应事件的输入输出约定，不要混用字段。&lt;/p&gt;
&lt;h2 id=&#34;哪些场景最值得先做-hook&#34;&gt;哪些场景最值得先做 Hook
&lt;/h2&gt;&lt;p&gt;如果刚开始用 Hook，不建议一下子做成复杂的企业级策略系统。可以先从三个小场景开始。&lt;/p&gt;
&lt;p&gt;第一个是隐私检查。它最容易带来真实收益，也最适合个人和团队通用。误贴密钥、token、&lt;code&gt;.env&lt;/code&gt; 片段，是 AI 编程工作流里很现实的问题。&lt;/p&gt;
&lt;p&gt;第二个是危险命令拦截。可以针对 &lt;code&gt;Bash&lt;/code&gt; 的 &lt;code&gt;PreToolUse&lt;/code&gt; 做基础规则，例如阻止递归删除、阻止改写系统目录、阻止向未知远端上传文件。&lt;/p&gt;
&lt;p&gt;第三个是收尾检查。用 &lt;code&gt;Stop&lt;/code&gt; 或 &lt;code&gt;PostToolUse&lt;/code&gt; 提醒 Codex 在结束前确认测试、构建、格式化、文档和未提交改动。这类 Hook 不一定要强制阻断，但能显著减少“差一步就收工”的情况。&lt;/p&gt;
&lt;h2 id=&#34;结论&#34;&gt;结论
&lt;/h2&gt;&lt;p&gt;Codex Hook 的进阶之处，不是让 Codex 多一个花哨功能，而是把“规则”接进了 Codex 的执行循环。&lt;/p&gt;
&lt;p&gt;普通用法里，你靠 prompt 告诉 Codex 应该怎么做；进阶用法里，你用 Hook 在关键节点检查它是否按规矩做。隐私检查、命令审查、权限策略、会话摘要、结束前校验，这些都可以从口头提醒变成可执行的工作流。&lt;/p&gt;
&lt;p&gt;如果你已经开始把 Codex 用在真实项目里，Hook 值得尽早配置。它不替代人工判断，也不替代沙箱和权限控制，但它能把很多容易遗忘的安全和流程要求，变成每次都会自动触发的默认动作。&lt;/p&gt;
&lt;p&gt;参考来源：&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/config-advanced#hooks&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Codex Advanced Configuration - Hooks&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/hooks&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Codex Hooks&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
