游乐游手机版
首页/AI教程/文章详情

AntV Harness:LLM自我进化闭环优化系统

时间:2026-05-29 14:40
一、问题起源:从「能跑」到「持续变好」 "让 LLM 根据自然语言生成图表代码 "——这个目标听起来简单。把 API 文档塞进 prompt,初版 demo 两天就能跑起来。但真正的挑战在于:如何系统性地让生成质量持续提升? 传统做法是:人工分析失败案例 → 手动修改知识库 → 重新测试。这个流程可以

一、问题起源:从「能跑」到「持续变好」

"让 LLM 根据自然语言生成图表代码"——这个目标听起来简单。把 API 文档塞进 prompt,初版 demo 两天就能跑起来。但真正的挑战在于:如何系统性地让生成质量持续提升?

传统做法是:人工分析失败案例 → 手动修改知识库 → 重新测试。这个流程可以工作,但它是线性的、依赖人工的、难以规模化的。

AntV chart-visualization-skills 项目的 Harness 子系统给出了一个不同的答案:把优化循环本身自动化——让 LLM 分析自己的失败,改进知识库,再重新评测。

二、架构概览:五 Agent + 控制器的闭环流水线

整个 Harness 系统由五个职责单一的 Agent 和一个 Controller 组成:

Controller Loop

每个 Agent 职责清晰,通过 Controller 协调形成闭环:

// controller.js 核心循环
while (consecutivePasses < MAX_PASSES) {
    const resultPath = await runEval(ids);
    const errorCases = await renderAgent.run(resultPath);
    const { skillToErrors, orphanCases } = analyzeAgent.run(errorCases);
    await optimizeAgent.run(skillToErrors, { orphanCases });
    await indexAgent.run();
}

三、五 Agent 详解

3.1 EvalAgent

EvalAgent 负责调用 eval CLI,让 LLM 基于现有 skill 生成图表代码。支持三种检索策略:

策略 工作方式 适用场景
bm25 预先检索相关 skill,直接注入 prompt 快速测试、低成本
tool-call LLM 通过多轮工具调用主动拉取 skill 精准检索、复杂查询

关键设计——--ids 参数定向重测:支持指定 case ID 重测,而非每次全量运行。这为后续调度逻辑奠定了基础。

3.2 RenderAgent

生成代码是否正确,最终要靠执行来验证。RenderAgent 使用 Playwright 无头浏览器实际运行代码,判断三种失败状态:

  1. error:Ja vaScript 报错,代码根本没跑起来
  2. blank:画布为空,代码执行了但什么都没画出来(白屏)
  3. 低视觉得分:图表渲染了,但通过 VL(视觉语言)模型判定与预期不符

白屏检测的重要性:白屏通常意味着数据绑定错误或 API 用法有误,但没有 JS 异常。这类问题纯靠代码静态分析抓不到,必须实际渲染后检查画布是否有像素内容。

3.3 AnalyzeAgent

把 error cases 映射到具体的 skill 文件,但这里有一个根本性的难题:一次 LLM 调用可能读取了多个 skill,你不知道是哪个 skill 导致了错误。

最朴素的归因策略是"谁最后被读就改谁",但这往往是错的。比如:LLM 先读了 bar-chart skill 拿到基础用法,再读了 color-mapping skill 调整颜色,结果最终代码在 bar chart 的数据格式上出了问题——最后读的是 color-mapping,但真正的 bug 在 bar chart skill 的示例里。

AnalyzeAgent 的做法是:收集 LLM 实际读取的所有 skill,构成候选归因集合,然后把整个集合交给 OptimizeAgent,让 OptimizeAgent 的 LLM 自己判断根因在哪里。

对于没有对应 skill 的 case,AnalyzeAgent 将其标记为 "孤儿 case"(orphanCases)。孤儿 case 的存在意味着知识库里有盲区——某些图表类型压根没有 skill 覆盖,这会触发 OptimizeAgent 的新 skill 创建流程。

3.4 OptimizeAgent

OptimizeAgent 对每个有问题的 skill 并行调用 LLM 重写。System Prompt 设计非常关键:

当前 skill 是候选归因,不一定是真正的根本原因。
- 如果你判断该 skill 确实有问题,输出修正后的完整文档
- 如果你认为该 skill 没有问题,原样输出即可

把"是否需要修改"的判断权交给 LLM,而非强制对每个候选 skill 都生成修改版本。OptimizeAgent 还支持工具调用,可以查阅本地官方文档和源码,但有路径访问白名单保护:

