核心抽象
把任意可度量任务统一抽象为:
target + metric + budget
target:当前要优化的对象metric:怎样算更好budget:允许迭代多少轮
AutoLoop 是一个以结果为目标的优化引擎。给定 target + metric + budget,
它会自动提出候选方案、逐轮评分、只保留更优版本,并把全过程写入历史和任务状态。
把任意可度量任务统一抽象为:
target + metric + budget
target:当前要优化的对象metric:怎样算更好budget:允许迭代多少轮textcodehtmlmarkdownconfig如果你想最快跑通 AutoLoop,先安装依赖,然后用 CLI 或本地示例启动。
python -m pip install --upgrade pip pip install '.[dev]'
python examples/demo_simple.py
这个 demo 不调用外部模型,主要用来验证优化循环本身。
python -m autoloop.cli serve --host 127.0.0.1 --port 8000
默认 job 状态会持久化到 ~/.autoloop/jobs.sqlite3。
Python API 适合把 AutoLoop 直接接入脚本、服务和内部流程。最小入口是 loop()。
from autoloop import loop
result = loop(
target="请把这段邮件写得更清晰",
metric=len,
budget=3,
)
print(result.best)
如果不显式传入 agent,Python API 默认会使用 deepseek provider,因此需要先配置对应 API key。
from autoloop import loop
@loop(metric=len, budget=1)
def build_prompt(topic):
return f"请写一个关于 {topic} 的标题"
装饰器会按输入缓存优化结果。相同输入复用结果,不同输入独立优化。
result = loop(
target=my_function,
metric=my_metric,
budget=2,
experimental=True,
)
仅支持顶层 Python 函数;lambda、闭包、绑定实例方法和依赖自由变量的函数都会被拒绝。
loop() 和内部 Loop(...) 共用同一套核心参数。下面列的是当前版本最重要、最常用的字段。
| 参数 | 类型 / 默认值 | 说明 |
|---|---|---|
target | Any | 要优化的目标。稳定支持文本和文件;顶层 Python 函数属于实验能力。 |
metric | Callable | 评分函数或评估器。只要能把候选结果映射成可比较的分数,就能接入 AutoLoop。 |
budget | int / 10 | 最大迭代轮数,必须大于等于 1。 |
agent | Agent / None | 负责提出候选方案;不传时会默认创建 deepseek agent。 |
direction | maximize / minimize | 优化方向。分数越高越好或越低越好,整个接受逻辑都会随之切换。 |
max_diff | int / 30 | 单轮允许的最大改动行数。超限候选会被直接拒绝并记录原因。 |
cost_limit | float / 5.0 | 总成本上限。达到上限后循环会停止继续提案。 |
target_type | auto | 目标类型推断。可选 text、code、html、markdown、config、auto。 |
judge_mode | score | 裁决模式。score+pairwise 会在分数接近时触发 pairwise 裁决。 |
pairwise_metric | Callable / None | 可选的 pairwise 裁判,只在 score+pairwise 下启用。 |
pairwise_window | float / 0.25 | 判定“分数足够接近”的窗口范围。 |
event_handler | Callable / None | 用于接收运行时事件,适合接 Web/SSE、日志或可视化界面。 |
should_cancel | Callable / None | 返回 True 时会尽快中断当前任务,最终状态变为 cancelled。 |
experimental | bool / False | 显式开启实验能力;callable 优化必须设置为 True。 |
每次循环完成后,AutoLoop 都会返回一个结构化结果。这个对象既能给应用直接消费,也能写入历史和服务层响应。
| 字段 | 说明 |
|---|---|
best | 当前找到的最佳结果;服务层会优先返回可序列化版本。 |
score | 最佳结果分数。 |
baseline | 初始目标的基线分数。 |
improvement | 相对基线的提升幅度;在 minimize 模式下也保持“越大代表越有提升”的语义。 |
rounds | 实际执行的轮数。 |
accepted / rejected | 被接受和被拒绝的候选数量。 |
history | 每轮实验记录,包含分数、原因、策略、phase、diff 统计和 pairwise 决策。 |
cost | 累计消耗成本。 |
duration | 总耗时,单位秒。 |
status | completed、cancelled 或 failed。 |
target_kind | 实际目标类别,例如 text、file、python_function。 |
accept_reason | 最佳结果被接受的主要原因,例如 score_improved 或 pairwise_win。 |
judge_mode | 当前使用的裁决模式。 |
best_diff_stats | 最佳结果的 diff 统计,如新增、删除和变更行数。 |
metadata | 扩展元数据,例如序列化后的最佳结果。 |
{
"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 适合开发者工作流、本地试验和文件型目标的快速迭代。
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>
--diff、--output、--inplaceserve 启动 Web / API 服务Web 是面向更广泛用户的可视化入口;Service API 适合接入产品后端与自动化系统。 两者共用同一套任务运行时和 SQLite Job Store。
autoretried_from 关系模板系统面向普通 prompt 与办公内容用户,首版采用双层模板结构。
| 字段 | 说明 |
|---|---|
template_id | 模板唯一 ID |
display_name | 展示名称 |
category | 分类,例如通用目标或办公场景 |
criteria | 内部实际使用的评估标准 |
default_budget | 默认预算轮数 |
judge_mode | score 或 score+pairwise |
tone_constraints | 语气和输出约束 |
target_type | 默认适用的目标类型 |
AutoLoop 不只返回结果,还会保留足够多的运行上下文,便于继续优化和复盘。
retried_from 血缘关系当前服务层对外提供以下接口:
| Method | Path | 说明 |
|---|---|---|
POST | /optimize | 创建一个新的优化任务 |
GET | /jobs/{id} | 读取任务状态、结果和重试信息 |
GET | /jobs/{id}/events | SSE 事件流 |
POST | /jobs/{id}/cancel | 取消运行中的任务 |
POST | /jobs/{id}/retry | 从已有任务显式重试 |
GET | /history | 读取历史列表 |
GET | /history/{id} | 读取单条历史详情 |
POST | /history/{id}/continue | 从历史最佳结果继续优化 |
GET | /templates | 读取只读模板注册表 |
| 字段 | 说明 |
|---|---|
target | 必填,最小长度为 1 的输入内容。 |
provider | 默认 deepseek;稳定文档范围内推荐 deepseek、openai、moonshot、ollama。 |
api_key | BYOK 密钥;ollama 不需要。 |
criteria | 自定义评估标准;如果和模板同时传入,以模板 criteria 为准。 |
template_id | 可选模板,例如 general-professional 或 work-email。 |
budget | 1-100,默认 8。 |
direction | maximize 或 minimize。 |
target_type | 默认 auto。 |
cost_limit | 大于等于 0.0 的成本上限。 |
temperature | 0.0-2.0,默认 0.7。 |
judge_mode | 可选 score 或 score+pairwise。 |
queued、running、cancelling、completed、cancelled、failedqueued、baseline_scored、proposal_generated、candidate_rejected、candidate_accepted、cancel_requested、cancelled、completed、failed/jobs/{id} 返回持久化 job 数据、结果、错误、模板和重试来源。/jobs/{id}/events 通过 SSE 连续输出事件,适合 Web 界面实时展示。下面的 JSON 示例基于当前服务层真实返回结构整理,可直接作为接入时的参考。
{
"target": "请把这段说明写得更专业",
"provider": "deepseek",
"target_type": "auto",
"budget": 8,
"direction": "maximize",
"cost_limit": 5.0,
"template_id": "general-professional"
}
{
"job_id": "a1b2c3d4",
"status": "queued"
}
{
"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"
}
}
{
"job_id": "a1b2c3d4",
"status": "cancelling"
}
{
"provider": "deepseek",
"api_key": "sk-...",
"budget": 10
}
{
"job_id": "e5f6g7h8",
"status": "queued"
}
{
"provider": "deepseek",
"api_key": "sk-...",
"budget": 6,
"cost_limit": 3.0,
"judge_mode": "score+pairwise"
}
{
"job_id": "i9j0k1l2",
"status": "queued"
}
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。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 目录可写。下面这些问题,是当前版本最常见的使用和交付疑问。
AutoLoop 的目标不是“先生成一个答案”,而是“在预算和约束内不断找更好的答案”。如果一个任务可以被评分,它就适合进入这个循环。
不需要。Web 和 Service API 可以直接用模板或自然语言 criteria。Python API 更适合需要完全自定义评估逻辑的开发者。
不会。取消后会返回当前已经找到的最佳结果,并把状态写成 cancelled。如果任务还没产生更优结果,最佳结果可能仍然是 baseline。
当前版本不会自动恢复运行中的任务。它们会被标记为失败,并可以通过 /jobs/{id}/retry 或 Web 的重试入口重新发起。
因为 Web 默认采用 BYOK,服务端不会持久化用户密钥。这样更适合 beta 和自托管场景,也能降低密钥托管风险。
暂时不建议。它是本地 / CLI 的实验能力,虽然有子进程沙箱和危险调用限制,但不是强安全边界,不应该当成多租户执行环境。
当前版本已经可用,但有一些边界和设计决定需要明确说明。
score+pairwise 只在分数接近时触发 pairwise 裁决
如果你只是想快速体验,先跑 CLI 或 Web。
如果你要把它接进产品,优先看 Python API 和 Service API。
如果你要面向普通用户交付,优先走模板系统 + Web BYOK。