@adminforth/agent

中文文档
3.5.2发布于 2026/11/03MITTypeScriptES Module近 30 天下载 3192

AdminForth 的AI代理插件, 有基于工具的工作流程和持续聊天会话

中文使用文档
文档目录23 节
  1. 特征
  2. 如何运作
  3. 建筑
  4. 一转,一结束
  5. 渐进工具和技能披露
  6. 所需资源
  7. 安装
  8. 设置
  9. 1. 创建存储资源
  10. 2. 配置插件
  11. 3. 行政配置中的注册
  12. 配置参考
  13. sessionResource 字段
  14. turnResource 字段
  15. 工具技能( T)
  16. 人与人之间的核准
  17. 语音
  18. 外部聊天表面( 如 Telegram)
  19. HTTP 终点
  20. 贡献/测试
  21. 关于管理员
  22. 相关链接
  23. 许可证

管理代理插件

License: MIT Build Status npm downloads npm version

Ask AI

在您的 AdminForth 应用程序中添加本地的、工具调用 AI 代理 。 特工住在一个 管理员UI内部的聊天面板,可以通过工具检查和变异您的资源 页:1 管理 MCP 服务器时 逐个回答, 并保持持续聊天会话 .

完整的教程 : 管理代理文档

特征

  • 管理 UI 中的聊天代理 ——每页注入一流聊天面.
  • 调用资源的工具 ——代理人读取并(可选)变异记录 通过 @adminforth/mcp 插件,作为用户运行 AdminForth 自己的 API 处理器, 所以,你的访问规则, 钩和验证仍然适用.
  • 渐进工具和技能披露 ——代理只装入它所需要的工具,引导 按马克下 技能 你可以延长.
  • 人与人之间的核准 - 工具,你标记为危险 暂停明确 运行前从用户批准/拒绝 .
  • 中转方向 ——在代理人仍在工作时再发出指示 折叠到 运行 在它的下一个模式呼叫之前转身,而不是排队等待.
  • 信件编辑分支( Z) ——编辑较早的一条消息,将对话从 转弯的检查站: 后转弯被放弃, 答案被重新生成.
  • 多种模式 ——曝光好几种模式(如:. 快点, (中文(简体) ), 余额d, (中文(简体) ), 聪明的思考(中文(简体) ) 并让用户相互切换.
  • 常年会议 ——对话存储在您的数据库中;可选 检查官继续 整个LangGraph州 横跨.
  • 进退两难 ——通过音频适配器可选的语音对文本和文本对语音.
  • 外部聊天表面 ——通过webhooks(例如. Telegram)与OAuth身份映射.

建造在 朗钱/朗格拉夫。 。 。 .

如何运作

对于每个用户消息,插件创建了一个 转弯,打开进程内连接 @adminforth/mcp 服务器作为用户,构建系统提示( MCP 服务器指令) 以它的技能,然后是代理商自己的规则, 流出模型的输出回过SSE, 并坚持迅速/响应您的转向资源。 每个工具呼叫都是MCP tools/call 连接上; 对话内存按会话保存( q)thread_id = sessionId) (中文(简体) ).

建筑

插件是分层的,以便提供商特有的部件(LangChain/LangGraph 完成适配器, 检查器) 坐在端口后, 永不漏入转动逻辑 :

