SETUP.md 15 KB

新 AI 助手部署与配置

新 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 与新助手无关

1. 部署 fwh-agent-mcp

1.1 创建独立配置 config.agent-mcp.env

fwh-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 运行,可以读取)。

1.2 构建并安装服务

在仓库的 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。以后代码更新也是执行这一条。

1.3 验证

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

1.4 写工具服务(二期,可选)

复制一份 unit 为 fwh-agent-mcp-ops.service,启动参数改为 -set=ops -listen=127.0.0.1:8092。默认与只读服务共用 config.agent-mcp.env(令牌相同);需要单独的令牌时复制一份配置,加 -config=./config.agent-mcp-ops.env 指定。

2. 在 AgentServer 登记 MCP 服务

打开 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 节。

3. 同步资料库

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 目前是空目录,数据知识库需要补充内容后才有意义。

4. 部署技能 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。后台入口:能力 › 技能与插件 › 自定义技能。两种方式任选其一。

4.1 上传 zip(首次推荐)

cd ~/web/FranklinWH-ToolBox/deploy/agent-assistant/skills && zip -r /tmp/fwh-assistant.zip fwh-assistant

在自定义技能列表顶部点“上传 zip 导入”(云朵图标),选择 /tmp/fwh-assistant.zip,在审阅框中勾选 fwh-assistant 并确认,导入后即发布。以后技能更新需要重新打包上传。

4.2 登记目录技能源(需要经常同步时)

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,再点“同步”(会显示文件差异,确认后发布)。

导入的技能默认只读,以仓库为准,不要在后台直接修改。

5. AgentServer 后台配置

打开 AgentServer 后台 /admin/(本机 http://127.0.0.1:8787/admin/)。

  1. 概览:确认 Claude 已登录(未登录时点“登录”)。
  2. MCP 服务:按第 2 节登记 fwh,“测试连接”通过。
  3. 资料库 › 新增:
    • 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 有内容后再登记)。
  4. Profiles › 新建 fwh-assistant:
    • 引擎 Claude,模型按需(如 sonnet);
    • 权限模式“需审批”;
    • 技能:report-conventions、custom-skills:fwh-assistant(第 4 节导入后出现在“自定义”分组;自定义技能必须单独勾选,“全部技能”不包含它);
    • 资料库:fwh-wiki(以及有内容后的 fwh-data-knowledge);
    • MCP 服务:fwh;
    • 文件访问:受限(只写工作区);
    • 系统提示词(可选):“你是 FranklinWH ToolBox 的 AI 助手,回答 FranklinWH 储能产品与运维数据相关的问题。用中文回答。”
  5. Profiles › 复制为 fwh-assistant-ops(二期):在上一个基础上加勾 MCP 服务 fwhops。
  6. Playground:选 fwh-assistant,问“站点 的概况和最近 7 天告警”,确认时间线中出现 custom-skills:fwh-assistant 与 fwh 工具调用、不弹审批。
  7. 接入 › API Keys › 签发 Agent Key(不是“签发 Bot Key”):
  8. | 项 | 填写 | | --- | --- | | 平台名称 | fwh-toolbox | | 可用的 Profile | fwh-assistant(二期加 fwh-assistant-ops) | | 默认 Profile | fwh-assistant |

    • Key 的明文只显示一次,立即复制;丢失只能吊销后重新签发。
    • 在 能力 › Profiles 记下各 Profile 的 ID(prf_…),第 6 节要用。
    • 页面提示的“设置 › 安全”中的 CORS 来源不需要配置:浏览器只请求 ToolBox 后端,由后端代理访问 AgentServer,Key 不出后端。

    6. ToolBox 后端配置

    主服务的 /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 可选:允许使用的角色,逗号分隔;为空表示所有登录用户

    6.1 写入配置

    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 后台吊销。

    6.2 发布前端并验证

    1. 前端用包含新助手的分支重新构建并发布:pnpm build && pnpm install(install 是本项目的发布脚本,拷贝到 /var/www/fwh-toolbox/fwh-toolbox/)。
    2. journalctl -u fwh-toolbox-server -n 30 --no-pager 无报错。
    3. 登录 ToolBox,打开左侧菜单“AI 助手”;新建会话、发一条消息,回答逐字流式出现。回答成段出现时按第 7 节关闭代理缓冲。
    4. 页面显示“AI 助手暂未开放”:后端 /agent/config 返回未开放。检查 AGENT_ENABLED=true、当前用户的角色是否在 AGENT_ALLOWED_ROLES 中(为空则不限制),以及是否已重启后端。菜单本身是静态的,不受这些配置影响。

    7. 反向代理:关闭流式接口的缓冲

    对话事件流的对外路径为 /fwh-toolbox/api/agent/v1/sessions/<会话ID>/stream(SSE)。中间任何一层缓冲都会导致回答一段一段地出现或很久才出现。

    7.1 Apache(/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。

    7.2 Caddy(/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。

    7.3 上传大小

    AgentServer 默认单文件上限 50MB;ToolBox 后端代理与 Apache 不应小于这个值(Apache 默认不限制请求体;Fiber 的 BodyLimit 由后端配置)。

    8. 验证清单

    • curl http://127.0.0.1:8091/healthz 返回 200;AgentServer 后台 MCP 服务 fwh 状态正常
    • Playground 用 fwh-assistant 能查询站点数据
    • ToolBox 登录后左侧有“AI 助手”,能新建会话并得到流式回答(文字逐字出现)
    • 回答中引用 Wiki 文档时能给出路径
    • 多日功率流分析时,导出文件出现在工作区 .agent/mcp/,上下文中没有明细
    • 用另一个账号打开别人的会话链接,提示无权访问

    9. 常见问题

    9.1 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 个工具而后台仍失败,问题在后台填写的地址或请求头。

    9.2 fwh-agent-mcp 启动即退出

    • 读取配置文件 ./config.agent-mcp.env 失败:部署目录中没有该文件,按第 1.1 节创建。
    • AGENT_MCP_TOKEN 未配置:配置文件中令牌为空。
    • 初始化失败:数据库、Redis 或 FWH API 配置有误,对照 config.env 检查同名项。