Skip to content

Agent Service

xiweicheng edited this page Oct 27, 2026 · 11 revisions

代理服务

AI Helper 扩展可选配一个 Node.js 代理服务(Agent),提供浏览器沙箱之外的文件系统、终端命令、Skill、MCP 协议、本地知识库(RAG) 与文件上传能力。

← 返回 Wiki 首页 · 相关内容:内建工具参考 · 配置说明 · 常见问题


为什么需要代理服务

浏览器扩展运行在受限的沙箱中,无法直接读写本地文件或执行系统命令。Agent 服务是一个跑在本机的独立进程,扩展通过 127.0.0.1:18910 与它通信,从而解锁:

  • 读写本地文件、浏览工作目录、上传下载文件
  • 执行终端命令(带三级安全策略)
  • 使用 Skill 技能系统
  • 通过 MCP 协议扩展第三方工具
  • 本地知识库(RAG)检索增强问答
  • 跨会话长期记忆

可选性:不安装 Agent 也能使用绝大部分网页操作功能;文件问答会自动降级为浏览器端提取。


安装与启动

全局安装(推荐)

npm install -g ai-helper-agent

要求 Node.js >= 18.0.0。

启动

# 前台启动(终端显示实时运行日志,适合调试)
ai-helper-agent start

# 后台启动(守护进程模式,终端立即返回)
ai-helper-agent start --background
ai-helper-agent start -b

# 指定工作目录和端口
ai-helper-agent start --workdir /path/to/your/project --port 18911

启动后终端会显示一个 6 位配对码,在扩展选项页的「Agent」标签页中填入即可完成配对。

本地开发模式

cd agent
npm install
npm start
# 默认监听 127.0.0.1:18910

启动选项

--background, -b    后台运行(守护进程模式)
--port <端口>       监听端口,默认 18910
--host <地址>       监听地址,默认 127.0.0.1
--workdir <目录>    工作目录(文件读写限制在此范围内)

CLI 命令

命令 说明
ai-helper-agent start / start -b 前台 / 后台启动
ai-helper-agent stop 停止运行中的 Agent
ai-helper-agent restart / restart -b 重启服务
ai-helper-agent status 查看运行状态
ai-helper-agent paircode 查看配对码
ai-helper-agent config 查看当前配置
ai-helper-agent rag status / rag install 检测 RAG 依赖可用性 / 一键安装 RAG 依赖
ai-helper-agent help 显示帮助信息
ai-helper-agent --version / -v 显示版本号

aha 是 ai-helper-agent 的快捷别名,例如 aha start -b。

前台 vs 后台

模式 命令 终端行为 适用场景
前台 start 阻塞终端,实时显示运行日志 开发调试、问题排查
后台 start --background 立即返回,终端无日志输出 生产环境、日常使用

前台运行时,所有操作日志会以格式化形式实时输出到终端:

[12:30:01] [INFO] [文件:read] path=/project/src/index.js size=2048
[12:30:05] [INFO] [命令:started] command="npm test" cwd=/project execId=a1b2c3d4
[12:30:12] [INFO] [命令:completed] execId=a1b2c3d4 exitCode=0 killed=false
[12:31:00] [WARN] [安全:exec_denied] command="rm -rf /" reason=高危命令被拦截

进程管理

Agent 通过 PID 文件(~/.ai-helper-agent/agent.pid)管理进程生命周期:

  • 启动时自动写入 PID 文件
  • stop 命令优先通过 API 优雅关闭,失败则通过 PID 文件 kill 进程
  • 正常关闭时自动清理 PID 文件
  • 命令整树终止:停止命令(/api/exec/stop)或超时终止按整棵进程树清理——npm 等派生出的孙进程(下载 / 编译子任务)一并终止,不会留下孤儿进程继续写磁盘;POSIX 对进程组发信号,Windows 使用 taskkill /T

安全机制

文件沙箱

所有文件操作限制在配置的 allowedPaths 白名单目录内。通过 realpath 解析防止符号链接绕过,确保物理路径安全。

注:沙箱作用于文件类工具(读写 / 删除 / 移动);命令执行走下面的分级名单,不经过 allowedPaths 判定。

命令分级管控

黑名单 —— 直接拦截,不可绕过:

