Skip to content

5.12c Hook 教程

💡 一句话总结:掌握 OpenCode Hook 系统,实现灵活的扩展和定制。


学完你能做什么

  • 理解 Hook 的概念
  • 能使用配置 Hook
  • 能创建插件 Hook
  • 能组合多个 Hook

🎒 开始前的准备

确保你已经完成以下事项:


核心思路

什么是 Hook

Hook 是在特定时机触发的回调函数,用于扩展或修改 OpenCode 的行为。

OpenCode 核心
    ↓ 触发事件
Hook 处理函数
    ↓ 处理
返回值/副作用

Hook 类型

类型触发时机用途
before_*操作前预处理、验证
after_*操作后后处理、通知
around_*环绕操作包装、增强

配置 Hook

AGENTS.md Hook

yaml
agents:
  my-agent:
    hooks:
      before_think:
        - name: "日志记录"
          handler: |
            console.log("开始思考:", input);
            return input;
      
      after_think:
        - name: "结果处理"
          handler: |
            console.log("思考结果:", output);
            return output;

插件 Hook

typescript
class HookPlugin implements Plugin {
  async initialize(api: OpenCodeAPI): Promise<void> {
    // 注册 Hook
    api.hooks.register("before_chat", {
      name: "my-before-hook",
      handler: async (context) => {
        console.log("收到消息:", context.message);
        return context;
      },
    });

    api.hooks.register("after_chat", {
      name: "my-after-hook",
      handler: async (result) => {
        console.log("回复完成:", result);
        return result;
      },
    });
  }
}

常用 Hook

对话 Hook

yaml
hooks:
  before_chat:
    - name: "上下文注入"
      handler: |
        // 添加额外上下文
        context.system_prompt += "\n当前用户: " + context.user_name;
        return context;
  
  after_chat:
    - name: "结果保存"
      handler: |
        await saveToHistory(context.session_id, result);
        return result;

文件操作 Hook

yaml
hooks:
  before_read_file:
    - name: "权限检查"
      handler: |
        if (!hasPermission(context.user, context.path)) {
          throw new Error("权限不足");
        }
        return context;
  
  after_write_file:
    - name: "同步通知"
      handler: |
        await notifySyncService(context.path);

工具调用 Hook

yaml
hooks:
  before_tool_call:
    - name: "参数验证"
      handler: |
        validateParameters(tool_name, args);
        return { tool_name, args };
  
  after_tool_call:
    - name: "结果记录"
      handler: |
        logToolUsage(tool_name, args, result);
        return result;

高级用法

条件 Hook

yaml
hooks:
  before_chat:
    - name: "条件处理"
      condition: "context.message.includes('密码')"
      handler: |
        console.log("检测到敏感词");
        context.message = context.message.replace("密码", "******");
        return context;

链式 Hook

yaml
hooks:
  after_chat:
    - name: "Hook 1"
      handler: |
        result.step1 = true;
        return result;
    
    - name: "Hook 2"
      handler: |
        if (result.step1) {
          result.step2 = true;
        }
        return result;

错误处理 Hook

yaml
hooks:
  on_error:
    - name: "错误记录"
      handler: |
        errorHandler.log(error);
        errorHandler.notify(error);
        throw error;

跟我做

实战:创建审计 Hook

yaml
hooks:
  audit:
    enabled: true
    
  before_chat:
    - name: "记录请求"
      handler: |
        auditLog.push({
          time: new Date().toISOString(),
          type: "chat_request",
          user: context.user_id,
          message_preview: context.message.substring(0, 100)
        });
        return context;
  
  after_tool_call:
    - name: "记录工具使用"
      handler: |
        auditLog.push({
          time: new Date().toISOString(),
          type: "tool_call",
          tool: tool_name,
          success: !result.error
        });
        return result;
  
  on_error:
    - name: "记录错误"
      handler: |
        auditLog.push({
          time: new Date().toISOString(),
          type: "error",
          message: error.message,
          stack: error.stack
        });

检查点 ✅

全部通过才能继续

  • [ ] 理解 Hook 概念
  • [ ] 能使用配置 Hook
  • [ ] 能创建插件 Hook
  • [ ] 能处理复杂场景

本课小结

你学会了:

  1. Hook 概念
  2. 配置 Hook
  3. 常用 Hook
  4. 高级用法
  5. 实战案例

下一课预告

下一课我们将学习自定义工具。


📚 更多完整模板Prompt 模板库