新 AI 助手(/ai-assistant 页面)基于 AgentServer。设计见 docs/ai-assistant-agentserver/。本文是上线前需要手动完成的配置,按顺序执行。旧 Kiro 助手不受影响,不需要改动。
涉及的组件(同一台机器):
| 组件 | 地址 | 说明 |
|---|---|---|
| AgentServer | http://127.0.0.1:8787,后台 /admin/ |
systemd agent-server,用户 agentsvc |
| fwh-agent-mcp(只读) | http://127.0.0.1:8091/mcp |
systemd fwh-agent-mcp |
| fwh-agent-mcp(写,二期) | http://127.0.0.1:8092/mcp |
可选,见第 1.4 节 |
| ToolBox 后端 | 127.0.0.1:8301,路由前缀 /api |
systemd fwh-toolbox-server |
| 对外入口 | Caddy → Apache :8300 → /fwh-toolbox/api → :8301/api |
见第 7 节 |
部署目录 /var/www/fwh-toolbox/server 中的配置文件:
| 文件 | 使用者 | 说明 |
|---|---|---|
config.env |
主服务 fwh-toolbox-server |
第 6 节的 AGENT_* 加在这里。不要新建 .env:程序优先读取 ./.env,存在时 config.env 整个不再生效 |
config.agent-mcp.env |
fwh-agent-mcp |
独立配置(第 1.1 节),不读 config.env |
config.mcp.env |
旧 Kiro MCP | 与新助手无关 |
emspara.db |
主服务、fwh-agent-mcp |
EMS 参数(PID / VID)字典。部署脚本由 EMS 头文件生成并拷贝到这里(service/cmd/deploy_emspara.sh,deploy_toolbox.sh 与 deploy_agent_mcp.sh 都会调用);进程启动时加载到 Redis,Redis 中没有字典时自动重新加载。缺失时 ems_param_lookup 查不到任何编号 |
config.agent-mcp.envfwh-agent-mcp 只读自己的配置文件(-config 可指定,默认工作目录下的 ./config.agent-mcp.env),文件缺失时拒绝启动。它只需要数据库与 Redis、FWH 生产与测试 API、Plane Web,这些值与 config.env 相同,可以照抄;令牌新生成。
下面的命令以示例文件为模板,从 config.env 原样复制同名配置,并生成新令牌(不在终端输出任何值):
cd /var/www/fwh-toolbox/server
test ! -e config.agent-mcp.env || echo "已存在,先确认是否要覆盖"
TOKEN=$(openssl rand -hex 32)
umask 077
awk -v token="$TOKEN" '
NR==FNR { if (match($0, /^[A-Z_]+=/)) { k=substr($0,1,RLENGTH-1); src[k]=$0 } ; next }
/^AGENT_MCP_TOKEN=/ { print "AGENT_MCP_TOKEN=\"" token "\""; next }
match($0, /^[A-Z_]+=/) { k=substr($0,1,RLENGTH-1); if ((k in src) && k !~ /^AGENT_MCP_/) { print src[k]; next } }
{ print }
' config.env ~/web/FranklinWH-ToolBox/deploy/config.agent-mcp.env.example > config.agent-mcp.env
grep -n CHANGE_ME config.agent-mcp.env | cut -d= -f1 # 应无输出;有输出的项需要手动填写
也可以手动 cp deploy/config.agent-mcp.env.example /var/www/fwh-toolbox/server/config.agent-mcp.env 后按 CHANGE_ME 逐项填写,令牌用 openssl rand -hex 32 生成。
文件权限保持 600(服务以 root 运行,可以读取)。
在仓库的 service/ 目录下执行(脚本中的路径相对 service/,在 service/cmd 下执行会构建失败):
cd ~/web/FranklinWH-ToolBox/service && ./cmd/deploy_agent_mcp.sh
脚本会:构建 fwh-agent-mcp → 拷贝到 /var/www/fwh-toolbox/server/ → 首次时安装 /etc/systemd/system/fwh-agent-mcp.service 并 enable → 检查 config.agent-mcp.env 与令牌 → 重启服务。需要 sudo。以后代码更新也是执行这一条。
systemctl is-active fwh-agent-mcp # active
curl -s http://127.0.0.1:8091/healthz # ok
journalctl -u fwh-agent-mcp -n 30 --no-pager # 启动日志;工具调用日志在 server/logs/agent-mcp.log
带令牌列出工具(应为 28 个):
T=$(grep -oP '^AGENT_MCP_TOKEN="?\K[0-9a-f]+' /var/www/fwh-toolbox/server/config.agent-mcp.env)
curl -s -X POST http://127.0.0.1:8091/mcp -H "Authorization: Bearer $T" \
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | grep -o '"name":"[a-z_]*"' | wc -l
复制一份 unit 为 fwh-agent-mcp-ops.service,启动参数改为 -set=ops -listen=127.0.0.1:8092。默认与只读服务共用 config.agent-mcp.env(令牌相同);需要单独的令牌时复制一份配置,加 -config=./config.agent-mcp-ops.env 指定。
打开 AgentServer 后台 /admin/,进入 能力 › MCP 服务 › 添加:
| 项 | 只读服务 | 写服务(二期) |
|---|---|---|
| 传输方式 | 远程 HTTP | 远程 HTTP |
| 显示名称 | FWH 业务数据 | FWH 业务操作 |
| 服务名(工具名前缀) | fwh |
fwhops |
| 服务地址 | http://127.0.0.1:8091/mcp |
http://127.0.0.1:8092/mcp |
| 请求头名称 | Authorization |
Authorization |
| 请求头值 | Bearer <令牌> |
同左 |
fwh / fwhops:技能中的工具名是 mcp__gateway__fwh__*。/mcp,不带斜杠:.../mcp/ 或不带 /mcp 都返回 404。请求头值必须带 Bearer 前缀(Bearer、一个空格、64 位十六进制令牌),不带引号。用下面的命令直接得到完整的值,整行复制:
grep -oP '^AGENT_MCP_TOKEN="?\K[0-9a-f]+' /var/www/fwh-toolbox/server/config.agent-mcp.env | sed 's/^/Bearer /'
编辑已保存的服务时,请求头值输入框留空表示保持原值;原值填错时要重新填写。
点“测试连接”,能列出 28 个工具后保存。只读服务的工具策略保持“直接调用”;写服务保持“跟随权限模式”。连接失败见第 9 节。
AgentServer 开启了 ProtectHome,读不到 /home 下的 Wiki,需要拷贝到 /srv/agent-server/knowledge/:
deploy/scripts/sync_agent_knowledge.sh # 需要 sudo
AGENT_KB_DRY_RUN=y deploy/scripts/sync_agent_knowledge.sh # 预演
源目录可用环境变量覆盖(WIKI_DOCS_DIR、DATA_KB_DIR),说明见脚本头部。同步采用手动方式:Wiki 或数据知识库更新后,需要时再运行一次上面的命令,不配置定时任务。
注意:docs/knowledge 目前是空目录,数据知识库需要补充内容后才有意义。
fwh-assistant技能源码在本仓库 deploy/agent-assistant/skills/fwh-assistant/(SKILL.md、references/、templates/company-template.pptx),不放进 AgentServer 仓库。
AgentServer 以“自定义技能”导入(AgentServer docs/design/12-custom-skills.md),技能 ID 为 custom-skills:fwh-assistant。后台入口:能力 › 技能与插件 › 自定义技能。两种方式任选其一。
cd ~/web/FranklinWH-ToolBox/deploy/agent-assistant/skills && zip -r /tmp/fwh-assistant.zip fwh-assistant
在自定义技能列表顶部点“上传 zip 导入”(云朵图标),选择 /tmp/fwh-assistant.zip,在审阅框中勾选 fwh-assistant 并确认,导入后即发布。以后技能更新需要重新打包上传。
AgentServer 开启了 ProtectHome,看不到 /home 下的仓库目录,先拷贝到 home 以外:
sudo mkdir -p /srv/agent-skill-sources
sudo rsync -a --delete ~/web/FranklinWH-ToolBox/deploy/agent-assistant/skills/ /srv/agent-skill-sources/fwh-toolbox/
在“技能源”中添加目录 /srv/agent-skill-sources/fwh-toolbox,点“扫描并同步”,勾选 fwh-assistant 导入。技能更新后重新执行 rsync,再点“同步”(会显示文件差异,确认后发布)。
导入的技能默认只读,以仓库为准,不要在后台直接修改。
打开 AgentServer 后台 /admin/(本机 http://127.0.0.1:8787/admin/)。
fwh,“测试连接”通过。fwh-wiki:路径 /srv/agent-server/knowledge/fwh-wiki,说明“FranklinWH 产品文档:硬件(aGate/aPower 等)、软件(PCS、调度、OTA 等)、系统(告警码表、事件列表、系统配置)”,只读;fwh-data-knowledge:路径 /srv/agent-server/knowledge/fwh-data-knowledge,说明“ToolBox 数据字段与业务术语说明”,只读(docs/knowledge 有内容后再登记)。fwh-assistant:
report-conventions、custom-skills:fwh-assistant(第 4 节导入后出现在“自定义”分组;自定义技能必须单独勾选,“全部技能”不包含它);fwh-wiki(以及有内容后的 fwh-data-knowledge);fwh;fwh-assistant-ops(二期):在上一个基础上加勾 MCP 服务 fwhops。fwh-assistant,问“站点 的概况和最近 7 天告警”,确认时间线中出现 custom-skills:fwh-assistant 与 fwh 工具调用、不弹审批。
| 项 | 填写 |
| --- | --- |
| 平台名称 | fwh-toolbox |
| 可用的 Profile | fwh-assistant(二期加 fwh-assistant-ops) |
| 默认 Profile | fwh-assistant |
prf_…),第 6 节要用。主服务的 /var/www/fwh-toolbox/server/config.env 增加以下配置(不要新建 .env:程序优先读取 .env,存在时 config.env 整个不再生效):
| 配置项 | 说明 |
|---|---|
AGENT_ENABLED |
true 开启;未开启时“AI 助手”页面显示暂未开放,/agent/* 接口返回 403 |
AGENT_SERVER_URL |
http://127.0.0.1:8787 |
AGENT_SERVER_API_KEY |
第 5 节第 7 步签发的 Key,只放后端 |
AGENT_PROFILE_DEFAULT |
fwh-assistant 的 ID(prf_…);留空时使用 Key 的默认 Profile |
AGENT_PROFILE_BY_ROLE |
可选:角色到 Profile,如 ops:prf_yyy,admin:prf_zzz,按顺序取第一个命中的 |
AGENT_ALLOWED_ROLES |
可选:允许使用的角色,逗号分隔;为空表示所有登录用户 |
Key 不要贴到聊天、工单或命令行参数中。在服务器上执行下面的命令,粘贴 Key 时屏幕不回显:
cd /var/www/fwh-toolbox/server
grep -n '^AGENT_\(ENABLED\|SERVER\|PROFILE\|ALLOWED\)' config.env && echo "已有 AGENT_ 配置,请先检查,避免重复"
read -rsp "AgentServer API Key: " KEY; echo
read -rp "fwh-assistant 的 Profile ID (prf_...): " PRF
cat >> config.env <<EOF
# ---------- 新 AI 助手(AgentServer)----------
AGENT_ENABLED=true
AGENT_SERVER_URL=http://127.0.0.1:8787
AGENT_SERVER_API_KEY="$KEY"
AGENT_PROFILE_DEFAULT=$PRF
AGENT_PROFILE_BY_ROLE=
AGENT_ALLOWED_ROLES=
EOF
unset KEY PRF
sudo systemctl restart fwh-toolbox-server
更换 Key 时直接编辑 config.env 中的 AGENT_SERVER_API_KEY 后重启;旧 Key 在 AgentServer 后台吊销。
pnpm build && pnpm install(install 是本项目的发布脚本,拷贝到 /var/www/fwh-toolbox/fwh-toolbox/)。journalctl -u fwh-toolbox-server -n 30 --no-pager 无报错。/agent/config 返回未开放。检查 AGENT_ENABLED=true、当前用户的角色是否在 AGENT_ALLOWED_ROLES 中(为空则不限制),以及是否已重启后端。菜单本身是静态的,不受这些配置影响。对话事件流的对外路径为 /fwh-toolbox/api/agent/v1/sessions/<会话ID>/stream(SSE)。中间任何一层缓冲都会导致回答一段一段地出现或很久才出现。
/etc/apache2/sites-available/006-fwh-toolbox.conf)现有配置:
ProxyPass /fwh-toolbox/api http://localhost:8301/api
ProxyPassReverse /fwh-toolbox/api http://localhost:8301/api
在它之前加一条(Apache 按配置顺序匹配,必须放在前面):
# 新 AI 助手事件流(SSE):立即转发,长连接
ProxyPassMatch "^/fwh-toolbox/api/agent/v1/sessions/([^/]+)/stream$" "http://localhost:8301/api/agent/v1/sessions/$1/stream" flushpackets=on timeout=3600
然后 sudo apachectl configtest && sudo systemctl reload apache2。
/etc/caddy/sites/002-lmt.zenpower.cc.caddy、001-link-ser.dev.caddy 中的 fwh-toolbox 块)Caddy 对 text/event-stream 响应默认会立即刷新,通常不用改。若仍有缓冲,把现有块:
handle /fwh-toolbox/* {
reverse_proxy localhost:8300
}
改为:
handle /fwh-toolbox/* {
reverse_proxy localhost:8300 {
flush_interval -1
}
}
然后 sudo caddy reload --config /etc/caddy/Caddyfile --force。
AgentServer 默认单文件上限 50MB;ToolBox 后端代理与 Apache 不应小于这个值(Apache 默认不限制请求体;Fiber 的 BodyLimit 由后端配置)。
curl http://127.0.0.1:8091/healthz 返回 200;AgentServer 后台 MCP 服务 fwh 状态正常fwh-assistant 能查询站点数据.agent/mcp/,上下文中没有明细| 报错 | 原因 | 处理 |
|---|---|---|
连接失败 / ECONNREFUSED |
fwh-agent-mcp 没有运行 | systemctl status fwh-agent-mcp;未安装时执行第 1.2 节;启动失败看 journalctl -u fwh-agent-mcp -n 30 |
Error POSTing to endpoint: 404 page not found |
服务地址路径不对 | 地址必须是 http://127.0.0.1:8091/mcp:末尾不带 /,不能省略 /mcp |
{"jsonrpc":"2.0","error":{"code":-32001,"message":"unauthorized"},"id":null} |
请求头令牌不对 | 最常见是值少了 Bearer 前缀;其次是复制了引号、请求头名称不是 Authorization、编辑时留空保留了旧的错误值。按第 2 节的命令重新生成完整的值填写 |
自检:在服务器上执行第 1.3 节的 curl 命令。本机能列出 28 个工具而后台仍失败,问题在后台填写的地址或请求头。
读取配置文件 ./config.agent-mcp.env 失败:部署目录中没有该文件,按第 1.1 节创建。AGENT_MCP_TOKEN 未配置:配置文件中令牌为空。初始化失败:数据库、Redis 或 FWH API 配置有误,对照 config.env 检查同名项。