Files
MoviePilot/docs/agent-execution.md

84 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 智能助手执行优先策略
交互轮次从宿主 `MoviePilotAgent.process` 进入,到本轮推理及工具调用收口后结束。
网页、消息渠道、CLI 和兼容 API 的前台请求使用交互容量;自主定时任务与心跳保持后台归属,
即使配置了结果回传渠道也不会升级为交互轮次。
默认启用 `AGENT_INTERACTIVE_PRIORITY=true`。这是协作式资源隔离:正在运行的同步线程、
数据库事务和后台协程不会被抢占。主事件循环仍采用 asyncio 的协作调度,
因此同步代码阻塞事件循环、CPU 饱和、数据库锁竞争和模型网络延迟仍可能影响响应。
| 执行边界 | 交互容量 | 普通后台容量 |
| --- | --- | --- |
| `ThreadHelper.submit` | 独立 4 线程 | 保留现有 `CONF.threadpool` |
| 宿主 `run_in_threadpool` | 当前事件循环共享 4 个 anyio 令牌 | 独立后台 limiter,容量跟随 anyio 默认配置(通常 40) |
| `DatabaseWorker.run` | 独立 1 线程、运行及排队总计 8 项 | 保留 4 线程、总计 32 项默认值 |
| Agent 同步工具 | 各能力域独立的交互桶 | 保留原能力域限额,供自主任务使用 |
| APScheduler | 自主 Agent 使用 `agent` 执行组,2 线程 | 其他任务使用原 `default` 组 |
以上容量按需启动工作线程,关闭时沿用各自生命周期 owner 的封口和收敛合同。
取消不会提前归还仍在执行的同步工具、线程调用或数据库事务的容量。
聊天持久化的全局写入准入也区分交互和后台;同一会话的写锁及单会话上限继续共享,
以免并发覆盖历史。`DatabaseWorker.snapshot()` 返回普通组,`interactive_snapshot()` 返回保留组;
数据库队列和执行指标包含两组的增减量。
执行归属通过上下文复制传入线程。`moviepilot_api` 的本机 HTTP 调用携带本进程随机登记的
临时执行凭据,由 ASGI 中间件恢复;普通自填请求头或已经结束的轮次无法取得优先级。
用户令牌与权限检查照常执行。子进程、外部 MCP 服务和插件自建线程池不受本策略控制。
框架同步鉴权与同步端点保留 anyio 默认 limiter,宿主后台线程调用不再消耗该组令牌;
框架自身的 HTTP 请求之间仍共用默认配额,不能保证在任意 HTTP 洪峰下立即响应。
## 自主任务执行账号
`agent_task create` 在创建时解析真实 MoviePilot 账号。Telegram 等渠道必须绑定唯一且已启用的
MoviePilot 用户;请在右上角头像 → 个人信息 → 账号绑定中填写渠道发送者完整 ID,不能填写昵称、
群 ID 或机器人 ID。Web 使用已登录的用户 ID,已认证的 API 集成使用宿主管理员账号。
任务分别保存渠道会话归属和执行账号。后台执行仍按该账号的通知设置回传结果,普通业务查询和
管理员操作使用同一账号的实时权限,不因后台运行而提升权限。改名不会改变执行主体;账号停用、
删除或被新账号替换时,本次执行记录为 `failed`,不调用模型,也不回退超级管理员。
升级前的任务保留原定义和运行历史,但不猜测其执行主体。请先确认账号绑定,再从创建任务的
原会话使用 `agent_task update` 更新任务(例如保持名称不变),以确认一次执行账号;也可删除后
重新创建。未确认的任务执行时会明确失败,仍可暂停或删除。已确认主体不能通过普通更新换成另一账号。
`last_status=success` 表示 Agent 本轮未遇到宿主识别的执行、身份或权限错误,不保证每项外部业务
已完成;入库重试等异步操作仍应查询对应业务记录核验结果。
## 后台避让
交互活跃时,新进入调度执行入口的非关键自动任务最多等待
`AGENT_BACKGROUND_DEFER_SECONDS` 秒,默认 30 秒,设为 `0` 禁用等待。
轮次结束后等待任务继续执行;持续对话超过预算时也会继续,避免后台任务饥饿。
期间保留原任务 generation、重入保护和协程句柄,不重复注册或补投任务。
调度器明确使用合并过期触发、单实例和无限 misfire 宽限,避免有限避让产生的排队
被默认一秒宽限误判为过期丢弃;任务自己的重入保护继续生效。
调度服务列表以“等待交互结束”显示正在避让的任务,API 的 `execution_group` 返回实际执行组。
Outbox 补偿、安全检查、数据库维护、运行时维护和手动专用任务不避让。
交互主动触发的同步调用不会等待自己结束;业务调度函数执行时会撤销继承的交互归属。
已有主循环同步入口沿用原调用合同,不在事件循环中同步等待。
避让只作用于新进入执行入口的任务,不会暂停或重放已开始的业务操作。
APScheduler 3 的标准线程池没有任意数值 `priority` 的调度能力。
这里通过独立执行组和实际准入等待实现隔离,不向 `add_job` 传入无效的优先级参数。
独立调度执行组仅隔离触发线程,协程仍回投到同一主循环。
## 超时
- `LLMHelper` 为 OpenAI 兼容、DeepSeek、Anthropic 兼容和 Google 模型显式设置 180 秒的
网络请求超时,同步插件调用也生效;Bedrock 保留既有的读取超时配置。网络超时限制单次
I/O 等待,供应商重试或持续回包可能延长总耗时,不能代替调用方的整次请求预算。
- `AGENT_LLM_TIMEOUT`:单次根 Agent 模型请求总预算,默认 180 秒,覆盖流式与非流式生成
以及该请求的供应商重试;`0` 表示不限时。工具执行时间由原 `LLM_TOOL_TIMEOUT` 管理。
- `SCHEDULER_JOB_TIMEOUT`:协程调度任务的默认执行预算,默认 3600 秒,等待避让不计入执行时间;
`0` 表示不限时。显式 `JobSpec.timeout_seconds` 优先于此默认值:正数是总时长上限,`0`
表示该任务显式不限时,缺省才继承此默认值。
超时通过协程取消收口,不能杀死同步线程或撤销已经发生的外部副作用。
数据库和线程调用仍等待实际操作收尾后释放容量,因而收尾时间可能超过超时预算。
超时后应先查询操作状态,再决定是否重试写入。
关闭 `AGENT_INTERACTIVE_PRIORITY` 可让 Agent 使用普通执行容量并停用避让;两项超时配置独立生效。
这些配置由部署环境或 `app.env` 提供,修改后重启生效。