层目录取决于
域名——即时构建,事件词汇,缓冲域/范围仅管理类型
应用程序——回合使用大小写+端口应用程序/域名
LLM 运行时间 — LangChain/ LangGraph 后端 LlmPort小时/小时应用程序、域、工具
工具——MCP连接,渐进披露工具/设备@adminforth/mcp
持久性——会议、转弯、检查站持久性/行政资源
运输——HTTP端点,SSE,外表面运输/应用程序
前端 — Vue 3 + Pinia 聊天表面习惯/HTTP + SSE合同
flowchart TB
    UI["Admin UI - custom/<br/>Vue 3 + Pinia chat surface"]
    TR["transport/<br/>HTTP endpoints, SSE, external surfaces"]
    APP["application/<br/>RunTurnUseCase + LlmPort"]
    DOM["domain/<br/>prompt building, steer buffer,<br/>events, language detection"]
    LLMS["llm/<br/>LangGraph agent, middleware chain, models"]
    TLS["tools/<br/>MCP connection,<br/>progressive disclosure"]
    PRS["persistence/<br/>sessions, turns, checkpoints"]

    MCPS(["@adminforth/mcp<br/>tools, skills, 2FA confirmation"])
    AF[("AdminForth core<br/>resources, API layer, auth")]
    MODEL(["Completion adapter<br/>OpenAI / Anthropic / Gemini"])
    ADPT(["Audio and chat surface adapters<br/>STT / TTS, Telegram"])

    UI <-->|"POST + SSE"| TR
    TR <--> ADPT
    TR --> APP
    TR -->|"session CRUD"| PRS
    APP --> DOM
    APP --> PRS
    APP -->|"LlmPort"| LLMS
    LLMS --> MODEL
    LLMS --> TLS
    LLMS -->|"checkpointer"| PRS
    TLS -->|"in-process MCP"| MCPS
    MCPS --> AF
    PRS --> AF

每把箭射进 AdminForth core 通过它的普通资源/ API 层, 所以您 进入规则、钩子和验证都同样适用于代理人,就像它们适用于人的管理人员一样. 代理拥有它运行的用户的完全权限: MCP readOnly 选项 仅适用于 MCP 客户端.

一转,一结束

sequenceDiagram
    autonumber
    actor U as User
    participant UI as Chat UI (useAgentChat)
    participant EP as POST /agent/response
    participant UC as RunTurnUseCase
    participant DB as sessions and turns
    participant LLM as LangGraphLlm + AgentRuntime
    participant M as Model (completion adapter)
    participant T as MCP tool (@adminforth/mcp)

    U->>UI: type a message
    UI->>EP: message, sessionId, mode, timeZone, currentPage
    EP->>UC: handleTurn
    UC->>DB: assert session ownership
    UC->>DB: create turn, response = not_finished
    UC-->>UI: data-turn-persisted with turnId
    UC->>M: detect user language (small side call)
    UC->>LLM: streamTurn with system prompt, messages, context

    loop agent loop, recursionLimit 100
        LLM->>LLM: steer middleware drains SteerBuffer
        LLM->>M: model call with currently enabled tools
        M-->>LLM: reasoning and text deltas
        LLM-->>UI: reasoning-delta and text-delta frames
        M-->>LLM: tool call
        alt tool has destructiveHint (agent.requiresHumanApproval)
            LLM-->>UI: data-interrupt, generation pauses
            U->>UI: approve or reject
            UI->>EP: POST /agent/approval
            EP->>UC: resume the interrupted graph
        else safe tool
            LLM->>T: tools/call on the in-process MCP connection
            T-->>LLM: YAML result
            LLM-->>UI: data-tool-call start and end
        end
    end

    LLM-->>UC: stream ends
    UC->>LLM: getLatestCheckpointId, the fork point for edits
    UC->>DB: save response, debug trace, checkpointId
    UC-->>UI: data-response then finish

两个侧道在流上运行:

  • 指导 —— 说 POST /agent/steer 在进程中缓冲消息 SteerBuffer· ; 页:1 beforeModel 在下一个模型之前将中间软件折叠成用户信息 调用和发送 data-steer-applied 转弯已经开通了.
  • 编辑/分支 —— 说 POST /agent/edit 前一转弯的叉已存储 检查点编号,截断后转,再生. 需要两者 checkpointResource 财务报告和审定财务报表 turnResource.checkpointIdField。 。 。 .

渐进工具和技能披露

