用例

Decisions API 用于 agent 下一步动作

agent 循环就是一连串有限决策:调工具、问用户、还是结束。决策调用选出下一个动作并返回每个选项的概率——无需解析自由文本,也不用校验工具调用的 schema。

更新于

把 agent 循环变成一个 choice 问题

每次循环迭代把当前状态交给模型,问同一个有限问题:下一步该做什么。答案是你命名的动作之一加置信度——正是循环执行器需要的契约。

选项是预先声明的,模型不可能返回你的循环没实现的动作。非法输出在结构上就不可能出现,不靠 prompt 约束。

下一步动作决策

// Agent loop: decisions-1 picks the next action each step.
type Action = "search_docs" | "call_tool" | "ask_user" | "finish";

async function decideNext(state: unknown): Promise<{ action: Action; confidence: number }> {
  const res = await fetch("https://decisions-api.net/api/v1/decisions", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.DECISIONS_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "decisions-1",
      state, // string, JSON object, or array of text
      questions: {
        next: {
          type: "choice",
          instructions: "What should the agent do next?",
          criteria: {
            search_docs: "Look up documentation before acting.",
            call_tool: "Run the next planned tool call.",
            ask_user: "Stop and ask the user for clarification.",
            finish: "The task is complete; produce the final answer.",
          },
        },
        done: { type: "noul", instructions: "Is the user's task fully complete?" },
      },
    }),
  });
  const { answers } = await res.json();
  return { action: answers.next.choice, confidence: answers.next.confidence };
}

const MAX_STEPS = 8;

async function runAgent(agentState: unknown) {
  for (let step = 0; step < MAX_STEPS; step++) {
    const { action, confidence } = await decideNext(agentState);
    // Illustrative response: { action: "call_tool", confidence: 0.83 }
    if (confidence < 0.8) { await askUser(agentState); continue; }
    switch (action) {
      case "finish": return;
      case "search_docs": await searchDocs(agentState); break;
      case "call_tool": await runTool(agentState); break;
      case "ask_user": await askUser(agentState); break;
    }
  }
  // MAX_STEPS reached: hand off to a human instead of looping forever.
}

给 agent 一个诚实的出口

criteria 里始终保留一个逃生动作——ask_user 或 finish。没有停止方式的 agent 会自己发明工作;诚实的出口让「我做完了」「我卡住了」成为一等答案。

你也可以在同一次调用里加一个独立的 noul 问题——「任务是否已完全完成」——作为对 choice 的交叉验证。

用置信度控制自主程度

置信度把答案变成策略:比如 ≥0.8 的步自动执行,低置信的转给 ask_user 或人工复核。第二名选项的概率还能告诉你这一步有多纠结。

记录整个分布而不只是胜出项:0.51 对 0.49 通过阈值的步也值得再看一眼。

每一步的成本

一次成功调用消耗 1 积分,无论带 1 个还是 6 个问题——所以「下一动作 choice + 完成检查」合起来每个循环步仍是 1 积分。

常见问题

这和工具调用有什么区别?

工具调用选择函数并生成参数——形态是开放式的。决策调用从你命名的动作中选一个,带每个选项的概率、没有自由参数,输出在结构上就是受约束的。

state 里该放什么?

模型做决策所需的一切:进度摘要、上一个工具结果、剩余步骤和约束。state 接受字符串、JSON 对象或文本数组。

一次调用能检查的不只是下一动作吗?

可以——单次调用最多 6 个问题。把下一动作 choice 和 noul「任务完成了吗」检查、或待执行步的风险 score 组合在一起。

如果置信度总是很低怎么办?

通常说明动作粒度太细或 state 缺少信号。合并近似动作、丰富 state,并保留 ask_user 作为模型可以诚实选择的兜底。

驱动一个 agent 步

新访客一次免费试用决策——把你的循环状态粘进试用台,看看下一动作的概率分布。