Pi SDK + Jev:三段式 Agent Harness 实战指南 · 干货攻略

  • 链接:https://x.com/i/article/2102762406204076532
  • 分类:x-tips
  • 来源:X @omarsar0
  • 作者:Jay
  • 更新:2026-09-29

这是什么

本篇来自 @omarsar0(elvis)的实操教程,基于 LangChain 官方博客上 Sydney Runkle 的同名文章,用 Pi SDK(TypeScript AI Agent 开发工具包)从零实现一套完整的三段式 Agent Harness,并将 Jev(TypeSafe AI 的决策模型)接入每个决策节点。

Pi SDK(github.com/earendil-works/pi)是 earendil-works 团队维护的 TypeScript Agent 工具包,MIT 协议,核心包包括:

包 作用
@earendil-works/pi-agent-core Agent 运行时,含工具调用和状态管理
@earendil-works/pi-ai 统一多 Provider LLM API(OpenAI/Anthropic/Google 等 15+)
@earendil-works/pi-coding-agent 交互式 Coding Agent CLI

Jev 是 TypeSafe AI(2026 年 9 月 15 日发布)的决策模型,定位为"System One 模型"——专注判断、不生成文本,输出结构化决策而非自然语言。Jev 版本为 jev-1.13.0(JevAdvBench 基准论文,2026-09-25 查询)。


为什么值得关注

解决什么问题

构建自定义 Agent Harness 时,核心痛点有两个:

  1. 决策判断贵:每次让 LLM 判断"这个工具调用安不安全"、"该用哪个模型"都要调一次完整的 Chat API,成本高、延迟大。
  2. Harness 逻辑散落各处:Gate/路由/验证逻辑混在 Agent 循环里,难以单独测试、难以调整阈值、难以审计。

Jev 把"判断"这件事做成一个廉价、可阈值化的原语:给状态 + 提问 → 返回带概率的结构化答案 → 代码直接做分支。不生成文本,不消耗多余 token。

三段式 Harness 是什么

教程把 Agent 循环中 Jev 插入的位置分成三个命名:

  • Gate(门控):每次工具调用前,问 Jev 一个是否题,决定是否放行
  • Router(路由):根据问题复杂度,问 Jev 该用哪个模型
  • Verifier(验证):Agent 返回最终答案前,问 Jev 答案质量如何

核验结论

关于 Jev 的几个关键说法,交叉核验结果如下:

说法 来源 核验状态
Jev 于 2026 年 9 月 15 日发布 Sanity glossary ✅ 多个来源一致
Diogo Almeida 为前 OpenAI 研究员、InstructGPT 合著者 RLCD glossary ✅ 与公开记录一致
Jev 版本 jev-1.13.0 JevAdvBench arxiv 论文 ✅ 学术来源
RLCD 为 TypeSafe 自创方法,非行业标准 RLCD glossary ⚠️ 标注:厂商主张,无独立复现
Jev 支持 Choice/Score/Noul 三种输出类型 JevAdvBench 论文 ✅ 学术来源一致

上手步骤

环境准备

# 安装 Node.js ≥ 18
# 创建项目
mkdir pi-jev-harness && cd pi-jev-harness
npm init -y
npm install @earendil-works/pi-agent-core

Jev 通过 TypeSafe AI API 调用(需要 API Key),文档地址 typesafe.ai/blog/introducing-system-one-models-and-jev。

第一段:Gate(工具门控)

每次工具调用前问 Jev 一个是否题,最基础的版本:

import { Agent } from "@earendil-works/pi-agent-core";

const agent = new Agent({
  initialState: { systemPrompt, model, tools },
  streamFn: models.streamSimple.bind(models),
});

// 在工具调用前插入 hook
agent.on("before_tool_call", async ({ toolName, toolArgs }) => {
  const decision = await jev.ask({
    type: "Choice",
    prompt: `Should the tool "${toolName}" be allowed to run with args ${JSON.stringify(toolArgs)}? Answer yes or no.`
  });
  if (decision.choice === "no" && decision.confidence > 0.8) {
    throw new Error(`Tool call blocked by Jev gate: ${toolName}`);
  }
});