flowchart LR
    A["Turn starts"] --> B["Exposed tools: MCP get_resources_list,<br/>get_resource, fetch_skill, wait_for_confirmation,<br/>and get_user_location, navigate_user, fetch_tool_schema"]
    B --> C{"Needs more than<br/>reading schema?"}
    C -- no --> D["Answer with the base tools"]
    C -- yes --> E["MCP fetch_skill returns<br/>the matching skill"]
    E --> F["fetch_tool_schema loads one<br/>MCP tool by name"]
    F --> G["McpToolsMiddleware sees the<br/>status 200 tool message and adds that<br/>tool to the next model call"]
    G --> H{"destructiveHint?"}
    H -- yes --> I["humanInTheLoopMiddleware interrupt,<br/>approve or reject in the UI"]
    H -- no --> J["tools/call on the MCP server"]
    I -- approved --> J

所需资源

安装

pnpm add @adminforth/agent @adminforth/mcp @adminforth/completion-adapter-openai-responses

设置

设置有三个部分:(1) 创建存储资源,(2) 配置插件,以及 (3) 在您的行政配置中同时注册。 添加 MCP 插件 改为: globalPlugins。 。 。 . 如果只有代理使用它, new AdminForthMcpPlugin({ internalOnly: true }) 不需要认证 秘密桌子和没有 adminPanelOrigin;为了连接其他 MCP 客户端,设置为 文档描述.

1. 创建存储资源

插件不为您创建表格——您会曝光普通的管理资源 告诉要使用的插件。 实地 名称 由您决定 插件选项可以连接它们 .

届会资源 (必须)
import { AdminForthDataTypes, type AdminForthResourceInput } from 'adminforth';
import { randomUUID } from 'crypto';

const sessionsResource: AdminForthResourceInput = {
  dataSource: 'maindb',
  table: 'sessions',
  resourceId: 'sessions',
  label: 'Sessions',
  columns: [
    { name: 'id', primaryKey: true, type: AdminForthDataTypes.STRING, fillOnCreate: () => randomUUID() },
    { name: 'title', type: AdminForthDataTypes.STRING },
    { name: 'asker_id', type: AdminForthDataTypes.STRING },
    { name: 'created_at', type: AdminForthDataTypes.DATETIME, fillOnCreate: () => new Date().toISOString() },
  ],
  // Agent-internal data: closed to admin users and MCP clients, the agent works with it directly.
  options: {
    allowedActions: { list: false, show: false, create: false, edit: false, delete: false },
  },
};

export default sessionsResource;
转换资源 (必须)
import { AdminForthDataTypes, type AdminForthResourceInput } from 'adminforth';
import { randomUUID } from 'crypto';

const turnsResource: AdminForthResourceInput = {
  dataSource: 'maindb',
  table: 'turns',
  resourceId: 'turns',
  label: 'Turns',
  columns: [
    { name: 'id', primaryKey: true, type: AdminForthDataTypes.STRING, fillOnCreate: () => randomUUID() },
    { name: 'session_id', type: AdminForthDataTypes.STRING },
    { name: 'created_at', type: AdminForthDataTypes.DATETIME, fillOnCreate: () => new Date().toISOString() },
    { name: 'prompt', type: AdminForthDataTypes.TEXT },
    { name: 'response', type: AdminForthDataTypes.TEXT },
    // Optional: map via turnResource.checkpointIdField. Stores each turn's tip
    // checkpoint id — required for message editing / branching.
    { name: 'checkpoint_id', type: AdminForthDataTypes.STRING },
    // Optional: add a `debug` TEXT column and map it via turnResource.debugField
    // to store per-turn debug traces.
  ],
  // Agent-internal data: closed to admin users and MCP clients, the agent works with it directly.
  options: {
    allowedActions: { list: false, show: false, create: false, edit: false, delete: false },
  },
};

export default turnsResource;
检查站资源 (可选的——允许持续的内存)

