错误链路全景
这是一个3 层架构的超时杀进程错误:
scss
Plugin (Python) ──[SSE]──▶ Plugin Daemon (Go) ──[HTTP]──▶ Dify API (Python)
│
⏱️ 计时器
(600s 默认)
第 1 层 --- 根源:Plugin Daemon (Go)
错误消息 "killed by timeout" 来源于 langgenius/dify-plugin-daemon 仓库的 Go 代码,它出现在两处:
| 位置 | 文件 | 场景 |
|---|---|---|
| SSE 流处理 | internal/service/base_sse.go |
Agent 执行过程中,Daemon 通过 SSE 与插件通信,超时后写回 "killed by timeout" |
| 端点处理 | internal/service/endpoint.go |
插件端点调用超时,返回 HTTP 500 |
Go 端的关键逻辑:
go
// 伪代码示意
timer := time.NewTimer(time.Duration(maxExecutionTimeout) * time.Second)
select {
case <-timer.C:
// 超时 → 杀死插件进程,返回错误
writeData(InternalServerError("killed by timeout"))
case <-done:
// 正常完成
}
第 2 层 --- Dify API 客户端转换
在 base.py 中,当 Daemon 返回 HTTP 500 时:
python
# 第 266 行
except httpx.HTTPStatusError as e:
if e.response.status_code < 500:
raise PluginDaemonClientSideError(...)
else:
raise PluginDaemonInternalServerError(description=str(e))
然后 _handle_plugin_daemon_error 方法(第 380 行)根据错误类型名反序列化:
python
case PluginDaemonInternalServerError.__name__:
raise PluginDaemonInternalServerError(description=message)
最终错误格式为:req_id: 15279e8a2e PluginDaemonInternalServerError: killed by timeout
第 3 层 --- 消费方
- endpoint.py:在
delete_endpoint()中捕获PluginDaemonInternalServerError,用于区分"真的错误"和"已删除"(幂等删除逻辑) - provider.py:将
PluginDaemonInternalServerError映射为重试/降级策略
超时控制点
有两个独立的 600 秒超时配置,含义不同:
| 配置项 | 位置 | 默认值 | 作用 |
|---|---|---|---|
PLUGIN_MAX_EXECUTION_TIMEOUT |
Plugin Daemon 容器环境变量 | 600s | ⚠️ Daemon 杀死插件进程的超时 |
PLUGIN_DAEMON_TIMEOUT |
API 容器环境变量 | 600s | Dify API 等待 Daemon HTTP 响应的超时 |
配置文件位置:
| 文件 | 内容 |
|---|---|
api/configs/feature/__init__.py:236 |
PLUGIN_DAEMON_TIMEOUT Pydantic 字段定义 |
api/core/plugin/impl/base.py:44-55 |
构建 httpx.Timeout 实例 |
docker/docker-compose-template.yaml:232 |
API 端: PLUGIN_DAEMON_TIMEOUT=${PLUGIN_DAEMON_TIMEOUT:-600.0} |
docker/docker-compose-template.yaml:554 |
Daemon 端: PLUGIN_MAX_EXECUTION_TIMEOUT=${PLUGIN_MAX_EXECUTION_TIMEOUT:-600} |
docker/envs/core-services/plugin-daemon.env.example:13 |
PLUGIN_MAX_EXECUTION_TIMEOUT=600 |
docker/envs/core-services/api.env.example:12 |
PLUGIN_DAEMON_TIMEOUT=600.0 |
根因总结
req_id: 15279e8a2e PluginDaemonInternalServerError: killed by timeout 表示:
- Agent 执行时间超过了
PLUGIN_MAX_EXECUTION_TIMEOUT(默认 600 秒 / 10 分钟) - Plugin Daemon (Go) 的计时器先于插件完成触发
- Daemon 杀死了插件子进程
- Daemon 向 Dify API 返回 HTTP 500,错误消息为
"killed by timeout" - Dify API 将其转换为
PluginDaemonInternalServerError
可能的原因:
- Agent 的 LLM 调用特别慢(如模型响应时间长、被限流)
- Agent 需要多轮工具调用,每轮积累后总耗时超过 600s
- 工具调用本身执行缓慢(如外部 API 响应慢)
- 插件进程资源不足导致执行缓慢
PLUGIN_MAX_EXECUTION_TIMEOUT设置过小(默认 600s)
解决方案方向:
- 增大超时 :在 docker-compose 环境变量中调大
PLUGIN_MAX_EXECUTION_TIMEOUT(如1200) - 减小 Agent 执行复杂度:减少最大迭代轮数、使用更快的模型
- 检查工具性能:排查 Agent 使用的工具是否存在慢调用