AutoLoop / Docs
Documentation

把任何可度量任务,接入一个会持续变好的系统。

这份文档覆盖 AutoLoop 当前已经实现的核心能力:快速上手、Python API、CLI、Web / Service API、 模板系统、历史记录、任务运行时以及当前版本的限制。内容以实际代码能力为准,不写未来占位功能。

产品概览

AutoLoop 是一个以结果为目标的优化引擎。给定 target + metric + budget, 它会自动提出候选方案、逐轮评分、只保留更优版本,并把全过程写入历史和任务状态。

Python API CLI Web BYOK Service API SQLite Job Store History / Continue / Retry

核心抽象

把任意可度量任务统一抽象为:

minimal abstractioncore
target + metric + budget
  • target:当前要优化的对象
  • metric:怎样算更好
  • budget:允许迭代多少轮

当前支持的目标类型

  • text
  • code
  • html
  • markdown
  • config
  • 实验性:顶层 Python callable(仅本地/CLI)

快速上手

如果你想最快跑通 AutoLoop,先安装依赖,然后用 CLI 或本地示例启动。

安装

installshell
python -m pip install --upgrade pip
pip install '.[dev]'

无 API key 的本地演示

demoshell
python examples/demo_simple.py

这个 demo 不调用外部模型,主要用来验证优化循环本身。

启动 Web / API 服务

serveshell
python -m autoloop.cli serve --host 127.0.0.1 --port 8000

默认 job 状态会持久化到 ~/.autoloop/jobs.sqlite3

Python API

Python API 适合把 AutoLoop 直接接入脚本、服务和内部流程。最小入口是 loop()

最小示例

python apipython
from autoloop import loop

result = loop(
    target="请把这段邮件写得更清晰",
    metric=len,
    budget=3,
)

print(result.best)

如果不显式传入 agent,Python API 默认会使用 deepseek provider,因此需要先配置对应 API key。

装饰器模式

decoratorpython
from autoloop import loop

@loop(metric=len, budget=1)
def build_prompt(topic):
    return f"请写一个关于 {topic} 的标题"

装饰器会按输入缓存优化结果。相同输入复用结果,不同输入独立优化。

实验性 callable

callablepython
result = loop(
    target=my_function,
    metric=my_metric,
    budget=2,
    experimental=True,
)

仅支持顶层 Python 函数;lambda、闭包、绑定实例方法和依赖自由变量的函数都会被拒绝。

参数说明表

loop() 和内部 Loop(...) 共用同一套核心参数。下面列的是当前版本最重要、最常用的字段。

参数 类型 / 默认值 说明
targetAny要优化的目标。稳定支持文本和文件;顶层 Python 函数属于实验能力。
metricCallable评分函数或评估器。只要能把候选结果映射成可比较的分数,就能接入 AutoLoop。
budgetint / 10最大迭代轮数,必须大于等于 1。
agentAgent / None负责提出候选方案;不传时会默认创建 deepseek agent。
directionmaximize / minimize优化方向。分数越高越好或越低越好,整个接受逻辑都会随之切换。
max_diffint / 30单轮允许的最大改动行数。超限候选会被直接拒绝并记录原因。
cost_limitfloat / 5.0总成本上限。达到上限后循环会停止继续提案。
target_typeauto目标类型推断。可选 textcodehtmlmarkdownconfigauto
judge_modescore裁决模式。score+pairwise 会在分数接近时触发 pairwise 裁决。
pairwise_metricCallable / None可选的 pairwise 裁判,只在 score+pairwise 下启用。
pairwise_windowfloat / 0.25判定“分数足够接近”的窗口范围。
event_handlerCallable / None用于接收运行时事件,适合接 Web/SSE、日志或可视化界面。
should_cancelCallable / None返回 True 时会尽快中断当前任务,最终状态变为 cancelled
experimentalbool / False显式开启实验能力;callable 优化必须设置为 True

LoopResult 结构

每次循环完成后,AutoLoop 都会返回一个结构化结果。这个对象既能给应用直接消费,也能写入历史和服务层响应。