function assertAllowed(filePath) {
    const realRoots = allowedRoots.map((r) => fs.realpathSync(path.resolve(r)));
    if (!realRoots.some((r) => realPath === r || realPath.startsWith(r + path.sep))) {
        throw new Error(`Access denied: ${filePath} is outside allowed ref paths.`);
    }
}

安全机制:

  • 响应长度 < 原文件 50%:跳过(防止截断导致文档大幅缩水)
  • 响应与原文完全相同:跳过(LLM 判定非根因,正确行为)
  • 写入前先备份 .bak 文件,失败自动还原

对于孤儿 case,OptimizeAgent 会创建全新的 skill 文件。为了让 LLM 一次生成多个 skill,设计了结构化分隔符协议:

<<>>
---
title: Grouped Bar Chart
tags: [...]
---
# 分组柱状图
...
<<>>

3.5 IndexAgent

每轮优化后重建 BM25 索引,确保下一轮 eval 能检索到最新内容。这一步看似平淡无奇,但省略则整个优化循环形同虚设——LLM 改了文档,但检索引擎用的还是旧索引。

四、Controller

4.1 终止条件:连续通过机制

while (consecutivePasses < MAX_PASSES) {
    // ...
    if (errorCases.length === 0) {
        consecutivePasses++;
        console.log(`Clean pass (${consecutivePasses}/${MAX_PASSES})`);
    }
}

为什么是「连续」通过而非单次通过?因为修复一个 bug 可能引入新 bug。只有连续多轮无错误,才能确信知识库质量稳定。

4.2 固定样本 + 定向重测:让「通过」有意义

问题:如何判断一轮优化真的有效?

固定样本:第一轮确定的 case IDs 锁定为 fixedCaseIds,后续每轮用同一批 case。如果每轮随机采样,可能出现「恰好这轮都是简单 case」的假阳性。

定向重测:每轮优化后,把失败的 case IDs 存入 priorityCaseIds,下一轮只测这些 case,快速验证修复。

配合流程:

第 N 轮:全量 fixedCaseIds → [case-3, case-7, case-12] 失败
→ 优化相关 skill
→ priorityCaseIds = [case-3, case-7, case-12]
第 N+1 轮(定向):只测 [case-3, case-7, case-12] → 全部通过 → 不计入 consecutivePasses → 跑完整 fixedCaseIds 确认
第 N+2 轮(全量):全量 fixedCaseIds → 全部通过 → consecutivePasses++

4.3 Worktree 隔离 + Baseline 对比

所有 skill 优化操作在独立的 git worktree 上进行,优化完成后对比 worktree 和 main 分支,这防止了「修好 A 但引入 B 的回归」,因为每个 skill 可能被多个 case 使用。

五、Memory 系统:跨轮次的持久化学习

每一轮优化的信息不应该随着进程退出而消失。Memory 系统实现了跨轮次的记忆持久化:

// memory.js
class HarnessMemory {
    // 记录错误
    recordErrors(skillPath, errorCases, iteration) {
        const history = this._skill(skillPath);
        for (const c of errorCases) {
            history.errors.push({
                caseId: c.id,
                errorType: this._errorType(c),
                query: c.query,
                iteration,
                ts: Date.now(),
            });
        }
        this._sa ve();
    }
    // 记录优化动作
    recordOptimization(skillPath, errorCases, iteration) { /* ... */ }
    // 生成历史摘要注入 LLM prompt
    getOptimizationContext(skillPath) { /* ... */ }
}

5.1 持续错误类型高亮

getOptimizationContext 会高亮持续出现的错误类型(在 ≥2 轮中间出现),相当于给 LLM 提供「重点关注清单」:

【历史优化记录 — bar-chart-grouped.md】
共优化 3 次,累计错误 7 条。
- 第 2 轮:3 个错误,类型:blank, TypeError: ...
- 第 3 轮:2 个错误,类型:blank
⚠️ 持续出现的错误类型(跨多轮未解决):blank

5.2 原子写入

_sa ve() {
    const tmp = `${this._path}.tmp`;
    fs.writeFileSync(tmp, JSON.stringify(this._data, null, 2));
    fs.renameSync(tmp, this._path); // POSIX 原子操作
}

5.3 路径归一化

解决 worktree 和主仓库绝对路径不同的问题:

_normalizeKey(skillPath) {
    if (path.isAbsolute(skillPath)) {
        return path.relative(PROJECT_ROOT, skillPath);
    }
    return skillPath;
}

