简介:本教程面向开发者、运维人员和技术负责人,说明如何在托管式智能体服务上搭建可长时间运行的任务。内容涵盖前置准备、会话与状态管理、工具调用与权限控制、断点恢复、多智能体协作、结果验证和常见问题排查,帮助读者减少自建运行底座的工程投入,形成可落地、可维护的生产方案。
本教程帮助读者完成一个能够持续运行、可中断恢复的智能体任务。具体包括:创建运行会话、为智能体配置工具与权限、设计检查点与断点恢复机制、接入多智能体协作流程,并通过日志和指标确认任务按预期执行。
完成本教程后,读者应能够:
适用读者
适用场景
不适合的场景包括:单轮问答、无需持久化状态的一次性调用。这类任务直接调用模型接口即可,无需引入完整的运行底座。
智能体在生产环境中运行,只靠模型能力远远不够。一个可靠的运行系统通常包含以下组成部分:
自建以上能力需要较长的工程周期,而且每一项都需要持续维护。托管式服务把这些能力作为平台功能提供,团队可以把精力集中在任务逻辑和业务质量上。
托管方案也有取舍。团队需要评估服务可用性承诺、数据存放地域、费用结构以及迁移成本。在正式接入前,建议把这些问题写入技术选型文档。
做什么:把业务目标拆分为若干任务单元。每个单元应有明确的输入、输出和成功判据。
为什么:长程任务失败后,需要知道从哪一步恢复。任务边界越清晰,检查点设计越简单,重复执行的风险越低。
注意什么:单元粒度要适中。单元过大时,一次失败会浪费大量已完成的计算;单元过小时,状态记录和调度开销会明显增加。
示例(以文档核对任务为例):
| 单元编号 | 输入 | 输出 | 成功判据 |
|---|---|---|---|
| U1 | 原始文档列表 | 标准化文本 | 每份文档均有非空文本 |
| U2 | 标准化文本 | 字段抽取结果 | 必填字段完整率不低于约定阈值 |
| U3 | 抽取结果与数据库记录 | 差异报告 | 差异项均附有来源位置 |
做什么:为每个业务任务创建一个独立会话,并把会话标识与业务编号建立映射关系。
为什么:会话承载上下文和执行历史。业务系统保存会话标识后,即使调度进程重启,也能找回对应任务。
注意什么:会话标识应持久化到业务数据库,不能只保存在内存中。同一业务编号重复提交时,应先查询是否已存在有效会话,避免重复创建。
伪代码(以下接口名仅用于说明流程,实际名称以所用服务的文档为准):
def start_task(biz_id, owner):existing = db.find_session_by_biz(biz_id)if existing and existing.status in ("running", "paused"):return existing.session_idsession = platform.create_session(agent_profile="doc-check-agent", # 智能体配置名,自定义timeout_minutes=720, # 会话最长存活时间metadata={"biz_id": biz_id, "owner": owner},)db.save_session_mapping(biz_id, session.id, status="running")return session.id
做什么:为智能体注册可用工具,并为每个工具设置白名单、参数校验规则和权限等级。
为什么:智能体会根据模型输出决定调用哪个工具。如果缺少约束,错误的参数或越权的写操作可能直接影响业务数据。
注意什么:
伪代码:
tools = [{"name": "query_record","access": "read","params_schema": {"record_id": "string, 格式校验: 正则"},"timeout_seconds": 30,},{"name": "update_record","access": "write","require_confirmation": True, # 写操作需人工确认"params_schema": {"record_id": "string", "fields": "object"},"timeout_seconds": 30,},]platform.register_tools(session_id, tools)
做什么:限定智能体的文件访问范围、网络出口和资源配额。
为什么:智能体执行的代码或脚本可能出现死循环、异常占用资源或访问非预期地址。隔离措施可以把影响限制在任务范围内。
注意什么:
做什么:每完成一个任务单元,就保存一次检查点。恢复时从最后一个成功检查点之后继续执行。
为什么:长程任务的中断几乎不可避免,原因包括网络抖动、节点回收和依赖服务超时。没有检查点时,只能整体重跑,成本高且容易产生重复写入。
注意什么:
伪代码:
def run_long_task(task):cp = load_checkpoint(task.id)cursor = cp.cursor if cp else 0state = cp.state if cp else init_state()for index in range(cursor, len(task.units)):unit = task.units[index]key = f"{task.id}:{unit.name}" # 幂等键result = execute_with_retry(unit,idempotency_key=key,max_retries=3,backoff="exponential",)save_result(task.id, unit.name, result) # 先持久化结果save_checkpoint(task.id, cursor=index + 1, state=state)return finalize(task.id)
做什么:设立一个编排智能体,负责拆分子任务、分派给执行智能体并汇总结果。
为什么:单个智能体承担过多角色时,上下文会快速膨胀,错误也难以定位。角色分离后,每个智能体的职责和评估标准更清楚。
注意什么:
编排流程示意:
编排智能体├─ 分派 U1 → 检索智能体 → 返回候选文档├─ 分派 U2 → 抽取智能体 → 返回字段结果└─ 分派 U3 → 校验智能体 → 返回差异报告↓汇总规则 → 最终结论 / 待人工复核列表
做什么:按开发、测试、生产三套环境分别配置,并在生产环境采用小流量灰度。
为什么:配置错误在开发环境暴露的代价远低于在生产环境暴露。灰度可以在影响范围有限时发现问题。
注意什么: