<?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/zh-tw/tags/hook/</link>
        <description>Recent content in Hook on KnightLi的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-tw</language>
        <lastBuildDate>Thu, 11 Jun 2026 11:57:18 +0800</lastBuildDate><atom:link href="https://knightli.com/zh-tw/tags/hook/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>別只會用 Codex：Hook 才是進階玩法</title>
        <link>https://knightli.com/zh-tw/2026/06/11/codex-hooks-advanced-usage/</link>
        <pubDate>Thu, 11 Jun 2026 11:57:18 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/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 的關鍵生命週期事件裡執行自訂腳本，例如使用者提交 prompt 時、工具呼叫前、工具呼叫後、請求權限時、會話停止時等。這樣一來，你可以把團隊規則、安全檢查、隱私保護和自動化記錄放進 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>