这确保同一个 skill 文件在不同环境下被视为同一条记录。

六、模式的通用性

如何为一个 SKILL 系统建立知识库质量的持续改进机制。这个问题不局限于图表生成。任何「LLM + 结构化知识库」的系统都面临同样挑战——代码生成工具、客服 FAQ、法律/医疗垂直领域的专业知识库。

核心模式可以抽象为:

评测(量化当前质量)→ 执行验证(在真实环境中验证)→ 分析归因(定位到具体文档)→ LLM 优化(驱动文档改进)→ 重索引(让改动立即生效)→ 循环

这条流水线的前提是:「评测」和「执行验证」这两步可以自动化。

对图表生成,Playwright 无头浏览器就是执行环境;对其他场景,你需要找到对应的自动验证方式。

七、结语

Harness 系统的代码量并不大,但它把一个复杂的质量优化问题拆解成了五个职责清晰的 Agent,用一套严谨的调度逻辑把它们串联起来,通过 FeedforwardFeedback 进行相关指引和校正。

Feedforwardskills/ 目录提供结构化知识,通过 BM25/tool-call 策略注入 prompt;

Feedback:RenderAgent 检测 JS 错误/白屏/低视觉评分,AnalyzeAgent 归因,OptimizeAgent 重写文档。

说到底,这种自动化闭环的思路是值得借鉴的——把人类从重复的「分析→修改→验证」中解放出来,让机器自己去迭代。

来源:https://juejin.cn/post/7628974585678676009
上一篇TWT Chat智能客服聊天系统 企业级在线平台 下一篇Photoshot AI头像个性化生成,完美展现独特风格
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
GPT Workspace通过GPT-5强化Google Workspace,文档表格邮件创作效率与智能化提升
AI教程 · 2026-05-29

GPT Workspace通过GPT-5强化Google Workspace,文档表格邮件创作效率与智能化提升

GPT Workspace 产品介绍:GPT-5 如何增强 Google Workspace 工作效率 如果你每天都在使用 Google Workspace 进行文档撰写、表格处理、邮件沟通和演示制作,一定深有体会:大量重复性的办公任务耗费了宝贵的时间。现在,GPT Workspace 将 GPT-

AI助手提升年终总结与周报效率的精准营销策略
AI教程 · 2026-05-29

AI助手提升年终总结与周报效率的精准营销策略

适合需求:在信息爆炸的时代,企业所承受的竞争压力几乎覆盖了所有维度,其中营销领域尤为令人困扰。无论是撰写年终总结还是生成周报,精准的营销策略已成为不可或缺的需求——没有谁愿意在庞杂的数据中迷失方向。当我们复盘营销活动时,总会思考:过去哪些数字营销策略真正发挥了效果?哪些内容营销策略有待改进?然而实际

Afri Studio 非洲创意工作室
AI教程 · 2026-05-29

Afri Studio 非洲创意工作室

Afri Studio是什么先来聊聊Afri Studio——它是Afri AI团队推出的一款AI媒体创作工作室,目标很明确:把原本高高在上的智能技术拉下神坛,让普通用户也能轻松生成高质量的文本、图像、音频等内容。换句话说,这是一个面向内容创作者、博主、营销人员、艺术家的“AI工具箱”,帮你高效搞定

Geniea专注Midjourney提示词优化提升创意生成效率
AI教程 · 2026-05-29

Geniea专注Midjourney提示词优化提升创意生成效率

Geniea产品详解:Midjourney提示优化工具Geniea是一款专注于Midjourney提示词优化的智能平台,致力于帮助创作者快速生成高质量且富有创意的提示方案。无论您需要电影镜头、食品摄影还是汽车广告等场景的提示词,只需输入简单指令,系统便会自动输出优化后的提示文本,大幅提升创作效率。提

幼儿园大班毕业典礼方案PPT AI轻松制作精彩回顾
AI教程 · 2026-05-29

幼儿园大班毕业典礼方案PPT AI轻松制作精彩回顾

使用情景 每年毕业季来临之际,幼儿园大班毕业典礼的筹备工作,总是牵动着众多老师、家长和孩子们的心弦。这不仅仅是一场简单的活动,更是孩子们人生中首个重要的成长仪式,标志着他们告别幼儿时光、迈向新阶段的里程碑。对于家长而言,这也是一次充满感怀的“毕业”,意味着一段陪伴旅程的暂时落幕。 如何让这场典礼既温