DSTS — 动态自动改进类型脚本
DSTS是TypeScript的最小,AI SDK-相配的即时优化器. 它为生成Object(带有Zod schemas)和以最新的GEPA优化器(类似"长颈鹿"的软G)生成Text优化了提示. GEPA在Pareto边界沿线发展出一个快速点,跨越了在实践中重要的多重目标:任务执行、时间和成本.
- AI Gateway - 相通: 通过模型 ids 作为字符串; 为结构化对象以 Zod schema 生成对象或为字符串生成 Text .
- 最小抽象: 一个默认适配器可调用
generateObject编号 :generateText和一个优化者. - 多重目标:首先,跟踪每个周期的正确性+耐久性(和成本);报告Pareto前部和高容量(2D).
- 持久性和预算:检查站/恢复、(通过象征性的)费用估算和预算上限、种子小批斗.
安装
npm i @currentai/dsts zod
快开始
import { z } from "zod";
import { optimize, DefaultAdapterTask } from "@currentai/dsts";
// Define schema (generateObject)
const Item = z.object({ title: z.string(), url: z.string().url() });
// Training data: use schema ⇒ generateObject; provide expectedOutput and/or a scorer
const trainset: DefaultAdapterTask<z.infer<typeof Item>>[] = [
{
input: "link to TS docs",
expectedOutput: {
title: "TypeScript",
url: "https://www.typescriptlang.org",
},
schema: Item,
},
];
const valset = trainset;
const result = await optimize({
seedCandidate: { system: "Extract a title and a valid URL from the text." },
trainset,
// Explicit held-out set used for Pareto selection
valset,
taskLM: {
model: "openai/gpt-5-nano",
// Any extra fields are passed through to AI SDK calls
temperature: 0.2,
providerOptions: { openai: { service_tier: "default" } },
},
reflectionLM: {
model: "openai/gpt-5.2",
providerOptions: { openai: { reasoningEffort: "high" } },
},
// Simple way to steer reflection without templates
reflectionHint: "Prioritize exact field correctness; avoid hallucinating properties.",
maxIterations: 5,
maxMetricCalls: 200,
maxBudgetUSD: 50,
reflectionMinibatchSize: 3,
candidateSelectionStrategy: "pareto",
componentSelector: "round_robin",
logger: {
log: (lvl, msg, data) => {
if (lvl === "info") console.log(`[${lvl}] ${msg}`, data || "");
},
},
persistence: {
dir: "runs/quickstart",
checkpointEveryIterations: 1,
resume: true,
},
});
console.log("Best system prompt:", result.bestCandidate.system);
种子提示物质
dsts 目前作为迅速的提炼者最有效,而不是迅速的发明者.
对于结构繁忙的任务,种子提示器应该已经编码任务的稳定协议:
- 输出形状和计划预期,
- 允许标签或字段值,
- 证据或引用格式,
- 索赔的颗粒性,
- 边缘大小写处理规则.
如果种子提示很弱,早期的GEPA迭代往往会花预算来重新发现计划限制,而不是改善域行为. 在实践中,最佳的工作流程是:
- 手写一个已经具有结构能力的种子提示 .
- 确保它能满足基本的计划和主题.
- 利用GEPA优化域判断,取舍,优先排序.
实例
- 电子邮件提取到丰富的对象计划 :
examples/email-extraction.ts - 信件垃圾邮件分类 :
examples/message-spam.ts - 优化结构化取票方式:
examples/optimize-anything-email-extraction.ts - 利用GEPAAdapter桥(信息分类):
examples/optimize-anything-legacy-bridge.ts
每个例子:
- 装入
.env本地(默认情况下的AI网关), - 印刷总数、标准电话、费用(美元)和时间(ms),
- 允许持久性
runs/...。 。 。 .
运行 :
npm run example # email extraction
npm run example:message-spam # spam classification
npm run example:optimize-anything
npm run example:optimize-anything-legacy
特定任务或私人实验可以生活在 local-examples/,这是被赋予的.
优化任何东西( 高级)
optimize() 仍然是稳定,AI SDK-内在的即时优化路径.
用于普遍优化(包括非文本状态和无种子拖带),使用 optimizeAnything()。 。 。 .
import { optimizeAnything } from "@currentai/dsts";
const result = await optimizeAnything<{ system: string }, Task>({
initialState: {
system: "Extract {title, assignee?, priority} as strict JSON.",
},
trainset,
evaluator: async (batch, state, captureTraces) => {
const evalResult = await adapter.evaluate(batch, state, captureTraces);
return {
instanceScores: evalResult.scores,
metrics: evalResult.metrics,
trajectories: evalResult.trajectories,
objectives: {
correctness: avg(evalResult.scores),
latency: avg(evalResult.metrics?.map((m) => m.latency_ms ?? 0) ?? []),
},
metricCalls: batch.length,
};
},
mutator: async (state, context) => {
// mutate prompt text using failed examples in context.evaluation
return { ...state, system: state.system + "\nBe stricter with priority mapping." };
},
objectives: { latency: { direction: "minimize" } },
scalarObjective: "correctness",
maxIterations: 5,
maxMetricCalls: 100,
});
console.log("Best prompt:", result.bestState.system);
后遗症适应器桥
重用已有的 GEPAAdapter 与 optimizeAnything,使用时 fromLegacyAdapter数字 :
import { fromLegacyAdapter, optimizeAnything } from "@currentai/dsts";
// const adapter = new MyGEPAAdapter(...)
// const { evaluator, mutator } = fromLegacyAdapter(adapter)
如何运作
- 默认适配器根据
schema; 收集 per-instance 分数、 耐久 ms 和 cost usd (在可用时通过符号) . - GEPA优化器维护候选档案,进行小批量反射,并接受改良儿童. 它计算出每个CANDIDA的衡量标准:
- 正确性=平均值(分数[])
- 纬度=-avg(纬度 ms)(存储的负高度更好)
- 费用累计跟踪并通过
maxBudgetUSD。 。 。 .
- 帕雷托前部和2D超容量(精确来说是两个目标)每个迭代和末端都有记录.
AI SDK 通过
通过对象变体 taskLM 直接将额外选项转发到 AI SDK 调用( 两者都) generateObject 财务报告和审定财务报表 generateText) (中文(简体) ). 所有未知的字段均被传播到适配器上,再传播到SDK上:
optimize({
// ...
taskLM: {
model: "openai/gpt-5-nano",
temperature: 0.2,
providerOptions: { openai: { service_tier: "default" } },
// tools, stopWhen, toolChoice, maxToolRoundtrips, experimentalTelemetry, etc. are also supported
},
})
引导反射( 无模板)
使用 reflectionHint 在反射提示上方插入一个短导线串。 保持简洁:
optimize({
// ...
reflectionHint: "Prioritize exact field correctness; avoid hallucinating properties.",
})
关键文件 :
- 优化者 :
src/gepa.ts - 适配器 :
src/adapters/default-adapter.ts(默认最大货币=10) - 公共事业:
src/pareto-utils.ts - 类型 :
src/types.ts - 持久性:
src/persistence.ts
设计选择
- 没有自定义的 LLM 类:通过模型代号为字符串(Gateway格式,例如,
openai/gpt-5-nano) (中文(简体) ). 适配器直接使用AI SDK. - 最小指针: 设置预算( )
maxMetricCalls, (中文(简体) ),maxBudgetUSD),小批量大小,以及选取者. 货币违约为10. - 默认的多目标:我们最乐观地共同追求正确性和耐久性;如果愿意,以后作为明确目标增加费用.
环境
- AI网关默认. 设定
AI_GATEWAY_API_KEY内.env或者在你的外壳中导出它. - 如果你喜欢提供商 直接,交换给
@ai-sdk/openai模型和通过模型对象;适配器会转发.
路线图
- 扩大超量和目标(例如作为第三个维度的成本),并有明确的参考点.
- 反映货币(可选)和父母/子女评价并行.