字段 说明
best当前找到的最佳结果;服务层会优先返回可序列化版本。
score最佳结果分数。
baseline初始目标的基线分数。
improvement相对基线的提升幅度;在 minimize 模式下也保持“越大代表越有提升”的语义。
rounds实际执行的轮数。
accepted / rejected被接受和被拒绝的候选数量。
history每轮实验记录,包含分数、原因、策略、phase、diff 统计和 pairwise 决策。
cost累计消耗成本。
duration总耗时,单位秒。
statuscompletedcancelledfailed
target_kind实际目标类别,例如 textfilepython_function
accept_reason最佳结果被接受的主要原因,例如 score_improvedpairwise_win
judge_mode当前使用的裁决模式。
best_diff_stats最佳结果的 diff 统计,如新增、删除和变更行数。
metadata扩展元数据,例如序列化后的最佳结果。

服务层返回的结果子集

result payloadjson
{
  "best": "优化后的最佳结果",
  "score": 9.2,
  "baseline": 6.8,
  "improvement": 0.3529,
  "rounds": 6,
  "accepted": 2,
  "rejected": 4,
  "cost": 1.14,
  "duration": 4.83,
  "status": "completed",
  "accept_reason": "pairwise_win",
  "judge_mode": "score+pairwise",
  "target_kind": "text",
  "best_diff_stats": {
    "added": 4,
    "removed": 2,
    "changed": 6
  }
}

CLI

CLI 适合开发者工作流、本地试验和文件型目标的快速迭代。

常用命令

clishell
python -m autoloop.cli "请把这段说明写得更专业" --provider ollama --budget 5
python -m autoloop.cli ./notes.md --budget 6 --diff
python -m autoloop.cli "帮我润色这封邮件" --template work-email --provider ollama
python -m autoloop.cli history
python -m autoloop.cli continue <record_id>

CLI 能做什么

  • 直接优化文本或文件
  • 支持模板和自然语言 criteria
  • 查看历史、删除记录、继续优化
  • 支持 --diff--output--inplace
  • 支持 serve 启动 Web / API 服务

Web / Service API

Web 是面向更广泛用户的可视化入口;Service API 适合接入产品后端与自动化系统。 两者共用同一套任务运行时和 SQLite Job Store。

Web 当前能力

  • BYOK:API key 只保存在浏览器本地
  • 模板选择与自定义 criteria
  • 自动 target type 检测,默认 auto
  • 任务事件流、取消、重试、复制结果
  • 高级设置:direction、cost limit、target type

任务状态持久化

  • job 状态和事件会落到 SQLite
  • 服务重启后已完成任务仍可查询
  • 中断或失败的任务可以显式 retry
  • retry 会生成新的 job,并保留 retried_from 关系

模板系统

模板系统面向普通 prompt 与办公内容用户,首版采用双层模板结构。

通用目标

  • 更清晰
  • 更专业
  • 更可执行
  • 更有结构
  • 更简洁

办公场景

  • 邮件润色
  • 汇报摘要
  • 会议纪要整理
  • 标题 / Headline 优化
  • 提案表达优化
  • Prompt 优化

每个模板包含的字段

字段 说明
template_id模板唯一 ID
display_name展示名称
category分类,例如通用目标或办公场景
criteria内部实际使用的评估标准
default_budget默认预算轮数
judge_modescorescore+pairwise
tone_constraints语气和输出约束
target_type默认适用的目标类型

历史记录与任务运行时

AutoLoop 不只返回结果,还会保留足够多的运行上下文,便于继续优化和复盘。

History 记录什么

  • 输入、目标类型、provider、criteria
  • baseline、final score、improvement、cost、duration
  • 每轮实验的 accept / reject 状态
  • 策略、phase、reject reason、diff stats
  • 继续优化所需的上下文信息

Job Runtime 记录什么

  • job 状态:queued / running / cancelling / completed / cancelled / failed
  • 事件流:proposal、accepted、rejected、completed、failed 等
  • 原始请求参数和是否需要 API key 重试
  • 历史关联和 retried_from 血缘关系