类型 示例
磁盘破坏 rm -rf /、mkfs.*、dd if=... of=/dev/...
递归删除关键系统目录 rm -rf /usr、/var、/bin、/sbin、/lib、/boot、/opt、/root、/System、/Library
系统文件覆盖 > /etc/passwd、> /etc/shadow
恶意管道执行 curl ... | bash、git clone ... | sh
Fork bomb :(){ :|:& };:

灰名单 —— 需要用户确认后才执行:

命令模式 原因
sudo ... 需要管理员权限
npm install -g ... 全局安装包
pip install/uninstall Python 包管理
chmod -R 777、chmod 000、chmod a-rwx 修改权限致文件不可用
chown ... 修改文件属主
rm -rf ...(含 rm -r -f、rm --recursive --force,相对与绝对路径均算) 递归强制删除
dd of=...(写普通文件) 裸写文件内容
shred、truncate -s 0 / --size=0 销毁 / 清空文件
curl、wget、nc、telnet、ssh、scp 向外发起网络连接
kill、pkill、killall 结束进程
systemctl、launchctl、crontab、sysctl 系统服务 / 计划任务 / 内核参数
git push --force 强制推送
shutdown/reboot 关机 / 重启
doas ...、runas /user: ... sudo 的同类提权方式
Remove-Item -Recurse/-Force PowerShell 递归 / 强制删除
pwsh -EncodedCommand ... 执行 base64 编码的 PowerShell 脚本
反引号、$() 命令替换 静态看不出替换结果流向哪里

白名单 —— 常规命令,直接放行。

