Webhook 支持从您的 LangSmith 应用向外部服务发送事件驱动的通信。例如,您可能希望在 LangSmith 的 API 调用完成后向其他服务发出更新。
许多 LangSmith 端点接受 webhook 参数。如果某个端点可以接受 POST 请求并且指定了此参数,LangSmith 将在运行完成时发送请求。
在使用 LangSmith 时,您可能希望使用 webhook 在 API 调用完成后接收更新。Webhook 可用于在运行处理完成后触发服务中的操作。要实现此功能,您需要公开一个可以接受的端点 POST 请求,并将此端点作为 webhook 参数在您的 API 请求中传递。
目前,SDK 不提供内置支持来定义 webhook 端点,但您可以使用 API 请求手动指定它们。
支持的端点
以下 API 端点接受 webhook parameter:
| 操作 | HTTP 方法 | 端点 |
|---|---|---|
| 创建运行 | POST | /thread/{thread_id}/runs |
| 创建线程定时任务 | POST | /thread/{thread_id}/runs/crons |
| 流式运行 | POST | /thread/{thread_id}/runs/stream |
| 等待运行 | POST | /thread/{thread_id}/runs/wait |
| 创建定时任务 | POST | /runs/crons |
| 流式运行无状态 | POST | /runs/stream |
| 等待运行无状态 | POST | /runs/wait |
在本指南中,我们将展示如何在流式运行后触发 webhook。
设置您的助手和线程
在发出 API 调用之前,请先设置您的助手和线程。
Python
from langgraph_sdk import get_client
client = get_client(url=)
assistant_id = "agent"
thread = await client.threads.create()
print(thread)
JavaScript
const client = new Client({ apiUrl: });
const assistantID = "agent";
const thread = await client.threads.create();
console.log(thread);
CURL
curl --request POST \
--url /assistants/search \
--header 'Content-Type: application/json' \
--data '{ "limit": 10, "offset": 0 }' | jq -c 'map(select(.config == null or .config == {})) | .[0]' && \
curl --request POST \
--url /threads \
--header 'Content-Type: application/json' \
--data '{}'
示例响应:
{
"thread_id": "9dde5490-2b67-47c8-aa14-4bfec88af217",
"created_at": "2024-08-30T23:07:38.242730+00:00",
"updated_at": "2024-08-30T23:07:38.242730+00:00",
"metadata": {},
"status": "idle",
"config": {},
"values": null
}
将 Webhook 与图运行配合使用
要使用 webhook,请在您的 API 请求中指定 webhook 参数。运行完成后,LangSmith 会向指定的 webhook URL 发送 POST 请求。
例如,如果您的服务器在以下地址监听 webhook 事件 https://my-server.app/my-webhook-endpoint,请将此包含在您的请求中:
Python
input = { "messages": [{ "role": "user", "content": "Hello!" }] }
async for chunk in client.runs.stream(
thread_id=thread["thread_id"],
assistant_id=assistant_id,
input=input,
stream_mode="events",
webhook="https://my-server.app/my-webhook-endpoint"
):
pass
JavaScript
const input = { messages: [{ role: "human", content: "Hello!" }] };
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantID,
{
input: input,
webhook: "https://my-server.app/my-webhook-endpoint"
}
);
for await (const chunk of streamResponse) {
// Handle stream output
}
CURL
curl --request POST \
--url /threads//runs/stream \
--header 'Content-Type: application/json' \
--data '{
"assistant_id": ,
"input": {"messages": [{"role": "user", "content": "Hello!"}]},
"webhook": "https://my-server.app/my-webhook-endpoint"
}'
Webhook 负载
LangSmith 以 Run格式发送 webhook 通知。请求负载包含运行输入、配置和其他元数据在 kwargs 字段中。除了标准运行字段外,webhook 负载还包括 values, webhook_sent_at和 error fields.
完整的 webhook 负载包含以下字段:
| 字段 | 类型 | 描述 |
|---|---|---|
run_id | string (UUID) | 运行的唯一标识符。 |
thread_id | string (UUID) | 运行所属线程的标识符。 |
assistant_id | string | 执行运行的助手标识符。 |
status | string | 运行的最终状态(例如, "success", "error"). |
created_at | string (日期时间) | 运行创建时的时间戳。 |
updated_at | string (日期时间) | 运行上次更新的时间戳。 |
run_started_at | string (日期时间) | 运行开始执行时的时间戳。 |
run_ended_at | string (日期时间) | 运行结束的时间戳。如果运行尚未结束则省略。 |
webhook_sent_at | string (datetime) | Webhook 请求发送时的时间戳。 |
metadata | JSON object | 与运行关联的自定义元数据。 |
kwargs | JSON object | 运行输入、配置和其他调用参数。 |
values | JSON object | 线程最新检查点的状态值。仅在有状态运行中存在。 |
multitask_strategy | string | 运行使用的多任务策略。 |
error | `JSON object \ | null` |
示例负载:
{
"run_id": "1ef6a5b8-4457-6db0-8b15-cffd3797fa04",
"thread_id": "9dde5490-2b67-47c8-aa14-4bfec88af217",
"assistant_id": "agent",
"status": "success",
"created_at": "2024-08-30T23:07:38.242730+00:00",
"updated_at": "2024-08-30T23:07:40.120000+00:00",
"run_started_at": "2024-08-30T23:07:38.300000+00:00",
"run_ended_at": "2024-08-30T23:07:40.100000+00:00",
"webhook_sent_at": "2024-08-30T23:07:40.150000+00:00",
"metadata": {},
"kwargs": {
"input": {
"messages": [{"role": "user", "content": "Hello!"}]
}
},
"values": {
"messages": [
{"role": "user", "content": "Hello!"},
{"role": "assistant", "content": "Hi there! How can I help you today?"}
]
},
"multitask_strategy": "reject",
"error": null
}
当运行失败时, error 字段包含有关失败的详细信息:
{
"error": {
"error": "TimeoutError",
"message": "Run exceeded maximum execution time"
}
}
安全 Webhook
为确保只有授权请求访问您的 webhook 端点,请考虑将安全令牌作为查询参数添加:
https://my-server.app/my-webhook-endpoint?token=YOUR_SECRET_TOKEN
您的服务器应在处理请求之前提取并验证此令牌。
向 webhook 请求添加标头
您可以配置静态标头以包含在所有出站 webhook 请求中。这对于身份验证、路由或向 webhook 端点传递元数据很有用。
添加一个 webhooks.headers 配置到您的 langgraph.json file:
{
"webhooks": {
"headers": {
"X-Custom-Header": "my-value",
"X-Environment": "production"
}
}
}
在标头中使用环境变量
要包含密钥或特定环境值而不将其签入配置文件,请使用 ${{ env.VAR }} 模板语法:
{
"webhooks": {
"headers": {
"Authorization": "Bearer ${{ env.LG_WEBHOOK_TOKEN }}"
}
}
}
出于安全考虑,默认只能引用以 LG_WEBHOOK_ 开头的环境变量。这可以防止意外泄露无关的环境变量。您可以使用以下方式自定义此前缀 env_prefix:
{
"webhooks": {
"env_prefix": "MY_APP_",
"headers": {
"Authorization": "Bearer ${{ env.MY_APP_SECRET }}"
}
}
}
限制 webhook 目标
出于安全或合规目的,您可以使用以下方式限制哪些 URL 是有效的 webhook 目标 webhooks.url configuration:
{
"webhooks": {
"url": {
"allowed_domains": ["*.mycompany.com", "api.trusted-service.com"],
"require_https": true
}
}
}
可用选项:
| 选项 | 描述 |
|---|---|
allowed_domains | 主机名白名单。支持子域通配符(例如, *.mycompany.com). |
require_https | 拒绝 http:// URL 当 true. |
allowed_ports | 显式端口白名单。默认为 443 (https) 和 80 (http)。 |
disable_loopback | 禁止相对 URL(内部回环调用)当 true. |
max_url_length | 允许的最大 URL 长度(字符)。 |
禁用 webhook
As of langgraph-api>=0.2.78,开发者可以在其中禁用 webhook langgraph.json file:
{
"http": {
"disable_webhooks": true
}
}
此功能主要适用于自托管部署,平台管理员或开发者可能更倾向于禁用 webhook 以简化其安全态势——特别是如果他们没有配置防火墙规则或其他网络控制。禁用 webhook 有助于防止将不受信任的负载发送到内部端点。
有关完整的配置详细信息,请参阅 配置文件参考.
测试 webhook
您可以使用以下在线服务测试您的 webhook:
- * **Beeceptor** – 快速创建测试端点并检查传入的 webhook 载荷。
- * **Webhook.site** – 实时查看、调试和记录传入的 webhook 请求。
这些工具可帮助您验证 LangSmith 是否正确触发并向您的服务发送 webhook。