接口参考

当前服务层对外提供以下接口:

Method Path 说明
POST/optimize创建一个新的优化任务
GET/jobs/{id}读取任务状态、结果和重试信息
GET/jobs/{id}/eventsSSE 事件流
POST/jobs/{id}/cancel取消运行中的任务
POST/jobs/{id}/retry从已有任务显式重试
GET/history读取历史列表
GET/history/{id}读取单条历史详情
POST/history/{id}/continue从历史最佳结果继续优化
GET/templates读取只读模板注册表

OptimizeRequest

字段 说明
target必填,最小长度为 1 的输入内容。
provider默认 deepseek;稳定文档范围内推荐 deepseekopenaimoonshotollama
api_keyBYOK 密钥;ollama 不需要。
criteria自定义评估标准;如果和模板同时传入,以模板 criteria 为准。
template_id可选模板,例如 general-professionalwork-email
budget1-100,默认 8
directionmaximizeminimize
target_type默认 auto
cost_limit大于等于 0.0 的成本上限。
temperature0.0-2.0,默认 0.7
judge_mode可选 scorescore+pairwise

任务状态与事件

  • 状态:queuedrunningcancellingcompletedcancelledfailed
  • 事件:queuedbaseline_scoredproposal_generatedcandidate_rejectedcandidate_acceptedcancel_requestedcancelledcompletedfailed
  • /jobs/{id} 返回持久化 job 数据、结果、错误、模板和重试来源。
  • /jobs/{id}/events 通过 SSE 连续输出事件,适合 Web 界面实时展示。

请求 / 响应示例

下面的 JSON 示例基于当前服务层真实返回结构整理,可直接作为接入时的参考。

创建任务

POST /optimizejson
{
  "target": "请把这段说明写得更专业",
  "provider": "deepseek",
  "target_type": "auto",
  "budget": 8,
  "direction": "maximize",
  "cost_limit": 5.0,
  "template_id": "general-professional"
}
responsejson
{
  "job_id": "a1b2c3d4",
  "status": "queued"
}

读取任务详情

GET /jobs/a1b2c3d4json
{
  "job_id": "a1b2c3d4",
  "status": "completed",
  "created_at": 1773501000.12,
  "updated_at": 1773501005.44,
  "input_text": "请把这段说明写得更专业",
  "provider": "deepseek",
  "target_type": "text",
  "history_id": "rec_20260315_001",
  "retried_from": null,
  "template_id": "general-professional",
  "request": {
    "target": "请把这段说明写得更专业",
    "provider": "deepseek",
    "criteria": null,
    "template_id": "general-professional",
    "budget": 8,
    "direction": "maximize",
    "target_type": "text",
    "cost_limit": 5.0,
    "temperature": 0.7,
    "judge_mode": null,
    "parent_id": "",
    "api_key_required": true
  },
  "retry_supported": true,
  "api_key_required_for_retry": true,
  "error": null,
  "result": {
    "best": "优化后的最佳结果",
    "score": 9.2,
    "baseline": 6.8,
    "improvement": 0.3529,
    "rounds": 6,
    "accepted": 2,
    "rejected": 4,
    "cost": 1.14,
    "duration": 4.83,
    "status": "completed",
    "accept_reason": "score_improved",
    "judge_mode": "score",
    "target_kind": "text",
    "best_diff_stats": {"added": 4, "removed": 2, "changed": 6},
    "history_id": "rec_20260315_001"
  }
}

取消与重试

POST /jobs/a1b2c3d4/canceljson
{
  "job_id": "a1b2c3d4",
  "status": "cancelling"
}
POST /jobs/a1b2c3d4/retryjson
{
  "provider": "deepseek",
  "api_key": "sk-...",
  "budget": 10
}
responsejson
{
  "job_id": "e5f6g7h8",
  "status": "queued"
}

从历史继续优化

