Background Tasks(后台任务)
本技能用于在 full-stack-ai-agent-template 项目中添加或修改运行在请求/响应周期之外的工作,包括发送邮件、文档摄取、Webhook、清理任务和定时任务。适用场景是某项工作较慢、可重试或属于即发即弃类型时。
任务与内联执行的判断
- 任务:任何慢、可重试或即发即弃的工作——发送邮件、文档摄取/嵌入、调用较慢的外部 API、周期性清理、物化视图刷新。
- 内联:响应所依赖的快速、事务性工作。
代码位置
任务位于 backend/app/worker/tasks/,例如 email_tasks.py、rag_tasks.py、cleanup_tasks.py。应用使用 {{ cookiecutter.background_tasks }}。对于简单场景,存在进程内回退方案 worker/background/。
添加任务
在 backend/app/worker/tasks/<area>.py 中定义任务,按所选框架不同写法如下(原文给出四种模板分支)。
Celery:
from app.worker.celery_app import celery_app
@celery_app.task(name="send_welcome_email")
def send_welcome_email(user_id: str) -> dict: ...
入队:send_welcome_email.delay(user_id)(或 .apply_async(args=[...], countdown=60))。
Taskiq:
from app.worker.taskiq_app import broker
@broker.task
async def send_welcome_email(user_id: str) -> dict: ...
入队:await send_welcome_email.kiq(user_id)。
ARQ:
# add the coroutine, then list it in arq_app.WorkerSettings.functions
async def send_welcome_email(ctx, user_id: str) -> dict: ...
入队:await request.state.arq_pool.enqueue_job("send_welcome_email", user_id)。
Prefect:
from prefect import flow
@flow(name="send-welcome-email", log_prints=True)
async def send_welcome_email_flow(user_id: str) -> dict: ...
从 service 中即发即弃:asyncio.create_task(send_welcome_email_flow(user_id))。
调用位置:从 service 调用(不要直接从 route 调用)——把业务逻辑保留在 services/,在工作单元结束时入队。
定时调度(可选)
- Celery:加入
celery_app.py中的beat_schedule(运行make celery-beat)。 - Taskiq:追加到
tasks/schedules.py的SCHEDULES(运行make taskiq-scheduler)。 - ARQ:在
arq_app.py的WorkerSettings.cron_jobs中添加cron(...)条目。 - Prefect:在
app/worker/prefect_app.py中注册带CronSchedule/IntervalSchedule的 deployment。
运行与验证
- Celery:
make celery-worker(定时任务加make celery-beat,监控用make celery-flower)。 - Taskiq:
make taskiq-worker(定时任务加make taskiq-scheduler)。 - ARQ:worker 随开发栈运行(
make dev),或uv run --directory backend arq app.worker.arq_app.WorkerSettings。 - Prefect:
prefect-server与prefect-runner随make dev启动;可在 http://localhost:4200 查看运行情况。
规则
- 任务参数必须可序列化(id、基本类型),不要传 ORM 对象或会话。在任务内部用新会话重新获取数据。
- 尽量让任务幂等(可安全重试)。
- 将重量级导入放在任务函数内部,保持 API 导入轻量。
- 完整操作步骤见
docs/howto/add-background-task.md。