传统聊天助手通常停在“一问一答”:你发出请求,它返回结果,然后等待下一条指令。OpenAI dots 指向了另一种工作方式——助手可以围绕复杂项目和日常任务持续推进,同时让用户保留控制权。
这里真正值得关注的,不只是助手能否生成更多内容,而是如何把“持续工作”变成一个可检查、可暂停、可恢复的过程。对于开发团队而言,目标定义、权限边界、审批节点和执行记录,往往比一次回答是否漂亮更重要。
从回答问题转向推进任务
复杂工作很少能通过单个提示词完成。一次产品发布可能包含整理需求、拆分任务、检查依赖、编写公告和跟踪反馈;日常事务也可能跨越多次沟通和多个时间点。
主动式助手更适合把工作表达为一组持续存在的对象:
- 目标:最终要交付什么,而不只是现在要回答什么。
- 状态:哪些步骤已完成,哪些正在等待输入。
- 约束:不能访问什么、不能做什么,以及预算或时间限制。
- 检查点:执行外部操作前,何时必须请求用户确认。
- 产物:文档、计划、草稿、代码或结构化记录。
这意味着提示词也需要变化。与其只写“帮我准备发布”,不如明确交付物和停止条件:
目标:为 2.4 版本准备发布材料。
需要产出:
1. 从变更记录中整理面向用户的发布说明草稿;
2. 列出仍缺少负责人或截止日期的事项;
3. 生成内部检查清单。
边界:
- 不得直接发布公告;
- 不得联系客户;
- 不得修改生产环境;
- 遇到信息冲突时暂停并列出冲突来源。
审批点:
- 对外发送内容前;
- 修改共享文档前;
- 任何涉及生产环境的操作前。
完成标准:
交付发布说明草稿、未决事项表和检查清单,并说明仍需人工确认的内容。
这样的描述既允许助手向前推进,也定义了它必须停下来的位置。
“保持控制”需要具体机制
“人在回路中”不能只是一句原则。一个长期运行的助手至少应提供以下控制面:
1. 操作按风险分级
读取文档、整理信息和生成草稿通常属于低风险操作;发送邮件、修改共享数据、触发部署或产生费用,则应该进入审批流程。风险等级最好绑定到具体动作,而不是依赖助手临场判断。
2. 重要动作先预览
在执行不可逆或面向外部的操作前,助手应展示:
- 准备执行的动作;
- 使用的输入和目标对象;
- 预计产生的变化;
- 可否撤销;
- 需要用户确认的具体内容。
相比笼统地询问“是否继续”,这种预览更容易发现收件人、环境、金额或文件范围错误。
3. 保存状态和证据
持续工作的前提是任务可恢复。每个步骤都应记录输入、输出、时间、审批状态和失败原因。用户重新接手时,不必猜测助手已经做了什么。
4. 为阻塞设置退出路径
助手遇到缺失信息时,不应该无限重试。更可靠的策略是:达到重试上限后暂停,汇总已经尝试的方法,并提出一个范围明确的问题。
一个可运行的本地审批流程
下面的示例不是 dots 的官方 API,而是一个可直接运行的概念性脚手架,用来演示任务状态、审批门和审计日志如何配合。它不会真正发送消息或修改外部系统。
先创建任务文件:
cat > task.json <<'JSON'
{
"project": "release-2.4",
"steps": [
{
"id": "collect-changes",
"action": "read_local_data",
"description": "整理本地变更记录",
"requires_approval": false
},
{
"id": "draft-announcement",
"action": "generate_draft",
"description": "生成发布公告草稿",
"requires_approval": false
},
{
"id": "send-announcement",
"action": "external_send",
"description": "向外部频道发送公告",
"requires_approval": true
}
]
}
JSON
再保存以下脚本为 runner.py:
import json
from datetime import datetime, timezone
from pathlib import Path
TASK_FILE = Path("task.json")
STATE_FILE = Path("state.json")
AUDIT_FILE = Path("audit.jsonl")
def load_json(path, default):
if not path.exists():
return default
return json.loads(path.read_text(encoding="utf-8"))
def save_state(state):
STATE_FILE.write_text(
json.dumps(state, ensure_ascii=False, indent=2),
encoding="utf-8",
)
def audit(event):
event["time"] = datetime.now(timezone.utc).isoformat()
with AUDIT_FILE.open("a", encoding="utf-8") as handle:
handle.write(json.dumps(event, ensure_ascii=False) + "\n")
task = load_json(TASK_FILE, {})
state = load_json(STATE_FILE, {"completed": []})
completed = set(state["completed"])
for step in task.get("steps", []):
if step["id"] in completed:
continue
if step.get("requires_approval", False):
print("任务已暂停,等待人工批准:")
print(json.dumps(step, ensure_ascii=False, indent=2))
audit({
"project": task.get("project"),
"step": step["id"],
"status": "waiting_for_approval"
})
break
# 这里只模拟执行。接入真实工具时,应按 action 建立明确的权限白名单。
print(f"执行:{step['description']}")
audit({
"project": task.get("project"),
"step": step["id"],
"action": step["action"],
"status": "completed"
})
completed.add(step["id"])
state["completed"] = sorted(completed)
save_state(state)
else:
print("所有步骤均已完成。")
运行它:
python runner.py
cat state.json
cat audit.jsonl
脚本会自动完成两个低风险步骤,然后停在“向外部频道发送公告”之前。实际接入模型、邮件、工单或部署系统时,可以保留同样的结构,但应把批准结果单独记录,而不是简单删除 requires_approval 字段。
这个小例子体现了一个关键设计原则:助手可以持续推进,但推进权和执行权不必完全相同。 它可以收集信息、组织材料和准备动作,而高影响操作仍由人授权。
哪些工作适合交给主动式助手
适合的任务通常具备三个特征:过程可以拆分、结果可以检查、失败可以恢复。例如:
- 汇总多份资料并维护未决事项列表;
- 为发布、会议或评审持续准备材料;
- 跟踪重复性的项目检查项;
- 生成草稿,并在发送前等待批准;
- 根据明确规则整理日常事务。
需要谨慎处理的场景包括生产环境变更、财务交易、法律或医疗决策,以及任何可能泄露敏感数据的任务。即使助手能够调用相关工具,也不意味着应该获得默认执行权限。
采用前的检查清单
把 dots 这类主动式助手引入真实工作流时,可以先确认:
- 目标是否有明确的完成标准;
- 助手能访问的数据范围是否最小化;
- 外部发送、删除、付款和生产变更是否设置审批门;
- 用户能否查看当前状态、历史动作和待处理问题;
- 任务是否可以暂停、取消和恢复;
- 失败重试是否有次数和成本上限;
- 产物是否仍由合适的人承担最终责任。
主动式助手的价值,不在于让人完全退出流程,而在于减少人对每个细小步骤的推动。最稳妥的采用方式,是先让助手负责可逆、可验证的准备工作,再逐步开放工具和权限。这样,工作可以继续向前走,而控制权仍然清晰地留在人手中。