@currentai/dsts

中文文档
1.0.1发布于 2026/03/09MITTypeScriptCommonJS近 30 天下载 6.8万

GEPA (Genetic-Pareto) optimizer for TypeScript - Multi-objective optimization through reflective evolution, with first-class support for AI SDK's generateObject

原始使用文档
文档目录12 节
  1. Install
  2. Quick start
  3. Seed prompts matter
  4. Examples
  5. Optimize Anything (Advanced)
  6. Legacy Adapter Bridge
  7. How it works
  8. AI SDK passthrough
  9. Steering reflection (no templates)
  10. Design choices
  11. Environment
  12. Roadmap

DSTS — Dynamic Self‑improving TypeScript

DSTS is a minimal, AI SDK–aligned prompt optimizer for TypeScript. It optimizes prompts for both generateObject (with Zod schemas) and generateText with the latest GEPA optimizer (soft G like “giraffe”). GEPA evolves a prompt along a Pareto frontier across multiple objectives that matter in practice: task performance, latency, and cost.

  • AI Gateway–aligned: pass model ids as strings; generateObject with a Zod schema for a structured object or generateText with a string.
  • Minimal abstractions: one default adapter to call generateObject/generateText and one optimizer.
  • Multi‑objective first: correctness + latency (and cost) tracked per iteration; Pareto front and hyper‑volume (2D) reported.
  • Persistence & budgets: checkpoint/resume, per‑call cost estimation (via tokenlens) and budget caps, seeded minibatching.

Install

npm i @currentai/dsts zod

Quick start

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);

Seed prompts matter

dsts currently works best as a prompt refiner, not a prompt inventor.

For heavy structured tasks, the seed prompt should already encode the stable protocol of the task:

  • output shape and schema expectations,
  • allowed labels or field values,
  • evidence or citation format,
  • claim granularity,
  • edge-case handling rules.

If the seed prompt is weak, early GEPA iterations tend to spend budget rediscovering schema constraints instead of improving domain behavior. In practice, the best workflow is:

  1. Hand-write a seed prompt that is already structurally competent.
  2. Make sure it can satisfy the basic schema and rubric.
  3. Use GEPA to optimize domain judgments, tradeoffs, and prioritization.

Examples

Each example:

  • Loads .env locally (AI Gateway by default),
  • Prints total iterations, metric calls, cost (USD), and duration (ms),
  • Enables persistence to runs/....

Run:

npm run example              # email extraction
npm run example:message-spam # spam classification
npm run example:optimize-anything
npm run example:optimize-anything-legacy

Task-specific or private experiments can live under local-examples/, which is gitignored.

Optimize Anything (Advanced)

optimize() remains the stable, AI SDK-native prompt optimization path. For generalized optimization (including non-text state and seedless bootstrapping), use 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);

Legacy Adapter Bridge

To reuse an existing GEPAAdapter with optimizeAnything, use fromLegacyAdapter:

import { fromLegacyAdapter, optimizeAnything } from "@currentai/dsts";
// const adapter = new MyGEPAAdapter(...)
// const { evaluator, mutator } = fromLegacyAdapter(adapter)

How it works

  • Default adapter decides generateObject vs generateText based on schema presence in each task; collects per‑instance scores, latency_ms, and cost_usd (via tokenlens when usage is available).
  • GEPA optimizer maintains a candidate archive, runs minibatch reflection, and accepts improving children. It computes per‑candidate metrics:
    • correctness = average(score[])
    • latency = −avg(latency_ms) (stored negative so higher is better)
    • cost is tracked cumulatively and enforced via maxBudgetUSD.
  • Pareto front and 2D hyper‑volume (when exactly two objectives) are logged per iteration and at the end.

AI SDK passthrough

Pass the object variant for taskLM to forward extra options directly into AI SDK calls (both generateObject and generateText). All unknown fields are spread through to the adapter and then to the 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
  },
})

Steering reflection (no templates)

Use reflectionHint to insert a short guidance string at the top of the reflection prompt. Keep it concise:

optimize({
  // ...
  reflectionHint: "Prioritize exact field correctness; avoid hallucinating properties.",
})

Key files:

Design choices

  • No custom LLM classes: pass model ids as strings (Gateway format, e.g., openai/gpt-5-nano). The adapter uses AI SDK directly.
  • Minimal knobs: set budgets (maxMetricCalls, maxBudgetUSD), minibatch size, and selectors. Concurrency defaults to 10.
  • Multi‑objective by default: we optimise for correctness and latency together; add cost as an explicit objective later if desired.

Environment

  • AI Gateway by default. Set AI_GATEWAY_API_KEY in .env or export it in your shell.
  • If you prefer provider‑direct, swap to @ai-sdk/openai models and pass model objects; the adapter will forward them.

Roadmap

  • Extend hyper‑volume and objectives (e.g., cost as a third dimension) with explicit reference points.
  • Reflection concurrency (optional) and parent/child evaluation parallelism.

版本与发布记录

@currentai/dsts 共发布 7 个版本,首次发布于 2025/09/15;过去 12 个月发布了 1 个版本。

版本发布日期距今
1.0.1latest2026/03/098 个月前
0.1.52025/09/301.1 年前
0.1.42025/09/291.1 年前
0.1.32025/09/161.2 年前
0.1.22025/09/151.2 年前
0.1.12025/09/151.2 年前

关于 @currentai/dsts 的常见问题

@currentai/dsts 是什么?

GEPA (Genetic-Pareto) optimizer for TypeScript - Multi-objective optimization through reflective evolution, with first-class support for AI SDK's generateObject

如何安装 @currentai/dsts?

在项目目录运行 npm install @currentai/dsts,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:zod(^4.1.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@currentai/dsts 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@currentai/dsts 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@currentai/dsts 可以商用吗?

@currentai/dsts 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@currentai/dsts 的下载量有多少?

根据 npm 官方下载统计,@currentai/dsts 在 2026/10/11 – 2026/11/09 这 30 天内被下载 67,551 次,日均约 2,252 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@currentai/dsts 还在维护吗?

最新版本 1.0.1 发布于 2026/03/09(8 个月前);至今共发布 7 个版本,其中过去 12 个月发布了 1 个;首次发布于 2025/09/15。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。