> ## Documentation Index
> Fetch the complete documentation index at: https://cndoc-langchain.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Fleet Webhooks

> 将智能体发布与外部系统、CI/CD 管道或自定义部署工作流集成。

当触发时，webhook 会将智能体的完整配置和文件包发送到指定的端点。

<Callout icon="lock" color="#4F46E5" iconType="regular">
  **安全说明：**

  * Webhook URL 必须使用 HTTPS。
  * 自定义头部（例如 API 密钥）以加密方式存储。
  * 发布者身份信息包含在内，用于审计跟踪。
  * Webhook 仅对智能体所有者可见。
</Callout>

## 添加 webhook

1. 导航到 [设置 > Fleet webhooks](https://smith.langchain.com/settings/workspaces/agent-builder-webhooks)。
2. 点击 **添加 webhook**。
3. 配置：
   * **名称**：一个描述性名称（例如，“发布智能体”、“部署到生产环境”）。
   * **URL**：将接收 webhook 的 HTTPS 端点。
   * **头部**（可选）：用于身份验证的自定义头部（加密存储）。
   * **表单模式**（可选）：定义触发时用户必须填写的自定义输入字段。
4. 点击 **保存**。

## 触发 webhook

1. 在 Fleet 编辑器中打开你的智能体。
2. 点击 **设置** 菜单（齿轮图标）。
3. 在 **Webhooks** 下，点击 webhook 名称。
4. 填写表单模式中定义的任何自定义字段。
5. 点击 **运行 Webhook**。

## 编辑 webhook

1. 导航到 [设置 > Fleet webhooks](https://smith.langchain.com/settings/workspaces/agent-builder-webhooks)。
2. 对于要编辑的 webhook，点击 **编辑**。
3. 进行更改并点击 **保存**。

## 删除 webhook

1. 导航到 [设置 > Fleet webhooks](https://smith.langchain.com/settings/workspaces/agent-builder-webhooks)。
2. 对于要删除的 webhook，点击 **删除**。
3. 要确认删除，请点击 **删除**。

## Webhook 载荷

Webhook 载荷是一个 JSON 对象，包含以下字段：

| 字段                                                  | 描述                            |
| --------------------------------------------------- | ----------------------------- |
| `action`                                            | Webhook 的名称。                  |
| `input`                                             | 来自自定义表单字段的值（如果没有自定义字段，则为空对象）。 |
| `publisher`                                         | 触发 webhook 的用户的 ID 和电子邮件。     |
| `agent`                                             | 智能体的名称和描述。                    |
| [`tool_auth_requirements`](#tool-auth-requirements) | 智能体使用的每个工具的身份验证要求。            |
| [`files`](#zip-file-structure)                      | 包含所有智能体文件的 Base64 编码 ZIP 文件。  |
| [`fields`](#custom-input-fields)                    | 自定义输入字段。                      |

例如：

```json theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{
  "action": "Webhook Name",
  "input": {
    "notes": "User-provided value",
    "environment": "prod",
    "dry_run": true
  },
  "publisher": {
    "user_id": "uuid-of-publishing-user",
    "email": "user@example.com"
  },
  "agent": {
    "name": "My Agent",
    "description": "Agent description text"
  },
  "tool_auth_requirements": [
    {
      "tool_name": "tavily_web_search",
      "auth_type": "api_key",
      "required_env_vars": ["TAVILY_API_KEY"]
    },
    {
      "tool_name": "google_calendar",
      "auth_type": "oauth",
      "auth_provider": "google",
      "scopes": ["calendar.readonly"]
    }
  ],
  "files": {
    "type": "zip",
    "filename": "My_Agent.zip",
    "content_base64": "<base64-encoded-zip>"
  },
  "fields": [
    {
      "name": "notes",
      "label": "Deployment Notes",
      "type": "textarea"
    }
  ]
}
```

### 工具身份验证要求

`tool_auth_requirements` 数组描述了每个工具所需的身份验证：

| 身份验证类型    | 字段                        | 描述                   |
| --------- | ------------------------- | -------------------- |
| `none`    | -                         | 工具不需要身份验证            |
| `api_key` | `required_env_vars`       | 工具需要环境变量中的 API 密钥    |
| `oauth`   | `auth_provider`, `scopes` | 工具需要具有指定范围的 OAuth 令牌 |

使用此信息为你的部署环境配置必要的凭据。

### ZIP 文件结构

`files.content_base64` 字段包含一个 ZIP 归档文件，其结构如下：

```
.
├── AGENTS.md           # 智能体系统提示和指令
├── config.json         # 智能体元数据（名称、描述、可见性）
├── tools.json          # 工具配置和中断设置
├── skills/             # 可选的技能定义
│   └── skill-name/
│       └── SKILL.md
└── subagents/          # 可选的子智能体配置
    └── research_worker/
        ├── AGENTS.md
        └── tools.json
```

`config.json` 文件和 `tools.json` 文件的结构如下：

<Tabs>
  <Tab title="`config.json`">
    ```json theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    {
      "name": "My Agent",
      "description": "Agent description",
      "visibility_scope": "tenant",
      "triggers_paused": false
    }
    ```
  </Tab>

  <Tab title="`tools.json`">
    ```json theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    {
      "tools": [
        {
          "name": "tavily_web_search",
          "mcp_server_url": "http://localhost:8084",
          "mcp_server_name": "Fleet",
          "display_name": "tavily_web_search"
        }
      ],
      "interrupt_config": {
        "http://localhost:8084::tavily_web_search::Fleet": false
      }
    }
    ```
  </Tab>
</Tabs>

### 自定义输入字段

你可以定义自定义输入字段，以便在触发 webhook 时收集信息。支持的字段类型如下：

| 类型         | 描述               |
| ---------- | ---------------- |
| `string`   | 单行文本输入（默认）。      |
| `number`   | 数字输入。            |
| `boolean`  | 复选框（true/false）。 |
| `textarea` | 多行文本输入。          |
| `json`     | JSON 编辑器。        |
| `select`   | 带有预定义选项的下拉菜单。    |

例如：

```json theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{
  "fields": [
    {
      "name": "notes",
      "label": "Deployment Notes",
      "type": "textarea"
    },
    {
      "name": "environment",
      "label": "Environment",
      "type": "select",
      "options": [
        { "label": "Development", "value": "dev" },
        { "label": "Staging", "value": "staging" },
        { "label": "Production", "value": "prod" }
      ]
    },
    {
      "name": "dry_run",
      "label": "Dry Run",
      "type": "boolean",
      "default": true
    }
  ]
}
```

## 示例：Webhook 服务器

以下是一个用 Python 编写的 webhook 服务器示例：

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import base64
import zipfile
import io

class WebhookHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        body = json.loads(self.rfile.read(content_length))

        action = body.get("action")
        input_data = body.get("input", {})
        publisher = body.get("publisher", {})
        agent = body.get("agent", {})
        tool_auth = body.get("tool_auth_requirements", [])
        files = body.get("files", {})

        print(f"Webhook: {action}")
        print(f"Publisher: {publisher.get('email')}")
        print(f"Agent: {agent.get('name')}")
        print(f"Custom Input: {input_data}")

        # 提取 ZIP 内容
        if files.get("content_base64"):
            zip_bytes = base64.b64decode(files["content_base64"])
            with zipfile.ZipFile(io.BytesIO(zip_bytes)) as zf:
                print(f"Files: {zf.namelist()}")

        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.end_headers()
        self.wfile.write(json.dumps({"status": "ok"}).encode())

HTTPServer(("", 8000), WebhookHandler).serve_forever()
```

***

<div className="source-links">
  <Callout icon="terminal-2">
    [将这些文档连接](/use-these-docs)到 Claude、VSCode 等，通过 MCP 获取实时答案。
  </Callout>

  <Callout icon="edit">
    [在 GitHub 上编辑此页面](https://github.com/langchain-ai/docs/edit/main/src/langsmith/fleet/webhooks.mdx) 或 [提交问题](https://github.com/langchain-ai/docs/issues/new/choose)。
  </Callout>
</div>