POST /history/rec_20260315_001/continuejson
{
  "provider": "deepseek",
  "api_key": "sk-...",
  "budget": 6,
  "cost_limit": 3.0,
  "judge_mode": "score+pairwise"
}
responsejson
{
  "job_id": "i9j0k1l2",
  "status": "queued"
}

SSE 事件流

GET /jobs/a1b2c3d4/eventsevent stream
event: baseline_scored
data: {"baseline": 6.8, "target_kind": "text", "target_type": "text"}

event: candidate_accepted
data: {"round": 2, "score": 8.7, "reason": "score_improved"}

event: completed
data: {"best": "优化后的最佳结果", "score": 9.2, "history_id": "rec_20260315_001"}

部署说明

当前版本最稳妥的交付方式是单实例服务 + 持久化 SQLite + 反向代理。Web 页面和 Service API 由同一个服务提供。

推荐部署形态

  • 使用 python -m autoloop.cli serve 启动应用服务。
  • 通过 --jobs-db 指定持久化 SQLite 路径,例如 /var/lib/autoloop/jobs.sqlite3
  • 用 Nginx、Caddy 或云负载均衡做 HTTPS 和域名转发。
  • BYOK 模式下,API key 默认由浏览器本地保存,服务端按请求使用但不落盘。

启动示例

servershell
python -m pip install --upgrade pip
pip install '.[dev]' fastapi uvicorn

python -m autoloop.cli serve \
  --host 0.0.0.0 \
  --port 8000 \
  --jobs-db /var/lib/autoloop/jobs.sqlite3

上线前建议检查

  • 确认 ~/.autoloop 或你指定的 jobs 目录可写。
  • 为 SQLite 文件所在目录做备份和磁盘监控。
  • 如果面向公网,务必通过反向代理启用 HTTPS。
  • 将服务日志、5xx 错误和重试失败纳入监控。
  • 如果需要更高吞吐,再评估将 Job Store 抽离到更专业的后端存储。

FAQ

下面这些问题,是当前版本最常见的使用和交付疑问。

为什么不是单次生成,而是多轮优化?

AutoLoop 的目标不是“先生成一个答案”,而是“在预算和约束内不断找更好的答案”。如果一个任务可以被评分,它就适合进入这个循环。

普通用户需要自己写 metric 吗?

不需要。Web 和 Service API 可以直接用模板或自然语言 criteria。Python API 更适合需要完全自定义评估逻辑的开发者。

任务取消后会丢结果吗?

不会。取消后会返回当前已经找到的最佳结果,并把状态写成 cancelled。如果任务还没产生更优结果,最佳结果可能仍然是 baseline。

服务重启后正在运行的任务会怎样?

当前版本不会自动恢复运行中的任务。它们会被标记为失败,并可以通过 /jobs/{id}/retry 或 Web 的重试入口重新发起。

为什么 retry 需要重新传 API key?

因为 Web 默认采用 BYOK,服务端不会持久化用户密钥。这样更适合 beta 和自托管场景,也能降低密钥托管风险。

callable 优化适合线上使用吗?

暂时不建议。它是本地 / CLI 的实验能力,虽然有子进程沙箱和危险调用限制,但不是强安全边界,不应该当成多租户执行环境。

限制与实验能力

当前版本已经可用,但有一些边界和设计决定需要明确说明。

当前限制

  • score+pairwise 只在分数接近时触发 pairwise 裁决
  • Web 当前只支持取消任务,不支持 pause / resume
  • BYOK 模式下,provider 需要密钥时,retry 也需要重新提交 API key
  • 重启后的运行中任务不会自动恢复,而是标记为失败后显式 retry

实验性 callable

  • 仅面向本地 / CLI 路径,不进入首个 Web 多租户路径
  • 走子进程沙箱,但这不是强安全边界
  • 默认拒绝 lambda、闭包、绑定实例方法和危险调用
  • 适合作为实验能力,不建议当成高强度代码沙箱

下一步怎么用 AutoLoop

如果你只是想快速体验,先跑 CLI 或 Web。
如果你要把它接进产品,优先看 Python API 和 Service API。
如果你要面向普通用户交付,优先走模板系统 + Web BYOK。