四个改进方向(对应教程四个 Gap)

教程指出了基础 Gate 的四个问题,并逐一解决:

Gap 1:阈值硬编码 → 把阈值提到 decideGate() 纯函数,形成 Policy 层:

function decideGate(jevResponse) {
  // 阈值集中在一处,便于调参和测试
  const threshold = 0.7;
  return jevResponse.confidence >= threshold ? "allow" : "block";
}

Gap 2:所有请求用同一模型 → Router:根据复杂度动态选模型:

agent.on("before_llm_call", async ({ prompt }) => {
  const complexity = await jev.ask({
    type: "Choice",
    options: ["simple", "moderate", "complex"],
    prompt: `Rate the complexity of this request: ${prompt.slice(0, 200)}`
  });

  const modelMap = {
    simple: "gpt-4o-mini",
    moderate: "gpt-4o-mini",
    complex: "gpt-4o"
  };
  return { model: modelMap[complexity.choice] };
});

Gap 3:Jev 不可用时无降级 → 增加 try/catch + fallback 到人工审批或拒绝:

async function safeGate(toolCall) {
  try {
    return await jev.ask({ ... });
  } catch (err) {
    return { choice: "escalate", confidence: 1.0 }; // 降级人工
  }
}

Gap 4:不检查最终答案 → Verifier:在 Agent 输出前验证质量:

agent.on("before_response", async ({ response }) => {
  const quality = await jev.ask({
    type: "Score",
    prompt: `Rate the quality of this answer: ${response}. Score from 1-5.`
  });
  if (quality.score < 3 && quality.confidence > 0.75) {
    return { rerun: true, reason: "Low quality flagged by verifier" };
  }
});

Pi SDK 的 Hook 机制

Pi 的 Agent 类在循环关键节点暴露 Hook:

Hook 触发时机
before_tool_call 工具调用前(Gate)
before_llm_call LLM 调用前(Router)
after_tool_call 工具调用后
before_response 返回结果前(Verifier)

官方内置了 permission-gate 扩展(packages/coding-agent/examples/extensions/permission-gate.ts),可直接参考。


坑与适用边界

⚠️ Jev 安全性警告(重要)

JevAdvBench 论文(arXiv:2609.31142v1,2026-09-25)对 jev-1.13.0 做了对抗性评测,结论触目惊心:

  • 状态注入:在请求状态中追加一条未验证意见,可导致 12.1% 的决策被翻转
  • 阈值穿透:此类注入使 38% 的高置信度答案(>0.8)跌破 0.8 路由阈值,被强制推向人工审核
  • Rewording 稳定:单纯改写问题表述,偏差在 1.2 个百分点以内(较稳定)
  • Schema 外字段:API 层面会把不合规范的字段预处理掉,不会到达模型

实操建议:不要把用户输入直接拼进 Jev 的 state prompt,必须做清洗和长度截断(教程建议 max_length=200),并始终保留人工兜底路径。

RLCD 方法论声明

RLCD(Reinforcement Learning for Calibrated Decisions)是 TypeSafe 自创术语,非行业标准。无公开论文、无奖励函数说明、无独立复现。其宣称的校准能力来自厂商自身材料,核验受限。性能数字需自行验证,不可盲目信任。

适用边界

  • 适用:需要高频判断(工具安全、模型路由、答案质量)的自定义 Agent;追求比完整 LLM 调用更低延迟和成本的场景
  • 不适用:判断逻辑本身很复杂(需要语义理解)的情况;Jev 不生成文本,无法做开放式推理

一句话结论

用 Pi SDK 的 Hook 机制把 Jev 三段式决策(Gate → Router → Verifier)嵌入 Agent 循环,是让自定义 Harness 同时实现低延迟判断和可审计策略的最直接路径——但必须正视 Jev 对状态注入的脆弱性,始终保留人工兜底。