如果没有这种资源,代理商会使用内置检查器(MemorySaver页:1 重新启动时丢失, 且未在实例中共享 。 生产时,增加检查站资源. 行会随时间而累积,因此推荐用自动清理插件来配对.

import { AdminForthDataTypes, type AdminForthResourceInput } from 'adminforth';

const checkpointsResource: AdminForthResourceInput = {
  dataSource: 'maindb',
  table: 'agent_checkpoints',
  resourceId: 'agent_checkpoints',
  label: 'Agent Checkpoints',
  columns: [
    { name: 'id', primaryKey: true, type: AdminForthDataTypes.STRING },
    { name: 'thread_id', type: AdminForthDataTypes.STRING },
    { name: 'checkpoint_namespace', type: AdminForthDataTypes.STRING },
    { name: 'checkpoint_id', type: AdminForthDataTypes.STRING },
    { name: 'parent_checkpoint_id', type: AdminForthDataTypes.STRING },
    { name: 'row_kind', type: AdminForthDataTypes.STRING },
    { name: 'task_id', type: AdminForthDataTypes.STRING },
    { name: 'sequence', type: AdminForthDataTypes.INTEGER },
    { name: 'created_at', type: AdminForthDataTypes.DATETIME },
    { name: 'checkpoint_payload', type: AdminForthDataTypes.TEXT },
    { name: 'metadata_payload', type: AdminForthDataTypes.TEXT },
    { name: 'writes_payload', type: AdminForthDataTypes.TEXT },
    { name: 'schema_version', type: AdminForthDataTypes.INTEGER },
  ],
  // Agent-internal data: closed to admin users and MCP clients, the agent works with it directly.
  options: {
    allowedActions: { list: false, show: false, create: false, edit: false, delete: false },
  },
};

export default checkpointsResource;

2. 配置插件

// globalPlugins.ts
import AdminForthAgent from '@adminforth/agent';
import CompletionAdapterOpenAIResponses from '@adminforth/completion-adapter-openai-responses';

// Reasoning effort is configured on the completion adapter, not on the plugin.
const createCompletionAdapter = (model: string, effort: 'low' | 'medium' | 'high') =>
  new CompletionAdapterOpenAIResponses({
    openAiApiKey: process.env.OPENAI_API_KEY as string,
    model,
    extraRequestBodyParameters: { reasoning: { effort } },
  });

export const globalPlugins = [
  new AdminForthAgent({
    // The first mode is the default. Users can switch modes in the chat UI.
    modes: [
      { name: 'Balanced', completionAdapter: createCompletionAdapter('gpt-5.4-mini', 'medium') },
      { name: 'Fast', completionAdapter: createCompletionAdapter('gpt-5.4-mini', 'low') },
      { name: 'Smart Thinking', completionAdapter: createCompletionAdapter('gpt-5.4', 'high') },
    ],
    maxTokens: 10000,

    sessionResource: {
      resourceId: 'sessions',
      idField: 'id',
      titleField: 'title',
      askerIdField: 'asker_id',
      createdAtField: 'created_at',
    },
    turnResource: {
      resourceId: 'turns',
      idField: 'id',
      sessionIdField: 'session_id',
      createdAtField: 'created_at',
      promptField: 'prompt',
      responseField: 'response',
      // Enables message editing / branching (together with checkpointResource below).
      checkpointIdField: 'checkpoint_id',
    },

    // Optional but recommended in production:
    checkpointResource: {
      resourceId: 'agent_checkpoints',
      idField: 'id',
      threadIdField: 'thread_id',
      checkpointNamespaceField: 'checkpoint_namespace',
      checkpointIdField: 'checkpoint_id',
      parentCheckpointIdField: 'parent_checkpoint_id',
      rowKindField: 'row_kind',
      taskIdField: 'task_id',
      sequenceField: 'sequence',
      createdAtField: 'created_at',
      checkpointPayloadField: 'checkpoint_payload',
      metadataPayloadField: 'metadata_payload',
      writesPayloadField: 'writes_payload',
      schemaVersionField: 'schema_version',
    },
  }),
];

3. 行政配置中的注册

import sessionsResource from './resources/agent_resources/sessions.js';
import turnsResource from './resources/agent_resources/turns.js';
import checkpointsResource from './resources/agent_resources/checkpoints.js';
import { globalPlugins } from './globalPlugins.js';

const admin = new AdminForth({
  // ...
  resources: [
    sessionsResource,
    turnsResource,
    checkpointsResource, // only if you configured checkpointResource
    // ...your other resources
  ],
  globalPlugins,
});

就这样——现在在管理UI中出现了聊天面板.

配置参考

选项类型需求说明
modes{ name: string; completionAdapter }[]✅可选型号. 这个 第一个 条目是默认模式。 每个模式都有自己的完成适配器.
sessionResourceISessionResource✅会议资源的实地映射(见下文).
turnResourceITurnResource✅转弯资源的实地映射 .
maxTokensnumber—— 说最大代号每个模型调用。 默认 1000。 。 。 .
systemPromptstring—— 说内置代理系统附加的额外文本提示 .
placeholderMessages({ adminUser, headers }) => string[] | Promise<string[]>—— 说示例提示预装入聊天文本区域 。 当聊天 UI 装入时解决一次 .
stickByDefaultboolean—— 说默认聊天面板是否对接( sticky) 。 默认 false。 。 。 .
checkpointResourceICheckpointResource—— 说现场映射可以使持久的LangGraph检查器生效. 回到记忆中 MemorySaver 当省略时.
audioAdapterAudioAdapter—— 说启用语音输入/输出(对文本和对文本).
chatSurfaceAdaptersChatSurfaceAdapter[]—— 说外部聊天表面(如Telegram)通过webhooks服务.
chatExternalIdentityResourceobject—— 说将外部聊天身份(提供方+外部用户id)映射给管理员用户. 聊天表面要求 .

sessionResource 字段

resourceId, (中文(简体) ), idField, (中文(简体) ), titleField, (中文(简体) ), askerIdField, (中文(简体) ), createdAtField。 。 。 .

turnsField 实值 已贬值 被忽略的——会场转折被看透 turnResource.sessionIdField。它仍然为反向兼容进行类型检查,并将是 在未来的主要版本中删除.

turnResource 字段

resourceId, (中文(简体) ), idField, (中文(简体) ), sessionIdField, (中文(简体) ), createdAtField, (中文(简体) ), promptField, (中文(简体) ), responseField, (中文(简体) ), 加上两个可选的:

外地效果
debugField每回合调试的痕迹都写在本列上.
checkpointIdField每个成功转弯的提示检查点的ID被存储,这就是 消息编辑/分支 叉从. 编辑需要这个 财务报告和审定财务报表 checkpointResource; 没有两者, 聊天 UI 隐藏编辑动作和 POST /agent/edit 拒绝这一要求.

作出合理努力 设置在完成适配器上(例如:. extraRequestBodyParameters: { reasoning: { effort } }),而不是插件上.

工具技能( T)

该代理没有自己的工具来获取您的数据: 它是该软件的 MCP 客户端 @adminforth/mcp 服务器,在 进程。 MCP 服务器运行 AdminForth 的 API 处理器,所以每个资源权限、钩子和验证都是执行的,它只显示 资源.

为了保持模式的重点,逐步披露各种工具:

  • 总是可用的: MCP 工具 get_resources_list, (中文(简体) ), get_resource, (中文(简体) ), fetch_skill 并,与 设置双要素认证, wait_for_confirmation;和经纪人自己的 get_user_location, (中文(简体) ), navigate_user 财务报告和审定财务报表 fetch_tool_schema。 。 。 .
  • 所有其他MCP工具都命名,并附有其描述的第一句,出现在 说明 fetch_tool_schema, MCP 客户端按需加载工具计划的方式 列出它们。 代理设备加载工具 fetch_tool_schema 第一次通话之前,还有 技能 装入 fetch_skill 告诉它任务需要哪些工具.

技能来自MCP服务器:其内置 fetch-data, (中文(简体) ), analyze-data 财务报告和审定财务报表 mutate-data附加时 每个 skills/<skill-name>/SKILL.md 在自定义组件目录和其他插件中。 这个 代理的自有系统即时添加了本次聊天的规则和Vega-Lite图表的指南.

时间 get_resource_data 结果来自用户的时区, 由聊天 UI 发送 每一个消息.

人与人之间的核准

端点设定的工具 agent.requiresHumanApproval, MCP 服务器标记为 destructiveHint,触发批准中断:生成暂停和UI显示 批准/拒绝提示 。 客户通过 POST /agent/approval,运行恢复 (或者在拒绝时,该模型被告知该动作被拒绝了).

以标签命名资源和列并列出工具的每个值 将写入 update_record 每个字段在新字段旁边显示其当前值. 数值 masked 财务报告和审定财务报表 backendOnly 从不显示列.

等待审批的有效期取决于您的设置: checkpointResource 配置 langGraph检查点是权威的,所以一个恢复在重启后存活下来,并跨越 实例; 随着内存倒计时, 状态按进程实例进行 .

用户在 MCP 上确认后需要两个要素验证的行动 管理员面板的确认页面:代理显示链接并等待 wait_for_confirmation。 。 。 .

语音

提供 audioAdapter (例如:. @adminforth/audio-adapter-openai(中文(简体) ) 以启用麦克风按钮。 音频被转录到文本中,由代理回答,以及 (可选)合成回语音并流到客户端. 客户端语音 活动检测自动加载.

外部聊天表面( 如 Telegram)

过 chatSurfaceAdapters (例如:. @adminforth/chat-surface-adapter-telegram(中文(简体) ) 揭发代理商在网路上 POST /agent/surface/<adapter-name>/webhook。 。 。 . 进入用户决心通过 chatExternalIdentityResource (与 OAuth 适配器相配,例如 @adminforth/oauth-adapter-telegram),以及 拒绝未经批准的账户.

HTTP 终点

所有路线都在您的 AdminForth API 基础路径下注册 .

方法与路径目的
POST /agent/response发送消息; 流出 SSE 上的答案 .
POST /agent/edit编辑前一个消息:从它的转弯检查站取出叉子,再转弯后再转弯,再生.
POST /agent/approval批准/拒绝待决的 " 入室 " 工具呼叫.
POST /agent/steer缓接中转指令;在下个型号调用前折叠入跑转.
POST /agent/speech-response多段音频上传; 溪流语录+答(+音频).
POST /agent/get-placeholder-messages占位符提示聊天文本区 .
POST /agent/get-sessions列出聊天会话 .
POST /agent/get-session-info找一个会话转弯.
POST /agent/create-session创建新会话 .
POST /agent/delete-session删除会话和轮回.
POST /agent/add-system-message-to-turns追加系统消息转弯 .
POST /agent/append-steer-to-turn坚持一个方向盘进入运行的转弯 存储了即时.
POST /agent/surface/<name>/webhook输入的 Webhook 用于外部聊天表面 .

这个 /agent/response, (中文(简体) ), /agent/edit 财务报告和审定财务报表 /agent/approval 流使用 Vercel AI UI 消息流格式( r)x-vercel-ai-ui-message-stream: v1); 前端消耗它们 直接说. /agent/speech-response 使用插件本身的赤裸事件名称取而代之.

贡献/测试

这个软件包是在 管理单列。 。 。 . 该插件在 测试/ - 运行它从 插件根 :

pnpm install
pnpm test

几起整合级剂检测(adminforth_agent_*.test.ts仍然生活在一个 单曲 tests/jest_tests/ 从目录中运行.

关于管理员

AdminForth是一个开源的代理第一管理框架,用于建设强大的Admin面板 和后台应用程序更快.

许可证

麻省理工学院

版本与发布记录

@adminforth/agent 共发布 238 个版本,首次发布于 2026/04/20;过去 12 个月发布了 238 个版本。

版本发布日期距今
3.5.2latest2026/11/034 天前
3.5.12026/11/034 天前
3.5.02026/10/308 天前
3.4.02026/10/309 天前
3.3.02026/10/2315 天前
3.2.02026/10/2117 天前

关于 @adminforth/agent 的常见问题

@adminforth/agent 是什么?

AdminForth 的AI代理插件, 有基于工具的工作流程和持续聊天会话

如何安装 @adminforth/agent?

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

@adminforth/agent 支持 TypeScript 吗?

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

@adminforth/agent 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@adminforth/agent 可以商用吗?

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

@adminforth/agent 的下载量有多少?

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

@adminforth/agent 还在维护吗?

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