⚖️ 逐段判定:名单不只检查命令串开头。一条命令会先展开成多个「子命令范围」后逐段送检,取最严结果: shell 控制符拆段(&&、||、;、管道、&、换行)、环变量前缀与前缀包装器剥壳(nohup / time / env / timeout / nice / command / xargs,以及提权前缀 sudo / doas)、 解释器内联载荷递归解开(bash -c、python -c、cmd /c、powershell -Command / -EncodedCommand)、$() 与反引号内部单独取出。 因此 cd /tmp && sudo apt install foo、echo 1234 | sudo -S ...、nohup sudo ...、bash -c "rm -rf /" 均不能逃过确认 / 拦截; 而引号内的普通文本不会被误伤(grep -c "sudo rm -rf /" notes.txt 依旧直接放行);但引号里嵌了替换时会逐层取出内层命令(bash -c "echo \rm -rf /`"、echo "text $(sudo id) text"` 仍能命中黑名单 / 灰名单)。判定只会变严不会变宽。

🔒 提权前缀不是降级通行证:sudo / doas 会被逐层剥壳后送检,所以 sudo rm -rf /usr、sudo mkfs、sudo dd of=/dev/sda、sudo sh -c "rm -rf /usr"、curl … | sudo sh 这些绝对禁止项仍是 deny(不会因披了层 sudo 而降为确认);剥壳保留 sudo … 中间形态,nohup sudo apt install foo 这类仍需确认。 重定向覆盖系统文件不再只认行首(echo x > /etc/passwd 一样 deny);路径写法变形会被归一化(rm -rf //usr、rm -rf /.//usr 等价 /usr,同判 deny)。 黑名单「改根目录权限 / 属主」只针对目标本身就是根 /(chmod -R 777 /、chown -R root /),普通绝对路径(chmod 777 /tmp/x)回落灰名单确认而非硬拒。

🔍 命令替换只拦「语法可疑」,不当「效果危险」:这一项特征单独享有一层只读豁免—— 头命令属于 echo / printf / cat / ls / pwd / cd / whoami / test 这类不落盘的只读类时, 不会因为后面带了 $(…) 就整串一票否决(pwd; echo $(date +%s)、cd /tmp && echo \ls` 直接放行)。 替换出现在赋值右侧(a=$(echo hi))、内联载荷里(bash -c 'echo $(echo hi)')或引号参数里(git commit -m "feat: $(date)")时仍要确认; 替换**内部**的命令照常送黑白名单,所以 echo $(sudo id) 该确认、cd /tmp && echo `rm -rf /`` 该拦仍然拦住。豁免只覆盖替换这一项特征,黑名单与其余灰名单条目不享豁免。

已知边界:变量间接执行(S=rm; $S -rf ./x)、脚本文件正文内容、以及「读取即外泄」(cat /etc/passwd)静态无法分类,不在这一层处理。

认证机制

首次配对时用户在扩展中输入终端显示的 6 位配对码完成配对(配对码每 30 秒轮换)。配对成功后使用 HMAC token 做后续请求认证,存储在 ~/.ai-helper-agent/pairings.json。

其他保护

  • 环境变量白名单(约 40 个),TERM=dumb 禁用交互式命令
  • 脚本保护:写入 .sh / .py / .js 等自动去除执行权限
  • 大小限制:请求体 10MB,单文件 50MB

配置文件

配置文件路径:~/.ai-helper-agent/config.json

{
  "port": 18910,
  "host": "127.0.0.1",
  "workdir": "/path/to/project",
  "allowedPaths": [],
  "pairCodeTTL": 30,
  "commandTimeout": 300000,
  "fileMaxSize": 52428800
}
字段 说明 默认值
port 监听端口 18910
host 监听地址 127.0.0.1
workdir 默认工作目录 启动时当前目录
allowedPaths 额外允许访问的目录列表 []
pairCodeTTL 配对码有效期(秒) 30
commandTimeout 命令执行超时(毫秒) 300000(5 分钟)
fileMaxSize 文件读写最大字节数 52428800(50MB)

HTTP API

无需认证

方法 路径 说明
POST /api/pair 配对认证
GET /api/status 健康检查(版本号、平台信息、搜索工具可用性)
POST /api/shutdown 关闭代理服务(仅限本地访问)

需要认证(Bearer Token)

方法 路径 说明
POST /api/fs/read 读取文件内容
POST /api/fs/write 写入文件
POST /api/fs/list 列出目录
POST /api/fs/delete 删除文件 / 目录(默认走回收站)
POST /api/fs/stat 文件详情(权限、UID/GID、MIME、时间戳)
POST /api/fs/upload-stream 流式上传
POST /api/fs/download-stream 流式下载
POST /api/fs/preview-xlsx Excel 解析预览
POST /api/files/upload 文件上传
POST /api/fs/search_files 按文件名模式搜索(glob)
POST /api/fs/search_content 搜索文件内容(rg 优先,Node.js 回退)
POST /api/exec 执行系统命令
POST /api/exec/stop 停止命令执行
GET /api/exec/running 运行中的进程列表
GET /api/status/detail 详细信息(含工作目录、配对码、搜索工具)
GET /api/logs 查询审计日志(支持 date/category/limit/offset)
GET /api/logs/dates 获取可用日志日期列表
POST /api/agent/restart 在线重启 Agent
POST /api/agent/update 在线更新 Agent
POST /api/trash/restore 从回收站恢复文件
GET /api/trash/list 回收站列表

长期记忆(/api/memory/*)

记忆的提取、存储与召回都在 Agent 进程内完成(条目落在 ~/.ai-helper-agent/memory/global-memory.json,派生向量缓存 memory-vectors.json),扩展端 tool-memory.js 只做转发。同样需要 Bearer Token。

方法 路径 说明
POST /api/memory/store 写入 / 更新 / 删除记忆条目(add / update / delete),带类型、标签与重要性
POST /api/memory/recall 召回记忆:关键词通道与语义向量通道融合排序,返回 tier(none / remote / local)与 vectorMatched
POST /api/memory/manage 记忆治理:审查质量(review)、压缩淘汰低价值记忆(compact)
POST /api/memory/inject 装配本轮对话要注入的记忆内容
POST /api/memory/reindex 按当前 embedding 配置重建全部向量;向量档未启用时返回 skipped: true
GET / POST /api/memory/embedding-config 读取 / 保存语义召回配置;明文 API Key 永不回显,只返回 hasApiKey;传 clearApiKey: true 显式清除
POST /api/memory/test-embedding 探活(8 秒超时保护),请求体可覆盖尚未保存的草稿配置
GET /api/memory/vector-status 只读状态:已索引 / 总条数、向量指纹与陈旧判定、生效档位

各配置项的含义与选项页入口见 配置说明 → 记忆(向量召回)配置。

语音识别(/api/asr/*)

本地语音输入的推理、模型管理与依赖安装在 Agent 进程内完成(模型落在 ~/.ai-helper-agent/asr/models/,配置 asr-config.json);流式定稿在独立 worker 线程里跑,不会阻塞其他接口。同样需要 Bearer Token。

方法 路径 说明
GET /api/asr/status 依赖 / 模型 / 开关 / 已加载引擎状态
POST /api/asr/config 修改配置(开关、语言、模型 id、空闲卸载)
GET /api/asr/models 已扫描模型包列表(非法包附原因)
POST /api/asr/models/scan 重新扫描模型目录
POST /api/asr/models/pick 从指定目录导入模型包
GET /api/asr/models/catalog 可下载模型清单
POST /api/asr/models/download 下载模型(支持断点续传 + 哈希校验)
GET /api/asr/models/download/status 下载进度
POST /api/asr/models/download/cancel 取消下载
POST /api/asr/transcribe 整段音频(WAV)一次性识别
POST /api/asr/warmup 预热引擎(启动时自动执行一次)
POST /api/asr/deps/detect 检测 sherpa-onnx 依赖
POST /api/asr/deps/install 安装依赖(白名单命令)
GET /api/asr/deps/install/status 安装进度

启用步骤与完整协议见 语音输入(本地 STT)。

WebSocket

路径 说明
ws://127.0.0.1:18910/ws/exec/:execId 命令执行实时输出流
ws://127.0.0.1:18910/ws/asr/:sessionId 语音识别流式会话(PCM 上行,partial / final 下行)

Skill 系统

Agent 服务内置 Skill 系统,支持将操作流程沉淀为可复用的技能。

Skill 类型

类型 定义格式 执行方式 用途
Workflow Skill JSON / YAML 直接执行 自动化流程,按步骤执行
Agent Skill SKILL.md AI 自主调用 知识沉淀,在对话中触发

目录结构

所有 Skill 存储在 ~/.ai-helper-agent/skills/ 目录下:

~/.ai-helper-agent/skills/
├── workflow-skill.json          # Workflow Skill(JSON 格式)
├── another-skill.yaml           # Workflow Skill(YAML 格式)
└── agent-skill/                 # Agent Skill(目录形式)
    ├── SKILL.md                 # 技能定义文件
    └── _meta.json               # 元数据(可选)

SKILL.md 格式

---
name: <skill-name>
description: "<简明描述,包含:(1) 技能做什么,(2) 何时触发调用>"
enabled: true
---

# <技能标题>

## When to Use This Skill

- 触发条件 1
- 触发条件 2

## Core Capabilities

- 能力 1
- 能力 2

## Usage

### Step-by-Step

1. 步骤 1
2. 步骤 2

## Examples

[具体示例]

## Source

从对话中沉淀,创建日期:YYYY-MM-DD

内置技能

  • skill-creator:元技能,用于从对话中创建和更新其他技能。

Skill API

方法 路径 说明
GET /api/skill/list 获取所有 Skill 列表
GET /api/skill/:name 获取单个 Skill 完整定义
POST /api/skill/import 导入新 Skill
POST /api/skill/:name/toggle 切换启用 / 停用状态
DELETE /api/skill/:name 删除 Skill
POST /api/skill/:name/run 执行 Workflow Skill

MCP 协议扩展

支持 Model Context Protocol(MCP),扩展第三方工具能力。

MCP Server 配置

配置文件路径:~/.ai-helper-agent/config.json

{
  "mcpServers": [
    {
      "id": "my-mcp-server",
      "name": "My MCP Server",
      "command": ["python", "-m", "my_mcp_server"],
      "enabled": true
    }
  ]
}

MCP API

方法 路径 说明
GET /api/mcp/status 获取所有 MCP Server 状态
POST /api/mcp/:serverId/connect 连接指定 MCP Server
POST /api/mcp/:serverId/disconnect 断开连接
GET /api/mcp/tools 获取所有 MCP 工具列表

工作原理

  1. Agent 启动时自动连接所有启用的 MCP Server
  2. 通过 stdio 建立 JSON-RPC 2.0 通信
  3. 自动发现 MCP Server 提供的工具
  4. 工具调用请求通过 Agent 转发到 MCP Server
  5. 工具结果返回给扩展

也可在扩展选项页「工具箱」Tab 中可视化添加和管理 MCP Server。


知识库(RAG)

可选的本地检索增强生成(RAG)能力:将文档索引为可检索的知识库,让插件回答时附带引用来源。

  • 依赖可选 —— Agent 启动时自动检测可用性,通过 /api/rag/status 对外暴露;依赖缺失时 RAG 请求返回 503,插件端提供一键安装(白名单依赖,进度可经 /api/rag/install/status 轮询),也可通过 CLI 安装:aha rag install
  • 启动自动恢复 —— 曾成功安装过依赖的用户:npm -g 更新代理会清理包目录内手动安装的依赖,Agent 启动检测到缺失时自动重新安装(标记 trigger=auto),用户零操作;从未安装成功过的用户不触发
  • 数据位置 —— 知识库存储于 ~/.ai-helper-agent/rag/(可用环境变量 AI_HELPER_RAG_ROOT 覆盖)
  • 多知识库管理 —— 创建 / 更新 / 删除 / 启用 / 停用知识库,各自维护向量配置与统计信息
  • 多格式导入 —— .txt .md .json .csv .html / PDF / Word(mammoth)/ PPT(officeparser)/ Excel;支持文本、文件(base64)、URL 三种导入方式
  • 混合检索 —— 向量相似度 + 关键词命中抬分(中英文混合关键词提取);跨库检索时 topK 配额按库均分
  • 可插拔向量化 —— 默认本地模型(Xenova/bge-small-zh-v1.5,512 维,经 @huggingface/transformers 本地运行),也可接入任意 OpenAI 兼容向量服务
  • 索引重建 —— 知识库向量空间变更时后台自动重建(临时目录重放 → 原子换入)

RAG API

以下接口注册在认证区内(需 Bearer Token),且仅在 RAG 依赖可用时按需加载。

方法 路径 说明
POST /api/rag/install 触发白名单 RAG 依赖安装
GET /api/rag/install/status 安装进度
POST /api/rag/detect 重新检测 RAG 依赖可用性
GET /api/rag/status 能力与安装状态
POST /api/rag/test-embedding 测试远端向量服务连通性(返回实际维度)
GET /api/rag/collections 列出知识库
POST /api/rag/collections 创建知识库
PUT /api/rag/collections/{id} 更新名称 / 描述 / 向量配置
DELETE /api/rag/collections/{id} 删除知识库
POST /api/rag/collections/{id}/toggle 启用 / 停用知识库
GET /api/rag/collections/{id}/stats 文档数 / 分块数统计
POST /api/rag/collections/{id}/ingest 导入文本 / 文件 / URL
GET /api/rag/collections/{id}/ingest/status 导入进度快照
GET /api/rag/collections/{id}/documents 文档列表
DELETE /api/rag/collections/{id}/documents/{docId} 删除文档
POST /api/rag/collections/{id}/search 单库检索
POST /api/rag/search 跨知识库检索

长期记忆

跨会话长期记忆由 Agent 全权托管:存储文件、读写互斥锁、召回计分、审查淘汰、注入筛选全部在 Agent 进程内完成,插件只转发 agent_memory 工具调用(不再走通用文件 API 往返,也不受插件 Service Worker 生命周期影响)。

  • 数据位置 —— 记忆存储于 ~/.ai-helper-agent/memory/global-memory.json(facts + summaries + stats)
  • 记录字段 —— id / type(fact 或 summary)/ category / content / title / tags / importance(1–10)/ accessCount / lastAccessAt / createdAt / updatedAt / sourceSessionId
  • 三级注入 —— Tier 1/2 只对 fact 生效:importance >= 8 常驻,其余按价值排序在 1500 字符 + 12 条预算内注入;summary 一律不注入,与剩下的 facts 一起只以标签索引行提示,由模型主动 recall 拉取
  • 召回计分 —— 关键词命中 content +3 / title +2 / tags +2;查询原文(≥ 2 字)出现在 content 中再 +5、出现在 title 中再 +3;中文不超过 4 字的连续段整段保留、更长拆为 bigram,英文数字整词,停用词过滤,最多 30 个关键词(零外部依赖)
  • 语义向量通道 —— 可选能力:在选项页「记忆」Tab 配置 embedding 并保存后,召回会叠加一路向量语义检索,与关键词通道按名次融合(语义档取相似度 top-K,不设绝对分数门槛);档位分为 none(未启用,纯关键词)/ remote(OpenAI 兼容端点)/ local(本地模型,需 RAG 依赖),向量不可用时静默回落关键词通道,不影响对话
  • 向量派生与重建 —— 向量缓存在记忆文件同目录的 memory-vectors.json,由记忆条目派生、可丢可重建;按「来源 + 模型 + 维度 + 前缀」拼出的指纹归档,换配置后须调 reindex 重建,否则 vector-status 判定为陈旧且语义名次静默退化
  • 价值与淘汰 —— 价值 = importance × (1 + ln(accessCount + 1)) × 时间衰减(≤ 7 天 1.0 / ≤ 30 天 0.8 / ≤ 90 天 0.5 / 更早 0.2);价值降到 10 以下由 manage 的 compact 淘汰
  • 容量提醒 —— meta.maxFacts 默认 50、maxSummaries 默认 20;达到 80% 时 store 响应附带接近上限提醒(不自动删除,清理需显式 compact)
  • 压缩摘要来源 —— 除 agent_memory 工具主动写入外,插件的会话上下文压缩会自动沉淀摘要:type: summary / category: decision / importance: 6 / 标签 compaction + session:<会话 ID>;同一会话重复压缩按 memoryId 走 update(不新增条目),沉淀失败只记日志,不影响已生成的会话摘要
  • 图形化入口 —— 选项页「记忆」Tab 底部的条目管理区不发明新接口,直接复用 manage(review / compact)与 store(update / delete):列表走只读的 review(不会产生 accessCount 记录,也不受会话去重缓存影响);编辑走 update,后台重算该条向量;删除与压缩会同步 dropVectors 并从会话召回缓存摘除,不留指向已删条目的孤儿向量
  • 会话去重 —— Agent 进程内记录本次对话已召回的记忆,重复召回时返回已检索过提示
  • 国际化 —— 响应文案按请求 Accept-Language 渲染

长期记忆需要带 /api/memory/* 端点的 Agent 版本。插件不会回退到通用文件 API:端点缺失时直接提示升级 Agent;Agent 未连接时记忆能力整体不可用。


文件搜索

Agent 优先使用系统原生搜索工具,不可用时自动回退到 Node.js 实现:

引擎 用途 检测命令
fd 文件名搜索(快速) fd --version
rg (ripgrep) 文件内容搜索(快速) rg --version

审计日志

所有操作自动记录到审计日志,日志文件位于 ~/.ai-helper-agent/logs/。

双通道输出

  • 终端输出(前台模式):格式化可读格式,输出到 stderr
  • 文件输出:JSON Lines 格式,写入日志文件(按日命名 agent-YYYY-MM-DD.log)

日志分类

category 说明 包含的操作
auth 认证事件 配对成功 / 失败
fs 文件操作 read, write, list, delete, search_files, search_content
exec 命令执行 started, completed, stopped, error
security 安全事件 deny, confirm, auth 失败, 路径越权拦截
system 系统事件 server_start, server_stop, shutdown, server_error 等

日志查询 API

GET /api/logs?date=2026-01-15&category=security&limit=50&offset=0
GET /api/logs/dates
  • date - 日期筛选 (YYYY-MM-DD),不传默认今天
  • category - 分类筛选,不传返回全部
  • limit - 返回条数上限,默认 200
  • offset - 分页偏移

自动清理

  • 最多保留 30 个日志文件
  • 单文件超过 10MB 自动删除

技术栈

  • Node.js >= 18
  • 原生 http 模块(HTTP 服务)
  • ws 库(WebSocket 服务)
  • 零外部框架依赖
  • 可选依赖:fd、rg(ripgrep)— 用于加速文件搜索
  • RAG 可选依赖:vectra(向量存储)、@huggingface/transformers(本地向量化)、pdf-parse / mammoth / officeparser / cheerio(文档解析)

Clone this wiki locally