npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bty/customer-service-cli

v0.7.7

Published

AI Customer Service CLI - Agent friendly

Readme

AI 客服 CLI

供客户、内部人员与 Agent 调用的 AI 客服命令行工具。所有输出默认为 JSON 格式,便于程序解析。

安装

通过 npm 全局安装(推荐)

npm install -g @bty/customer-service-cli

安装后即可直接使用 cs-cli 命令。

从源码构建

pnpm install
pnpm build

构建产物位于 dist/bin.js,可通过 cs-cli 命令调用。

源码入口与多行配置

推荐在 packages/customer-service-cli 目录用 pnpm exec tsx src/bin.ts <args> 跑源码;生产配置写入须先取得明确授权,备份目标字段,写后回读并逐字核对。多行 SA 使用 UTF-8 文件(--situation-file / --action-file),Agent 补丁使用 --data @patch.json,文件读取保留 CRLF、末尾换行和字面反斜杠。

仓库的 pnpm --filter @bty/customer-service-cli --silent dev <args> 也保留真实换行。它通过本包启动器解码 pnpm 9 的原始 JSON 参数,并用无 shell 的 Node/tsx 运行 CLI,避免 pnpm 9 把 LF 变成字面 \n 或展开 $() 等内容;支持 macOS/Linux 的 POSIX shell + pnpm 9(仓库固定 9.15.4)。Windows、npm/yarn、其他 pnpm 大版本或不能解析的生命周期参数会停止执行,请改用上述 pnpm exec 入口。不要删掉 package.json 中 dev 脚本末尾的 #。

默认 API 地址

未传 --env 或使用 --env prod 时可使用以下内置地址;--env dev 需要先配置该环境的服务地址:

| 服务 | 默认地址 | | -------------- | --------------------------------------------- | | 客服 API | https://customer-servhub-api.betteryeah.com | | Dashboard 只读 API | 客服 API 地址追加 /observability | | AI API | https://ai-api.betteryeah.com | | Customer Agent | https://customer-agent.bantouyan.com | | Langfuse | http://192.168.40.10:3000 |

AI API 同时服务于登录认证(auth login / auth whoami),不再区分独立的 "认证 API" 字段。

如需覆盖,可通过 cs-cli config set 修改:

cs-cli config set --cs-api https://your-api.example.com

Dashboard 命令会自动请求该地址下的 /observability/v1/dashboard/**。

API 地址优先级

未传 --env 时,每个 API 地址的读取顺序为 环境变量 > config.json > 内置默认值。环境变量为 undefined 或空字符串 "" 都视为未设置,继续向下 fallback。显式环境只读对应环境的配置;prod 可使用内置地址,dev 缺配置会报错,避免请求落到生产。

| 环境变量 | 覆盖字段 | 默认值 | | ----------------------- | ------------------- | --------------------------------------------- | | CS_CS_API_URL | customerServiceApiUrl | https://customer-servhub-api.betteryeah.com | | CS_AI_API_URL | aiApiUrl(同时服务 auth 调用) | https://ai-api.betteryeah.com | | CS_CUSTOMER_AGENT_URL | customerAgentApiUrl | https://customer-agent.bantouyan.com | | CS_CS_ADMIN_URL | csAdminUrl | https://customer-service-admin.betteryeah.com |

快速开始

# 登录
cs-cli auth login --phone 13800000000 --password yourpassword

# 查看当前用户
cs-cli auth whoami

# 设置默认工作空间
cs-cli config set-workspace <workspace_id>

# 列出 Agent
cs-cli agent list

同时登录 dev 与线上

全局 --env dev|prod 选择本次命令的 API 地址、登录态和默认工作空间,推荐放在一级命令前。每个环境登录一次即可交替执行,无需反复改配置:

# 一次性配置 dev;替换为部署提供的真实地址
cs-cli --env dev config set --cs-api <dev客服API地址> --ai-api <dev登录及AI地址>
# 使用 Customer Agent / cs-admin 命令时再配置相应服务
cs-cli --env dev config set --agent-api <devCustomerAgent地址> --admin-api <dev后台地址>

cs-cli --env dev auth login --phone 13800000000 --password yourpassword
cs-cli --env prod auth login --phone 13800000000 --password yourpassword
cs-cli --env dev config set-workspace <dev工作空间ID> --global
cs-cli --env prod config set-workspace <线上工作空间ID> --global

cs-cli --env prod agent list
cs-cli --env dev agent list
cs-cli --env dev config get
cs-cli --env prod auth whoami
# 只退出 dev,prod 登录态仍可使用
cs-cli --env dev auth logout
  • 全局配置和凭据分别存入 ~/.cs-cli/environments/dev/ 与 ~/.cs-cli/environments/prod/。CS_CLI_HOME 只替换根目录;两个环境仍位于其 environments/ 子目录。凭据文件权限为 0600。
  • 登出、过期和 401 只清理发起请求的环境;未登录时提示带同一 --env 的登录命令。Dashboard 地址仍从该环境的客服 API 派生。
  • 未传 --env 继续读取原 config.json / credentials.json 和原 .cs-cli.json 字段。旧登录态不会自动归入 prod,也不会被 dev/prod 借用;开始使用显式环境后各登录一次。
  • 通用 CS_AUTH、CS_WORKSPACE_ID、CS_AGENT_ID、CS_CS_API_URL、CS_AI_API_URL、CS_CUSTOMER_AGENT_URL、CS_CS_ADMIN_URL 没有环境归属,非空时与显式 --env 混用会报错,且不发请求。sandbox / CI 继续不传 --env 使用原注入方式;多环境调用先清除这些变量并配置各自环境。
  • config get 返回当前 environment=dev|prod|legacy 及该环境的全局、本地配置。

Langfuse 通过 debug trace --langfuse-env dev|prod 单独选择;默认跟随全局 API 环境,未选 API 环境时默认 prod。旧的 debug trace <id> --env dev 仍只选择 Langfuse,API 环境保持原配置;若要同时选择 API 环境,必须把全局 --env 放在一级命令前。旧参数与 --langfuse-env 值冲突时拒绝执行。

cs-cli --env dev debug trace <trace_id>
cs-cli --env prod debug trace <trace_id> --langfuse-env dev

全局选项

| 选项 | 说明 | 默认值 | | ------------------ | ---------------- | ------- | | --table | 以表格形式输出(默认 JSON) | false | | --env <dev\|prod> | 本次 API 环境,独立配置与登录态 | 原配置(legacy) | | --workspace <id> | 覆盖默认工作空间 ID | 配置文件中的值 | | --request-timeout <ms> | 单个 HTTP 请求超时(毫秒);--timeout 是相关子命令的轮询窗口 | 60000 |

本地配置 (.cs-cli.json)

支持在项目目录下放置 .cs-cli.json 文件,为不同项目配置不同的工作空间。

工作空间优先级

| 优先级 | 来源 | 说明 | | --- | ----------------------- | ---------------------------- | | 0 | CS_WORKSPACE_ID 环境变量 | env lock,最高优先级,override 硬失败(见下方"环境变量锁定") | | 1 | --workspace <id> 参数 | 命令行临时覆盖 | | 2 | .cs-cli.json (本地配置) | 当前目录或祖先目录 | | 3 | ~/.cs-cli/config.json | 全局默认配置 |

使用方式

# 在项目目录下初始化本地配置
cs-cli config init

# 设置工作空间(自动写入本地 .cs-cli.json)
cs-cli config set-workspace <workspace_id>

# 强制写入全局配置
cs-cli config set-workspace <workspace_id> --global

CLI 从当前目录向上查找 .cs-cli.json,找到第一个即使用其中的 workspaceId。

显式 --env 只读取同一文件的 environments.dev 或 environments.prod;缺该项则使用该环境的全局默认工作空间,不借用旧顶层 workspaceId 或另一环境。本地与全局默认值在查询参数及 HTTP workspace header 中使用同一优先级。config set-workspace 写入所选环境,保留另一环境和旧字段。

.cs-cli.json 格式:

{
  "workspaceId": "ws-abc123",
  "workspaceName": "某客户项目"
}

同一目录保存两环境的格式:

{
  "environments": {
    "dev": { "workspaceId": "ws-dev", "workspaceName": "开发环境" },
    "prod": { "workspaceId": "ws-prod", "workspaceName": "线上环境" }
  }
}

set-workspace 写入规则

  • 当前目录或祖先目录存在 .cs-cli.json → 写入本地配置
  • 不存在 .cs-cli.json → 写入全局配置
  • 使用 --global → 强制写入全局配置

每次写入后会提示写入的目标路径。

环境变量锁定(sandbox / CI)

当 sandbox、CI 等非交互环境预先注入以下环境变量时,cs-cli 会透明地把 env 作为凭据与上下文来源,并拒绝任何运行时 override(--workspace / --agent / auth login 等),避免下游脚本在上下文被静默切换时产生未定义行为。

| 环境变量 | 作用 | | ----------------- | ------------------------- | | CS_AUTH | 登录凭据(等同 access token)。存在即视为"已锁定" | | CS_WORKSPACE_ID | 锁定工作空间 ID | | CS_AGENT_ID | 锁定默认 agent ID |

处理逻辑:

  1. env 优先:只要环境变量有值,cs-cli 就从 env 读取,忽略本地 credentials.json / .cs-cli.json / 全局配置。
  2. override 硬失败:锁定后如果再通过 --workspace / --agent / auth login / auth logout / config set-workspace 传入不一致的值,cs-cli 立刻报错退出,不会静默覆盖。
  3. 幂等传值:override 与 env 值完全一致时允许通过(便于脚本显式断言)。

使用示例:

export CS_AUTH="<your-access-token>"
export CS_WORKSPACE_ID="ws-abc123"
export CS_AGENT_ID="agent-xyz"

cs-cli agent list     # 直接运行,无需 auth login
cs-cli --workspace ws-other agent list   # ❌ 报错:CS_WORKSPACE_ID 已被锁定

要解除锁定,清空对应环境变量即可(unset CS_AUTH CS_WORKSPACE_ID CS_AGENT_ID)。

命令权限

客户与内部人员继续使用各自账号执行 auth login,共用登录体系。CLI 仅维护下表的 27 条内部受限命令,按当前账号的服务端 role_code 检查权限;未命中清单的命令不新增 CLI 角色校验,沿用原有登录与工作空间权限。

| CLI 权限 | 允许的角色 | 命令范围 | | --- | --- | --- | | 普通 | 不增加平台角色要求 | 商品、SA、FAQ、知识、会话、调试、看板等业务命令;包括 product feedback get/save/accept/restore/revoke/mode | | 内部普通 | DEVELOPER、ADMIN、SYSTEM_ADMIN | channel-metric query/backfill、monitor fields、monitor tickets list/delete、全部 ops-record 与 special-project 子命令、普通 key 的 system-config get | | 内部高级 | ADMIN、SYSTEM_ADMIN | agent fork | | 系统管理员 | SYSTEM_ADMIN | agent engine get/set、device list、token-usage summary、monitor agents/workspaces/statistics 与 monitor snapshots hourly/daily/daily-range |

system-config get 的以下四个 key 要求 SYSTEM_ADMIN:installer_package_api_keys、sop_main_engine_config、sop_main_engine_request_config、sop_main_engine_flow_service_config;其他 key 要求内部普通权限。SHOP_MANAGER、ASSISTANT 及未知角色不能执行内部命令。平台角色通过 CLI 检查后,服务端仍会执行原有业务和资源权限校验。

执行内部命令前,CLI 使用当前环境的登录凭据请求客服 API GET /v1/user/profile,不把角色写入凭据文件,也不跨进程缓存。角色无法确认或请求失败时,不执行目标业务命令;仅注入 CS_AUTH 而未设置 workspace 时,也能查询角色。auth、config、帮助和普通命令不增加此请求,auth whoami 仍返回原用户中心身份信息。

仅受限命令的 --help 增加权限标签。角色不足时输出 JSON 错误并以退出码 1 结束;未登录或 Token 失效为 2,网络或服务器错误为 3。本限制作用于本版 CLI;服务端接口与旧版 CLI 的行为未作调整。

本版移除了测试集与节点模板命令组,相关子命令不再注册;Sol 的 debug replay / debug overlay 流程保留。

命令速查表

认证 (auth)

| 命令 | 说明 | | ------------------------------------------ | -------- | | auth login --phone <手机号> --password <密码> | 登录 | | auth logout | 退出登录 | | auth whoami | 查看当前登录用户 |

配置 (config)

| 命令 | 说明 | | ----------------------------------------------------------- | ---------------------------- | | config set [--cs-api <url>] [--ai-api <url>] [--agent-api <url>] [--admin-api <url>] | 设置当前环境的 API 地址 | | config get | 查看当前配置(含全局和本地) | | config init | 在当前目录初始化本地配置 (.cs-cli.json) | | config set-workspace <workspace_id> [--global] | 设置默认工作空间 |

工作空间 (workspace)

| 命令 | 说明 | | --- | --- | | workspace list | 列出所有工作空间 | | workspace points-consumes-daily [--start <YYYY-MM-DD>] [--end <YYYY-MM-DD>] | 按天查询工作空间积分消耗(默认最近 30 天) |

workspace points-consumes-daily 需要可用的工作空间上下文(--workspace、本地 .cs-cli.json 或全局 defaultWorkspaceId)。

# 查询最近 30 天(默认)
cs-cli workspace points-consumes-daily

# 指定日期范围(含 start/end)
cs-cli workspace points-consumes-daily --start 2026-04-01 --end 2026-04-23

Agent 管理 (agent)

| 命令 | 说明 | | ---------------------------------------------- | ----------- | | agent list [--keyword <名称>] [--page N] [--page-size N] [--fields <路径,...>] [--raw] | 列出 Agent 列表;--keyword 按名称模糊搜索;--fields 裁每一条记录;--raw 不遮蔽凭据 | | agent get <config_id> [--fields <路径,...>] [--raw] | 获取 Agent 详情;--fields 只输出指定字段;--raw 不遮蔽凭据 | | agent update <config_id> --data <json|@file> | 更新 Agent 配置 | | agent fork --source-customer-config-id <id> --target-workspace-id <id> [选项] | 复制 Agent;CLI 要求内部高级权限(ADMIN 或 SYSTEM_ADMIN);同空间仍校验当前用户权限,跨空间服务端仍仅允许 SYSTEM_ADMIN | | agent engine get <config_id> | 查看 Agent 独立层引擎版本(顶层 + 设备定向;null 按 classic 跑),需超级管理员(SYSTEM_ADMIN) | | agent engine set <config_id> --to v2\|v3\|v4 [--device <设备ID>] / --device <设备ID> --clear | 切换引擎版本(写线上);不带 --device 为整体切换并清掉设备定向;返回切换前版本 |

agent list 每条都带完整 customer_config,单页可达数十万 token;只要 id 和名字时用 agent list --keyword <店名> --fields config_id,config_name。--fields 逗号分隔,点号取嵌套(如 customer_config.xxx),路径途经数组时作用到每个元素,不存在的路径直接省略,输出保持原嵌套结构;list 作用于 .data.items 每一条,分页字段保留;返回体没有 items 数组时往 stderr 打警告并对整个返回体裁剪。不带 --fields 时输出除凭据遮蔽外与之前相同。

agent get / agent list 默认按键名遮蔽凭据字段,值替换为 [REDACTED len=N]。规则比 debug trace 窄,只看键名、不扫正文:整键 token / session / authorization(仅字符串值)/ ak / sk / dsn / database_url,或键名(去掉 _、- 并转小写后)以 secret、password、passwd、access_token、refresh_token、api_token、auth_token、security_token、bearer_token、session_token、id_token、session_key、api_key、app_key、access_key、secret_key、private_key、cookie(s)、credential(s) 结尾;命中的数字值也遮(平台 appkey 常是纯数字),布尔、null、空串和空对象 / 数组不遮,值是 JSON 字符串时按同一规则处理其中的键。max_token、keep_session、need_authorization、cookie_rule、password_hint 这类键以及 prompt 正文里的 Cookie: 曲奇 不会被遮。agent update --data 里出现 [REDACTED len=N] 时会在调用接口前拒绝,所以带遮蔽占位的内容不能回传,只传要改的字段。确实需要真实值时加 --raw 关闭遮蔽:输出含明文凭据,不要贴进对话、日志或工单。

agent fork 必须显式指定来源 Agent 配置 ID 和目标工作空间 ID。--copy-product-data、--copy-activity-data 默认开启,可分别用 --no-copy-product-data / --no-copy-activity-data 关闭。--clone-tools 会复制来源 Agent 当前已绑定的全部工具(包括系统工具和自定义工作流工具),默认不复制;多数场景建议开启。--copy-authorized-shop-id 让克隆的工具沿用来源工具的店铺授权 authorized_shop_id,默认清空;仅与 --clone-tools 同用生效,只在用户明确要求全量复制工具时开启。--shop-id 可显式指定目标店铺 ID。

agent engine 读写的是 Agent 独立层的 version(v2=classic / v3=Luna / v4=Sol),这是 sop 收到的 extra.version 的唯一来源;判断引擎不要用 /effective 的合并结果。店铺还要在 sop_main_engine_config 的 internal 路由里(system-config get sop_main_engine_config),版本才会生效。

agent engine get/set、device list 和 token-usage summary 要求超级管理员(SYSTEM_ADMIN)账号。system-config get 按 key 区分权限,见下表;角色不足时应由具备相应权限的账号执行。

系统配置 / 设备(system-config / device)

| 命令 | 说明 | | --- | --- | | system-config get <key> | 读一条全局 system_config;普通 key 要求内部普通权限,四个敏感 key 要求 SYSTEM_ADMIN(见「命令权限」) | | device list [--workspace-id <id>] [--channel <渠道>] [--equipment-id <id>] [--page N] [--page-size N] | 需 SYSTEM_ADMIN;分页列出设备,返回的 version 是客户端版本,不是引擎版本 |

场景动作 (sa)

| 命令 | 说明 | | --- | --- | | sa list --agent <id> [--intent <意图>] [--first-label <标签>] [--second-label <标签>] | 列出场景动作 | | sa search --agent <id> --keyword <关键词> | 搜索场景动作 | | sa create --agent <id> --first-label <一级标签> --second-label <二级标签> --situation <场景> --action <动作> [--transfer] [--intent <意图>] | 创建场景动作 | | sa update --agent <id> --id <SA_ID> --first-label <一级标签> --second-label <二级标签> --situation <场景> --action <动作> [--transfer] | 更新场景动作 | | sa delete --agent <id> --id <SA_ID> --first-label <一级标签> --second-label <二级标签> | 删除场景动作 | | sa versions --agent <id> --id <SA_ID> | 查看修改记录 |

sa create/update 的场景必须从 --situation <文本> 与 --situation-file <路径> 中选一个,动作必须从 --action <文本> 与 --action-file <路径> 中选一个;两字段均必传,可混用文本与文件。文本参数含字面 \n 且没有真实 CR/LF 时会在调用 API 前拒绝,不会自动替换;有意写入字面 \n 请放入文件。--situation/--action @file 仍是普通文本,不读取文件。sa update 仍为全量更新,标签及转人工等字段需按备份回填。

# 本包目录,示例使用已配置的 dev;仅在确认范围与备份后执行
pnpm exec tsx src/bin.ts --env dev --workspace <workspace_id> sa update \
  --agent <agent_id> --id <SA_ID> --first-label <一级标签> --second-label <二级标签> \
  --situation-file ./situation.md --action-file ./action.md

工具 (tool)

| 命令 | 说明 | | --- | --- | | tool list --agent <id> | 列出该 Agent 配置已绑定的工具(custom + system) | | tool create --agent <id> --name <名称> --key <标识> --source-id <flow_id> [--description <描述>] [--source-type <类型>] [--invocation-mode <模式>] [--input-vars <json>] | 创建绑定工作流(flow)的自定义工具 | | tool update <tool_id> [--name <名称>] [--key <标识>] [--description <描述>] [--source-id <flow_id>] [--invocation-mode <模式>] [--input-vars <json>] | 更新工具(仅透传实际提供的字段) | | tool delete <tool_id> | 删除(软删除)指定工具 | | tool workflow list [--keyword <关键词>] | 搜索可绑定的工作流(flow),取 source_id | | tool workflow detail <flow_id> | 查看工作流入参,辅助填 --input-vars | | tool workflow create --name <名称> --code <code\|@file> [--description <描述>] [--input-vars <json\|@file>] [--no-publish] [--code-node-name <名称>] [--version-desc <描述>] | 创建 START→CODE→END 骨架工作流,CODE 节点承载工具代码(仅 JavaScript),默认自动发布 | | tool workflow update <flow_id> --code <code\|@file> [--no-publish] [--version-desc <描述>] | 只更新工作流唯一 CODE 节点的代码(其它节点原样保留),默认自动发布 | | tool workflow run <flow_id> [--input <json\|@file>] | 运行已发布的工作流(HTTP 同步执行),返回 task_id / status / run_result | | tool workflow delete <flow_id> --yes | 硬删除工作流(不可恢复);缺 --yes 拒绝执行 | | tool workflow describe | 输出 CODE 节点(JavaScript)使用文档:入口/变量注入/返回值/内置包/SDK,依据官方文档整理 |

tool 命令组包装 customer-servhub-api 现有 /v1/tool 接口,管理 Agent 的自定义/覆盖工具;CLI 不改变服务端工具表或 sop-engine 的工具执行逻辑。--invocation-mode 取值 must_invoke / on_demand(默认)/ on_demand_async,非法值在发请求前本地报错;tool create --input-vars 接受 JSON 字符串,形如 {"order_id":{"description":"订单号","type":"string","required":true}},对应工作流入参描述;workspace_id 由当前工作空间自动回填。

tool workflow create/update/run/delete 直连 BetterYeah 平台(ai-api)程序化管理工作流本体:create 生成固定 START→CODE→END 三节点骨架并把代码写进 CODE 节点、默认发布,返回 flow_id 供 tool create --source-id 绑定;update 只暴露 CODE 节点代码的修改;run 是 HTTP 同步执行(自动经 GET /v1/workspaces/getKey/{ws} 用登录态换应用态 Access-Key 再调 execute_flow,替代平台画布的 wss 通道),--input 的键对应 START formConfig 的 variableName(默认 {});delete 是硬删除、必须显式 --yes。create/update 发布时可用 --version-desc 附版本描述(平台版本历史里可见,便于区分 CLI 改动;--no-publish 时忽略)。CODE 节点只支持 JavaScript(CommonJS require,不支持 ES Module)。--code / --input-vars 的值以 @ 开头时按文件路径读取(如 @./tool.js)。注意 tool workflow create --input-vars 覆盖的是 START 节点的 formConfig 入参声明,与 tool create --input-vars(工具记录的 input_var_descriptions)是不同字段。tool workflow describe 输出依据官方 JavaScript&Python 节点文档整理的 CODE 节点使用文档(入口 main()、变量注入、返回值约定、内置包、BetterYeah SDK),AI 编写工具代码前应先读。

商品管理 (product)

| 命令 | 说明 | | --- | --- | | product list --agent <id> [--keyword <关键词>] [--status <状态>] [--tag <标签>] | 列出商品 | | product get --agent <id> --product-id <商品ID> | 获取商品详情(自动获取 db_id) | | product update --agent <id> --product-id <商品ID> --update <json\|@file> | 更新商品信息 | | product shelf --agent <id> --status <上架\|下架\|预售> (--ids <id,id> \| --ids-file <path>) [--concurrency <n>] [--yes] | 批量设置商品状态(上架 / 下架 / 预售,写「商品状态」列,写后回读校验) | | product update-sku --agent <id> (--sku <SKU名称> \| --sku-id <id>) --update <json\|@file> | 更新 SKU 信息(--sku-id 优先于 --sku) | | product add --agent <id> --data <json\|@file> [--source <type>] [--no-identify] | 直接传入结构化商品数据(JSON 数组)异步学习(manual / identify 默认开启) | | product learn --agent <id> --url <URL...> [--source <type>] [--no-identify] | 通过商品 URL 异步学习(manual / identify 默认开启) | | product identify-all --agent <id> | 一键增强学习当前 Agent 下所有待增强商品 | | product sync-taobao --agent <id> [--skip-hash-check] [--sync-type <full\|incremental>] | 触发淘宝店铺商品同步 | | product sync-taobao-item --agent <id> --product-id <商品ID> | 触发单个淘宝商品同步 | | product related-knowledge list --agent <id> --product-id <商品ID> | 列出商品详情绑定的 QA / 扩展知识库文件 | | product related-knowledge add --agent <id> --product-id <商品ID> --type <qa\|common> (--file <文件名> \| --file-id <id> --partition-id <id>) | 给商品追加关联知识库文件 | | product related-knowledge remove --agent <id> --product-id <商品ID> --type <qa\|common> --file-id <id> | 移除商品绑定的指定知识库文件 | | product related-knowledge set --agent <id> --product-id <商品ID> --bindings <json\|@file> | 覆盖商品绑定的全部知识库文件 | | product supplement list --agent <id> --product-id <商品ID> | 列出商品补充知识条目(含每条的 question / answer / images / videos) | | product supplement add --agent <id> --product-id <商品ID> --question <Q> --answer <A> [--image <path\|url>...] [--video <path\|url>...] [--dry-run] [--backup <path>] | 新增一条补充知识(Q/A + 可选图片/视频);本地媒体自动上传公开 OSS,URL 直写;read-modify-write 保留旧条目 | | product supplement append-media --agent <id> --product-id <商品ID> --index <n> [--image ...] [--video ...] [--dry-run] [--backup <path>] | 向指定下标条目追加图片/视频,其它条目原样保留、去重合并 |

product update 支持更新的字段包括:卖点、补充知识、tag、参数、轮播图识别结果、商品详情页识别结果 等。--update 接受 JSON 字符串或 @文件路径。

product add 与 product learn 走同一个上传接口(/v1/knowledge/products/upload),区别在于载荷:add 传结构化商品数据 product_items(已抓好的商品详情 JSON 数组),learn 传 product_urls(让后端去抓)。--data 接受 JSON 字符串或 @文件路径;传单个对象会自动包成数组,传 JSON 基本类型(数字 / 字符串等)会直接报错;--source 默认 manual,--no-identify 关闭自动识别。

product learn 提交商品详情页 URL 进入异步学习队列(/v1/knowledge/products/upload),返回 flow_id 和 knowledge_ids。--url 可多值,用空格分隔;--source 默认 manual;传 --no-identify 可关闭自动识别。

product identify-all 对接 POST /v1/knowledge/products/identify/all,会为当前 Agent 一键提交所有“已可用但尚未增强”的商品进入增强学习队列。它不是全量重学;当没有待增强商品时,服务端会返回“暂无需要识图的商品”。

product sync-taobao / product sync-taobao-item 调用 customer-servhub-api 的授权店铺同步接口,要求 --agent 已唯一绑定一个淘宝授权店铺。前者支持 --sync-type full|incremental,默认 full;后者按 product_id 补同步单个淘宝商品。

注意:这两个命令仅对已开通“高级工具”的店铺 Agent 生效。未开通高级工具时,即使 --agent 已绑定淘宝授权店铺,请求也可能在服务端失败。

product related-knowledge 管理商品详情的“关联知识库”文件级绑定。--type qa 对应 FAQ 知识库,--type common 对应扩展知识库。add / remove 会先读取当前绑定,再通过服务端全量替换接口写回;重复添加或移除不存在的文件保持幂等。--file <文件名> 会按当前 Agent 的知识库文件列表做精确匹配;文件名不存在或不唯一时,改用 --file-id + --partition-id 显式模式。

product supplement 维护商品「补充知识」的带图/视频问答(结构为 { question, answer, images: [URL], videos: [URL] }),与前端商品详情页的补充知识上传一致。写入采用 read-modify-write:先 product get 读取并解析当前补充知识,本地合并后再调既有 /v1/knowledge/product/update,绝不用新增项覆盖旧条目。--image / --video 可重复传多个,值可以是本地文件(先经 /v1/upload_sts 取 STS 凭证上传公开 OSS,key 为 /ai/knowledge/supplement/${timestamp}_${filename})或已有 http(s) URL(直写不重复上传)。图片限 image/* ≤ 10MB、视频限 video/* ≤ 200MB,超限或类型不符在发起上传请求前直接失败。--dry-run 只输出将写入的最终 JSON、不落库、不上传;--backup <path> 在写前把当前补充知识快照到本地文件。append-media 仅向 --index 指定的条目追加媒体,去重合并,其它条目原样保留。

单文件上传也可单独用 media upload(见下方「媒体上传」小节),拿到公网 URL 后再作为 --image / --video 的值传入。

# 更新卖点
cs-cli product update --agent <id> --product-id <商品ID> --update '{"卖点":"新卖点内容"}'

# 更新标签
cs-cli product update --agent <id> --product-id <商品ID> --update '{"tag":"[\"春季新品\",\"热卖\"]"}'

# 添加商品补充知识
cs-cli product update --agent <id> --product-id <商品ID> --update '{"补充知识":"[{\"question\":\"问题\",\"answer\":\"回答\"}]"}'

# 更新 SKU 补充知识(按 SKU 名称定位)
cs-cli product update-sku --agent <id> --sku "颜色分类:粉红" --update '{"补充知识":"说明内容"}'

# 更新 SKU 补充知识(按 sku_id 定位,推荐)
cs-cli product update-sku --agent <id> --sku-id 6072595054179 --update '{"补充知识":"说明内容"}'

# 给商品绑定一个 FAQ 文件
cs-cli product related-knowledge add --agent <id> --product-id <商品ID> --type qa --file "常见问题.xlsx"

# 显式 ID 模式绑定扩展知识文件
cs-cli product related-knowledge add --agent <id> --product-id <商品ID> --type common --file-id 622474 --partition-id 12345 --file-name "售后规则.md"

# 查看商品当前补充知识条目
cs-cli product supplement list --agent <id> --product-id <商品ID>

# 新增一条带图问答(本地图片自动上传,已有 URL 直写)
cs-cli product supplement add --agent <id> --product-id <商品ID> \
  --question "尺码怎么选?" --answer "参考尺码表,拍下留言身高体重" \
  --image ./size-chart.png --image https://xxx.com/a.png

# 先 dry-run 预览最终写入 JSON,不落库
cs-cli product supplement add --agent <id> --product-id <商品ID> \
  --question "Q" --answer "A" --video ./demo.mp4 --dry-run

# 向第 0 条补充知识追加媒体,写前备份
cs-cli product supplement append-media --agent <id> --product-id <商品ID> \
  --index 0 --image ./extra.png --backup ./supplement-backup.json

媒体上传 (media)

| 命令 | 说明 | | --- | --- | | media upload --file <path> [--type <image\|video>] [--path-prefix <prefix>] [--dry-run] | 上传单个本地图片/视频到公开 OSS,返回可访问 URL |

media upload 把单个本地文件上传到公开 OSS(resource_bucket),返回公网 URL,供 product supplement 的 --image / --video 复用。凭证走 GET /v1/upload_sts(返回 AES-CBC 加密,CLI 内解密),上传 key 为 <path-prefix>/<timestamp>_<filename>,--path-prefix 默认 /ai/knowledge/supplement。--type 缺省时按扩展名推断;图片限 image/* ≤ 10MB、视频限 video/* ≤ 200MB,超限/类型不符在发起上传前直接拒绝。传入的 --file 如果本身是 http(s) URL 会被拒绝(无需上传)。--dry-run 仅校验并输出将要上传的信息、不实际上传。

# 上传本地图片,拿到公网 URL
cs-cli media upload --file ./banner.png --type image

# 自定义路径前缀 + 预览(不实际上传)
cs-cli media upload --file ./demo.mp4 --path-prefix /ai/knowledge/supplement --dry-run

活动管理 (activity)

活动 V2(Issue #34)增删改查 + per-tenant V2 总开关。服务端 customer-servhub-api /v1/activity*;契约详情参见 docs/devkit/specs/2026-05-28-activity-v2-api-reference.md。

| 命令 | 说明 | | --- | --- | | activity list --agent <id> [--page N] [--page-size N] [--search <text>] | 列出活动(返回 total / v2_activity_enabled / items[]) | | activity by-product --agent <id> --product-id <id> | 按 product_id 反查当前生效活动(仅 enabled、product_scope='all' 必入) | | activity create --data <json\|@file> | 创建活动(payload 见 IActivityWritePayload) | | activity update <activity_id> --data <json\|@file> | 整体更新活动(products 整组替换,非增量) | | activity set-enabled <activity_id> --enabled <true\|false> | 切换单条活动启用状态(仅写 enabled) | | activity delete <activity_id> | 软删活动 + 级联软删关联 | | activity v2-enabled --agent <id> --enabled <true\|false> | per-tenant 启停 V2 链路 |

  • --agent <id> 对应服务端 customer_agent_config_id(与 sa / product 命令同口径)。
  • activity create / update payload 必填:customer_agent_config_id、activity_name、effective_type、activity_rule;effective_type=time_range 要求 start_time + end_time;product_scope='specific'(缺省)要求 products ≥ 1。
  • 业务失败(参数非法 / 跨 workspace / 不存在)服务端返 HTTP 200 + code:400,CLI 转为 exit 1 并打印 INVALID_PAYLOAD: …。
# 列出活动
cs-cli activity list --agent <cfg_id> --search 返现

# 按商品反查
cs-cli activity by-product --agent <cfg_id> --product-id 914494989518

# 创建活动(从文件读 payload)
cs-cli activity create --data @activity.json

# 整体更新
cs-cli activity update 6 --data @activity.json

# 列表行 toggle 启用
cs-cli activity set-enabled 6 --enabled false

# 软删活动
cs-cli activity delete 6

# 为某 agent 启用 V2 链路
cs-cli activity v2-enabled --agent <cfg_id> --enabled true

工单管理 (issue)

| 命令 | 说明 | | ------------------------------------------------------------------------------------------ | ------ | | issue list [--agent <id>] [--status <状态>] [--priority <优先级>] [--start <日期>] [--end <日期>] | 列出工单 | | issue get <issue_id> | 获取工单详情 | | issue create --title <标题> --content <内容> [--priority <优先级>] [--tags <标签>] | 单条创建工单 | | issue create --file <path> \| --stdin [--dry-run] [--concurrency <n>] [--yes] | 批量创建工单(JSON 协议见下) | | issue update <issue_id> --data <json|@file> | 单条更新工单 | | issue update --ids <a,b,c> \| --ids-file <path> --data <json|@file> [--dry-run] [--concurrency <n>] [--yes] | 批量更新工单字段(串行 PATCH) | | issue update-owner <issue_id> --owner <user_id\|花名> | 单条改派负责人(花名自动解析) | | issue update-owner --ids <a,b,c> \| --ids-file <path> --owner <user_id\|花名> [--dry-run] [--yes] | 批量改派负责人(走 cs-admin BFF,原子改派 + 自动 Feishu/DingTalk 通知,单批 ≤ 200) | | issue stats [--start <日期>] [--end <日期>] | 各工作空间 Issue 统计(open/closed/total) | | issue comment list <issue_id> | 列出工单评论 | | issue comment add <issue_id> --content <内容> | 添加评论 |

批量写约定(update / update-owner / create --file)

  • --ids "a,b,c" 与 --ids-file path.txt(一行一个 id,# 注释、空行忽略)互斥;与单条 <issue_id> 互斥。
  • --owner 同时接受 user_id(≤ 7 位纯数字)和工程师花名。花名经 cs-admin /api/account-roles 解析(KA + SMB 合并去重,5 分钟内存 cache),同名 / 模糊歧义会报错列 candidates。--owner 拒绝 11 位手机号(Issue #49,老 --owner-phone 0.5.0 起硬删)。
  • --dry-run 在所有批量子命令上都不会调写接口;create --file --dry-run 会真跑 user_name → conversation_id 反查,以便提前发现 NOT_FOUND / AMBIGUOUS。
  • N ≥ 20 且 stdout 是 TTY 时弹二次确认(输入 yes);非 TTY 必须显式 --yes,否则拒收。
  • 末尾报告统一 schema:{version:"1", total, success_count, failed_count, skipped_count, aborted, success_ids[], failed[{id,code,msg}], skipped[{id,reason}]}。退出码:0 全成功 / 1 全失败 / 2 部分失败 / 130 SIGINT。
  • update-owner --ids 走 cs-admin BFF POST /api/workbench/issues/batch-owner 单次调用(原子),返回 {updated, skipped:[{issueId, reason}], notify[]},与 update 的 runBatch 报告 schema 不同(保留 BFF 原样)。
  • 双后端单 token:servhub Bearer JWT 同时通过 cs-admin BFF 鉴权(实测验证),无需额外登录。

issue create --file JSON 协议

文件解析交给上游(LLM/Agent/脚本)整理成下面这份结构化 JSON,CLI 只做校验 + 反查 + 拼装 + 批量创建。

{
  "version": "1",
  "workspace_id": "ws_xxx",          // 顶层,对所有 issue 生效;缺省时落到默认 workspace
  "issues": [
    {
      "title": "客户反馈:A 问题答非所问",   // 必填
      "priority": "high",              // 必填,critical|high|medium|low
      "expected": "应该回答 X",          // 必填,CLI 把它写进 content 的 ## Expected 段
      "description": "上下文描述",       // 可选,拼在 expected 前面
      "conversation_id": "conv_xxx",   // 与 user_name 二选一
      "user_name": "张三",              // 仅给昵称时,CLI 调 /v1/chat/conversations?user_name= 反查
      "tags": ["badcase"],             // 可选
      "source_type": "manual_review",  // 可选
      "source_data": {"reviewer": "..."} // 可选
    }
  ]
}

CLI 把 description + expected 拼成 content:

{description}(如有)

## Expected
{expected}

user_name 反查规则(5 分钟内存 cache,key = ${workspaceId}|${userName}):

  • 1 条命中 → 用其 conversation_id
  • 0 条 → 该 issue 标记 NOT_FOUND,整批拒收(防止半批进创建)
  • 多条 → 该 issue 标记 AMBIGUOUS,提示改传显式 conversation_id

priority 不在枚举内、title/expected 缺失等 → 客户端直接拒收(不打任何接口)。

聊天记录 (chat-history)

查询客户导入的聊天记录,用于 SA(场景动作)清洗,非 Agent 自身的对话记录。

| 命令 | 说明 | | ------------------------------------------------------ | --------------- | | chat-history --agent <id> [--page N] [--page-size N] | 查询客户导入的聊天记录 |

FAQ 知识库 (faq)

| 命令 | 说明 | | ---------------------------------------------------------------------------- | --------- | | faq list --agent <id> | 列出 FAQ 文件 | | faq content --agent <id> --file <文件名> [--keyword <词>] [--page-size <n>] [--next-group-id <id>] | 列出文件内答案组(含 answer_group_id / 问题 / 答案) | | faq add --agent <id> --file <文件名> --questions <问题1,问题2> --answers <答案=xxx> | 添加 FAQ 内容 | | faq update --agent <id> --file <文件名> --group-id <id> [--questions <...>] [--answers <...>] [--delete-chunks <id1,id2>] | 更新已有 FAQ 答案组(--questions / --answers / --delete-chunks 至少一个) | | faq delete --agent <id> --file <文件名> --group-id <id> | 删除 FAQ 答案组 | | faq bind-products list --agent <id> (--file <文件名> \| --file-id <id> --partition-id <id>) | 列出 FAQ 文件绑定的商品 | | faq bind-products add --agent <id> (--file <文件名> \| --file-id <id> --partition-id <id>) --product-id <商品ID...> | 给 FAQ 文件追加绑定商品 | | faq bind-products remove --agent <id> (--file <文件名> \| --file-id <id> --partition-id <id>) --product-id <商品ID...> | 从 FAQ 文件移除绑定商品 | | faq bind-products set --agent <id> (--file <文件名> \| --file-id <id> --partition-id <id>) --product-id <商品ID...> | 覆盖 FAQ 文件绑定的全部商品 |

faq content 走 GET /mebsuta/api/v1/dataset/{knowledge_id}/faq_contents,列出文件内的答案组及其 answer_group_id,是 faq update / faq delete 拿 --group-id 的来源(faq list 只给文件,文件内的 group-id 要靠这条命令查)。支持 --keyword 搜索、--page-size 分页、--next-group-id 游标续翻。

faq update 按 answer_group_id 定位目标组,先读回这组的现值,只覆盖显式传入的字段,再 POST 同一个 faq_contents/save 接口完成字段替换、问题替换与 chunk 级删除。--questions 整组替换问法,没列出的原问法会被删掉。读不到现值、合并后没有问题或没有非空答案时拒绝保存。faq delete 走 DELETE /faq_contents/{group_id} 整组删除。

faq bind-products 固定写入 knowledge_type=qa 的商品绑定关系,适合从 FAQ 文件视角批量维护关联商品。--file 为精确文件名匹配;文件名不唯一时请传 --file-id 和 --partition-id。

扩展知识库 (knowledge)

Agent 关联的通用规则知识库(suffix_type=_common),与 FAQ / 商品知识并列的第三类知识源,支持段落(chunk)级 CRUD,统一走 /mebsuta/api/v1/dataset/{id}/contents/perform-operations。

| 命令 | 说明 | | --- | --- | | knowledge list --agent <id> [--page N] [--page-size N] | 列出 Agent 关联的扩展知识库文件 | | knowledge content list --knowledge-id <id> [--page-size N] [--direction up\|down] | 列出段落(chunk) | | knowledge content add --knowledge-id <id> --content <text\|@file> [--keyword <k...>] [--after <chunk_id>] | 新增段落 | | knowledge content update --knowledge-id <id> --chunk-id <id> [--content <text\|@file>] [--keyword <k...>] [--enable \| --disable] | 更新段落(四个变更字段至少一个;未指定 --enable / --disable 时自动保留当前启停状态,避免后端 enable 必填校验失败) | | knowledge content delete --knowledge-id <id> --chunk-id <id> | 删除段落 | | knowledge bind-products list --agent <id> (--file <文件名> \| --file-id <id> --partition-id <id>) | 列出扩展知识文件绑定的商品 | | knowledge bind-products add --agent <id> (--file <文件名> \| --file-id <id> --partition-id <id>) --product-id <商品ID...> | 给扩展知识文件追加绑定商品 | | knowledge bind-products remove --agent <id> (--file <文件名> \| --file-id <id> --partition-id <id>) --product-id <商品ID...> | 从扩展知识文件移除绑定商品 | | knowledge bind-products set --agent <id> (--file <文件名> \| --file-id <id> --partition-id <id>) --product-id <商品ID...> | 覆盖扩展知识文件绑定的全部商品 |

knowledge content add / update 的 --content 支持 @路径 前缀从文件读取纯文本(不是 JSON)。--keyword 为 variadic 选项,空格分隔多个关键词。

knowledge bind-products 固定写入 knowledge_type=common 的商品绑定关系,适合从扩展知识文件视角批量维护关联商品。add / remove 会 read-modify-replace,重复添加或移除不存在的商品保持幂等。

会话管理 (conversation)

| 命令 | 说明 | | -------------------------------------------------------------------------------- | -------- | | conversation list [--agent <id>] [--equipment-id <设备ID>] [--user <用户名>] [--start <日期>] [--end <日期>] [--query-content <文本>] | 搜索会话;--start/--end 按会话 updated_at 过滤(按时段算转人工率用 transfer-human);--query-content 按消息内容搜索,必须同时给起止时间 | | conversation records <conversation_id> [--page-size N] [--direction prev|next] [--current-id <id> \| --all] | 获取会话聊天记录;--current-id 是记录的数字 id 游标(不是 record_id),只能往前翻;--all 沿 prev 翻完整个会话并按时间升序返回 | | conversation context-search (--query <文本> \| --user <用户名>) [--limit <1~500>] [--start <时间>] [--end <时间>] | 通过上下文内容或买家用户名模糊搜索对话记录(返回匹配消息详情,时间范围最多 3 天) | | conversation find-order <订单号> --agent <id> --start <时间> --end <时间> | 按订单号反查会话与 record_id;超过 3 天自动按 3 天分段顺序查询,总跨度最多 31 天 | | conversation transfer-human --agent <customer_agent_config_id> --start <时间> --end <时间> [--only-abnormal] | 查询转人工会话及对应转人工消息记录(时间范围最多 7 天,自动 cursor 翻页;--only-abnormal 仅保留异常会话) |

Agent 调试 (debug)

| 命令 | 说明 | | ----------------------------------------------------------------------------------------------------------- | -------------------- | | debug ask --agent <id> (--text <消息> \| --messages <json\|@file>) [--user <用户名>] [--url <图片URL>] [--conversation <会话ID>] [--mock <json\|@file>] [--data-overlay <json\|@file>] [--timeout <秒>] [--poll-interval <毫秒>] | 向 Agent 发送消息并等待回复 | | debug reproduce <record_id> [--agent <id>] [--mock <json\|@file>] [--data-overlay <json\|@file>] [--timeout <秒>] [--poll-interval <毫秒>] [--dry-run] | 根据 record_id 复现 Agent 回复(自动获取上下文) | | debug data snapshot --agent <id> [--product-id <商品ID...>] | 生成可传给 --data-overlay @file 的 debug 数据覆盖 JSON | | debug record <record_id...> [--out <file.ndjson>] | 获取记录的调试信息(flow_info);多个 id 时最多 3 路并发,--out 按 NDJSON 每行一条写盘(附 engine / flow_engine),stdout 只给汇总;返回中包含 trace_id;Sol 引擎有存档时另有 sol_trace_id 与 sol_trace(服务端 view=diagnosis 的原样结果) | | debug trace <trace_id> [--langfuse-env <dev\|prod>] | 根据 Langfuse Trace ID 获取完整 Trace 详情(经所选环境的服务端代理);Sol 轮次另附 sol_trace(服务端 view=diagnosis) | | debug trace (<st-…> \| --record <record_id>) [--view summary\|prompt\|lean\|full\|otel] [--call <node>] [--out <file>] | Sol 引擎单轮完整 prompt 存档(服务端展开并逐字节校验);默认摘要 | | debug trace --date <YYYY-MM-DD> [--agent <id>] [--out <dir> [--label <l>]... [--node <n>]... [--limit <n>]] | 某天 Sol 存档按 workspace + agent 合并好的调用文件:列条数 / 下载并筛选 | | debug replay export (--trace <id...> \| --record <id...>) --out <case.json> | 导出同一会话的 Sol 轮次上下文及商品快照 | | debug replay open --case <case.json> [--mode rollout\|original] [--products <snapshot.json>] --out <run.json> | 初始化本地运行文件,默认沿用 dev 状态逐轮执行 | | debug replay next --run <run.json> | 执行下一轮并保存完整结果与状态 | | debug replay run --run <run.json> [--until <N>] | 从保存的进度继续,逐轮落盘 | | debug replay fork --run <run.json> --at <N> [--products <snapshot.json>] --out <new-run.json> | 保留前 N 轮与对应状态,在新文件继续验证 | | debug replay inspect --run <run.json> [--turn <index>] [--view <view> \| --path <pointer>] [--offset <N>] [--limit <N>] [--out <file>] | 只读本地摘要/卡片/工具/原文,按需取证 | | debug replay compare --baseline <run.json> --candidate <run-b.json> [--expect <expected.json>] [--ab] [--out <file>] | 同输入字段差异与显式断言,区分执行和验证;两边 case.overlay hash 不同时默认拒绝,--ab 声明为配置 A/B | | debug overlay init (--case <case.json> \| --agent <id>) --out <dir> [--base current\|incident] [--turn <N>] | 只读:把回放基线拉成可编辑的覆盖目录 | | debug overlay build [--case <case.json>] --overlay <dir> --out <file> [--format sol\|v1] | 离线:把覆盖目录合并进 case 的 overlay 段(classic 输出 debug_data_overlay v1) |

debug ask 会自动创建调试会话、发送消息、轮询等待 Agent 回复,默认最大等待 30 秒,默认轮询间隔 2000ms。--text 与 --messages 二选一:--text 发送单条消息,--url 只在 --text 模式下作为附图 URL;--messages 传入完整消息列表(JSON 或 @文件)重放多轮对话,既接受 JSON 数组,也接受 conversation records 原始 { "msg_list": [...] } 对象。--conversation 可复用已有 debug 会话继续对话;--mock 可传工具结果 mock;--data-overlay 可传 debug_data_overlay JSON 或 @文件。

debug reproduce 根据一条回复记录自动复现 Agent 回复:通过 recordId 获取关联会话和 Agent 配置,拉取完整会话记录并截取目标 record 之前的上下文,使用原始用户名创建新 debug 会话并发送。默认最大等待 60 秒,默认轮询间隔 2000ms。--agent 可指定另一个 Agent 复现同一段上下文(A/B 对比);--mock 和 --data-overlay 会在复现发送时透传;--dry-run 仅输出截断后的 msg_list、mock 和 overlay,不发送。

debug data snapshot 生成 debug_data_overlay v1 JSON,适合把当前 Agent 的 SOP / 商品 / 活动等数据固定成一次 debug 覆盖输入,再通过 debug ask --data-overlay @file 或 debug reproduce --data-overlay @file 复跑。--agent <id> 必填;--product-id <商品ID...> 可重复传多个商品 ID,只导出指定商品,不传则分页导出全量商品。命令输出写到 stdout,通常重定向到文件保存。

# 只导出指定商品相关 overlay
cs-cli debug data snapshot --agent <id> --product-id 586812046546 > overlay.json

# 使用 overlay 跑一次 ask
cs-cli debug ask --agent <id> --text "https://item.taobao.com/item.htm?id=586812046546 这个商品名称是啥" --data-overlay @overlay.json

Sol 逐轮回放:先用生产环境的 CLI 配置运行 replay export,按轮次顺序传入同一会话的 1 到 50 个 sol_trace_id 或回复 record_id。导出依赖存档中的轮前状态、客户资产和商品数据;缺少可执行上下文的历史存档会由服务端明确报错。导出包顶层附 export_report(sol-replay-export-report/v1),逐轮标出回放会不会停:blocked 表示严格与 lenient 都会停,warn 表示严格会停、lenient 可继续(含跳过轮);有 warn/blocked 时 export 在 stderr 打印逐轮摘要(轮号、状态、规则码),stdout 与退出码不变。授权了推荐工具却没捕获 recommend_route 的轮由导出自动补(先借同包邻轮,借不到补空路由),来源记入 export_report.recommend_route_filled,不用再手工补。replay open 只生成本地 run.json,内嵌完整 case;消息卡片、未知字段与原时间戳均原样保存。

执行 next / run 时使用当前 CLI 环境的客服 API 和登录态;服务端仅在 dev 开放执行。预先按上面的多环境步骤分别配置并登录,生产导出使用 --env prod,执行使用 --env dev。rollout(默认)沿用 dev 每轮产生的状态,适合改了商品选择逻辑后验证后续轮次;original 每轮恢复对应线上状态,适合独立对照。

# dev 与 prod 已分别配置 API、工作空间并登录
cs-cli --env prod debug replay export --record <第一轮回复ID> <第二轮回复ID> --out case.json
cs-cli debug replay open --case case.json --out run.json
cs-cli --env dev --request-timeout 180000 debug replay next --run run.json
cs-cli --env dev debug replay run --run run.json --until 2

# 保留完成的第一轮,从其 dev 状态继续新分支;--at 0 从初始上下文开始
cs-cli debug replay fork --run run.json --at 1 --out run-b.json
cs-cli --env dev debug replay run --run run-b.json

# 新逻辑会查询 B:补入包含 B 的原始商品数据,再从同一个 checkpoint 分叉
cs-cli debug replay fork --run run.json --at 1 --products products-B.json --out run-products-B.json
cs-cli --env dev debug replay next --run run-products-B.json

open / fork --products snapshot.json 把原始商品数据对象固定到 case.products,显式作为所有后续轮次的数据源;商品 ID/SKU 查询和卡片生成仍由真实 Sol 代码执行。其余消息、客户身份、前 N 轮与 checkpoint 保持原样。快照应覆盖改动后会查到的商品及所需 SKU、库存、摘要;缺范围由服务端报错,不自动补空结果。不传 --products 则使用各轮自己的录制数据,库存等时点数据不会跨轮自动合并。

--until N 表示执行到完成 N 轮,包含第 N 轮;不传则跑完。每轮用独立 request_id 关联同步终态,并原子保存结果及 checkpoint。failed / skipped 也作为该轮结果保存;HTTP 错误或返回关联不符时保留上一个已完成 checkpoint,再次执行即可从该处恢复。export / open / fork 不覆盖已有文件。运行文件使用同目录 .lock 防止并发推进;进程异常退出后,确认没有回放进程才可删除残留锁。文件包含客户上下文,默认权限为 0600。

供 AI 执行的输出与取证:next/run 默认仅返回进度、最后一轮 response_status、回复预览、焦点商品及卡片/工具/告警数量。execution_status=completed 表示命令完成,verification_status=not_evaluated 表示尚未判断业务预期;即使本轮 Sol 是 failed/skipped,仍完整存档并在摘要中明确显示。完整 response、trace、checkpoint 保存在 saved_to 指向的 run 文件。

inspect 只读本地文件,不需要联网或登录。--turn 使用从 0 开始的索引;不传则分页读取已完成轮次摘要。视图为 summary|response|cards|tools|trace|checkpoint|request|raw;cards 读取 checkpoint 中的 tool_result 事实载荷(包含沿用的历史事实),没有记录时提供 run_record 卡片摘要;原始业务载荷可取 /response/llm_payload。tools 来自 trace 的工具执行。--path 从本轮完整结果按 JSON Pointer 取字段(覆盖 view),支持 /→~1、~→~0 转义。未执行轮次可查 request。数组默认 10 项,--offset/--limit 分页,返回 total/next_offset;超过 12,000 bytes 的视图仅给标记截断的预览,可缩小路径或 --out 完整保存所选视图/数组页,未知字段不改写。

cs-cli debug replay inspect --run run.json
cs-cli debug replay inspect --run run.json --turn 0 --view cards --limit 5
cs-cli debug replay inspect --run run.json --turn 0 --view tools
cs-cli debug replay inspect --run run.json --turn 0 --path /checkpoint/head/focus_skus
cs-cli debug replay inspect --run run.json --turn 0 --view trace --out turn-0-trace.json
cs-cli debug replay compare --baseline run.json --candidate run-b.json --out comparison.json
cs-cli debug replay compare --baseline run.json --candidate run-b.json --expect expected.json --out verified.json

compare 要求 source、mode、逐轮 trace ID 和 request 相同,允许显式更换数据。比较共同已执行前缀的状态、回复、转人工、标签、事实卡及载荷、工具有效参数/结果、焦点商品/订单/SKU/场景;忽略卡片抓取时刻与工具耗时。case_equal/data_equal 和两份运行摘要用于标明输入包及数据是否一致;完成长度不同则 comparison_status=incomplete。默认只报差异位置和数量,完整 before/after 与断言证据可用 --out 保存,或通过 inspect 按位置读取。无 --expect 一律 not_evaluated,不把“无差异”判作“正确”。

预期文件只支持显式逐轮字段相等判断,不执行代码或自动语义评分:

{"schema":"sol-replay-expect/v1","assertions":[
  {"turn_index":0,"path":"/checkpoint/head/focus_product_ids","equals":["B"]},
  {"turn_index":1,"path":"/checkpoint/head/focus_product_ids","equals":["B"]}
]}

全部声明断言满足才是 verification_status=passed;不相等或字段不存在为 failed,所需轮次尚未执行为 incomplete。这里的通过仅覆盖声明的断言,可用于验证 A→B 以及下一轮继续 B;回复质量仍需业务标准。比较命令成功时外层 success=true;断言失败/未完成额外设置退出码 1。无预期的差异报告和断言通过退出码为 0。

缺数 HTTP/业务 422 会在 CLI error 中保留受控的 reason/retryable/missing/next_action/truncated,例如 missing=[{"kind":"catalog","ids":["B"],"fields":["rows","covered_product_ids"]}]。snapshot_data_incomplete 对应 supply_snapshot,输入损坏的 replay_invalid_input 对应 repair_case;两者均 retryable=false。AI 应按 fields 补齐原始快照再 open/fork,或修复 case,随后从保存的轮次继续;重复同一请求不会产生缺失数据。诊断只含字段名和受控实体标识,不含凭据、任意上游异常或完整工具参数;非法诊断退回固定失败信息,不更新失败轮的 checkpoint。

所有回放命令默认 JSON 的最终输出信封(包含路径等元数据)按 12,000 bytes 控制。超限时返回 truncated=true、data.artifact 与 next_action=read_artifact,完整输出转存为权限 0600 的本地临时证据文件;运行文件和显式 --out 仍保留完整数据。AI 应先读取 artifact;需长期保存时将其复制到任务目录。非法或缺失结构化诊断的 422 始终使用固定文案,不回显上游 message。

回放配置覆盖(#442):在本地改 SA、FAQ、扩展知识、customer_config 后重跑,不写线上。

cs-cli --env prod debug replay export --record <record_id> --out case.json
cs-cli --env prod debug overlay init --case case.json --out ov/          # 只读;默认 --base current
# 编辑 ov/sa.json、ov/faq.json、ov/common_knowledge.json、ov/customer_config.json
cs-cli debug overlay build --case case.json --overlay ov/ --out case.ov.json
cs-cli --env dev debug replay open --case case.ov.json --out run-ov.json && cs-cli --env dev debug replay run --run run-ov.json
cs-cli debug replay compare --baseline run.json --candidate run-ov.json --ab
  • overlay init 生成 sa.json(SA 全量)、faq.json(FAQ 当前全集)、common_knowledge.json(扩展知识当前全集)、customer_config.json(深合并补丁,初始 {})和 .base.json(基线元信息)。不写 request 及其中凭据。
  • --base current:取同一 Agent 最近一轮 Sol 回复的资产,再用 sa list、agent get 的当前值修正,差异写进 stale_fields(只核对 SA 和 flow_instruction 槽位;所选回复超过 24 小时会告警,其他配置可能已改过);找不到 Sol record 时退回事故快照,.base.json 标 fallback: "incident" 并在 stderr 告警。--base incident:取 case 第一轮(或 --turn N)的资产。
  • FAQ 条目 id 写成 <file_id>-<answer_group_id>,知识条目写成 <file_id>-<chunk_id>。
  • overlay build 只写和基线不同的 SA,定位写 id(内容哈希),不写每轮排序编号 ref;sa.json 里 ref / id 重复会报错(复制条目当新增时去掉 ref 和 id)。faq.json / common_knowledge.json 相对 init 有改动(含新增、删除)时整集写入,回放里对应的检索改为本地词法检索(报告标 lexical_approx);没改或删掉文件时不写,仍用录制结果。标准 QA 不覆盖,报告固定写 qa_assets: "baseline"。商品仍用 replay open/fork --products。
  • hash 与引擎同口径:去掉 hash 后键按码点排序、无空白分隔、非 ASCII 原样、UTF-8,取 sha256。
  • 每轮结果带 overlay_report(applied / missing / retrieval)。同样的 case 可直接给 sol-local run --case case.ov.json。
  • classic 店:overlay init --agent <id>,overlay build 输出 debug_data_overlay v1,交给 debug reproduce --data-overlay @file。v1 的 FAQ / 知识只带相对基线改动或新增的条目;v1 表达不了的改动(含删除条目)列在 skipped。

--data-overlay 生效检查:debug ask / debug reproduce 带 --data-overlay 时,发送前若目标 Agent 的顶层引擎(读不到时 reproduce 看原 record)是 Sol 或 Luna 而 sop 子树非空,直接退出码 2、不发送(这两个引擎不读 sop 子树);发送后逐条读回 debug_data_overlay 回报并输出 debug_data_overlay_report,一项都没生效时退出码 3。

Sol 完整 prompt 存档(debug trace 的第二种 id):Sol 引擎(路由 v4)每轮把每次 LLM 调用发给模型的原样 messages / tools 存到 OSS(30 天),debug record 返回的 sol_trace_id(st-YYYYMMDD-<uuid>)即存档 id。存档格式与各种视图都由服务端定义,CLI 只传参、写文件(设计见 docs/devkit/specs/2026-09-23-sol-trace-完整prompt回溯与AI取数.md §9.20)。只接受登录用户,且需有该存档所属 workspace 的权限。

  • 单轮:--view summary(默认)给身份 / 结局 / labels / decision / 每次调用一行。--view diagnosis 是给客服助手的更短卡片(无身份 id、无工具入参,不超过 4KB)。要原文再取 prompt(--call 选,默认第一次 main)、lean、full 或 otel。verified 是服务端哈希校验结果。
  • 按天:每天北京时间 02:30 合并前一天,当天的请用单轮(先在 Langfuse 按结局 tag 筛出轮次,再拿 sol_trace_id)。workspace 取全局 --workspace / 默认配置。不带 --out 只列各 agent 的轮数;--out <dir> 下载服务端展开好的调用文件到 <dir>/<date>/<workspace>/<agent>/calls.jsonl(一次调用一行,lean 形态,每行带轮次上下文、labels、decision)。--label(可重复,AND)按结局标签筛轮次,如 transfer、repair、llm-error、status:failed、warn:<告警码>;--node 只保留某类调用;--limit 限制轮数(跨 agent 累计)。
# 某条回复为什么这么回:record 里直接带 decision;要原文再看 prompt
cs-cli debug record <record_id>
cs-cli debug trace --record <record_id> --view prompt
cs-cli debug trace st-20260923-<uuid> --view prompt --call repair

# 批量:昨天某 agent 所有转人工轮次的主调用
cs-cli --workspace <workspace_id> debug trace --date 2026-09-23 --agent <agent_id> --out ./sol-trace --label transfer --node main

debug trace(v0.4.0 起,行为变更)不再由 CLI 直连 Langfuse REST API,改为请求 customer-servhub-api 的 GET /v1/debug/langfuse/trace/{trace_id}?env=<env>,走 CLI 标准 Bearer 鉴权,由服务端按 env 选择 Langfuse 凭据并代理拉取 Trace。Trace ID 从 debug record 返回的 trace_id 字段获取。

工作空间 (workspace)

| 命令 | 说明 | | --- | --- | | workspace list | 列出当前账号可访问的工作空间 | | workspace points-consumes [--page <n>] [--page-size <n>] | 分页查询积分账户消耗流水,固定返回 extra 调试字段 | | workspace points-consumes-daily [--start <YYYY-MM-DD>] [--end <YYYY-MM-DD>] | 按天查询积分消耗趋势 |

  • debug trace --langfuse-env <dev|prod>:指定 Langfuse 环境,默认跟随全局 API 环境;未传全局 --env 时默认 prod。非法值报错并以非 0 退出,不发请求。
# 默认 prod 环境
cs-cli debug trace <trace_id>

# 指定 dev 环境
cs-cli debug trace <trace_id> --langfuse-env dev

迁移(v0.4.0 BREAKING):config set --langfuse-host / --langfuse-public-key / --langfuse-secret-key 及 CLIConfig.langfuseHost / langfusePublicKey / langfuseSecretKey 已移除;环境变量 LANGFUSE_BASE_URL / LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY 在 CLI 侧不再被读取。~/.cs-cli/config.json 中相关字段可直接删除。Langfuse 连接信息(含 dev/prod 双环境凭据)现由 customer-servhub-api 服务端的 system_config 表 langfuse_config 行统一管理(不再读服务端环境变量 / 内置常量),CLI 侧无需也无法再配置。

修复记录 (repair-record)

| 命令 | 说明 | | --- | --- | | repair-record list [--issue <工单ID>] [--agent <AgentID>] [--workspace <工作空间ID>] [--page N] [--page-size N] | 列出修复记录 | | repair-record create --issue <工单ID> --agent <AgentID> --action <修复动作> [--agent-name <名称>] [--type <类型>] [--status <状态>] [--duration <毫秒>] [--result <JSON>] [--workspace <工作空间ID>] | 创建修复记录 | | repair-record update <record_id> --data <json\|@file> | 更新修复记录 |

--status 可选值:pending、success、failed、partial。

repair-record update 的 --data 支持的字段:repair_action、repair_result(JSON 对象)、repair_type、repair_status、duration_ms。

repair_result 结构

--result 或 --data 中的 repair_result 字段应为结构化 JSON,用于记录 AI 修复的完整推理过程,支持未来 AI 自我进化。

| 字段 | 类型 | 说明 | | --- | --- | --- | | failure_type | string | 问题分类: wrong_answer / missing_answer / hallucination / wrong_routing / slow_response / other | | root_component | string | 归因组件: sa_policy / faq / product_knowledge / customer_config / prompt / multiple / unknown | | input | string | 触发问题的用户输入 | | expected | string | 期望的正确回复 | | actual | string | 实际的错误回复 | | diagnosis_reasoning | string | AI 的诊断推理过程:排查了什么、怎么定位根因、排除了哪些可能性(最高价值字段) | | diagnosis_confidence | string | 诊断置信度: high / medium / low | | hypotheses_considered | array | 考虑过的假设列表,每项含 hypothesis、evidence_for、evidence_against、verdict | | fix_strategy | string | 修复策略: create_sa / update_sa / delete_sa / update_faq / add_faq / update_product / update_config / multi_step | | fix_reasoning | string | AI 的修复决策推理:为什么选这个方案、为什么不选其他方案、预期风险和收益 | | alternatives_rejected | array | 被否决的方案列表,每项含 approach、reason | | changes | array | 变更快照,每项含 component、action、target_id、before、after | | target_fixed | boolean | 目标问题是否修复 | | regression_summary | string | 回归验证结果摘要 | | retry_history | array | 重试记录,每项含 round、what_failed、lesson、adjustment | | duration_ms | number | 修复总耗时(毫秒) | | repair_status | string | 最终状态: success / failed / partial | | resolved_date | string | 修复完成时间(ISO 格式) |

加粗的两个字段(diagnosis_reasoning 和 fix_reasoning)是对 AI 自我进化价值最大的:没有它们只能做模式匹配,有了它们才能做推理。

运维操作记录 (ops-record)

本组全部命令要求内部普通权限(DEVELOPER、ADMIN 或 SYSTEM_ADMIN)。

| 命令 | 说明 | | --- | --- | | ops-record list [--workspace <工作空间ID>] [--agent <AgentID>] [--page N] [--page-size N] | 列出运维操作记录 | | ops-record get <record_id> | 获取运维操作记录详情 | | ops-record create --workspace <工作空间ID> --agent <AgentID> [--workspace-name <名称>] [--agent-name <名称>] [--path <文件路径>] [--remark <备注>] | 创建运维操作记录 | | ops-record update <record_id> --data <json\|@file> | 更新运维操作记录 | | ops-record delete <record_id> | 删除运维操作记录(软删除) |

ops-record update 的 --data 支持的字段:workspace_name、agent_name、path、remark。

创建记录时 operator_id 和 operator_name 自动从当前登录用户获取,无需手动指定。

商品变更事件消费 (change-consumer)

客服运维助手订阅并消费商品变更事件(pull 模式)。后端走 /v1/change-consumers/*,CLI 标准 Bearer 鉴权。默认 consumer_key=ops_agent_assistant。

标准工作流:sub create 创建订阅 → delivery list 轮询待消费项 → delivery claim 认领 → 处理 → delivery complete 回写。

| 命令 | 说明 | | --- | --- | | change-consumer sub create --workspace-id <id> [--agent-config <id>] [--events <list>] [--resource-type product] [--consumer-key <key>] [--consumer-name <名称>] [--disabled] [--data <json\|@file>] | 创建订阅(最简只需 --workspace-id;--agent-config 缺省表示该工作空间全部商品事件) | | change-consumer sub list [--workspace-id <id>] [--agent-config <id>] [--consumer-key <key>] [--enabled <true\|false>] [--page N] [--page-size N] | 查询订阅列表 | | change-consumer sub update <subscription_id> --data <json\|@file> | 更新订阅(enabled / events / filters / consumer_name) | | change-consumer delivery list [--workspace-id <id>] [--agent-config <id>] [--consumer-key <key>] [--statuses <list>] [--cursor-created-at <iso>] [--cursor-delivery-id <id>] [--limit N] | 查询待消费项(不传 --statuses 时后端默认返回 pending/claimed/failed;--cursor-* 做增量拉取) | | change-consumer delivery claim <delivery_id> --claimed-by <id> [--consumer-key <key>] [--lease-seconds N] | 认领待消费项(已被其他实例认领且未过期时认领失败) | | change-consumer delivery complete <delivery_id> --status <completed\|ignored\|failed> [--result-action <action>] [--result-note <note>] [--last-error <error>] [--consumer-key <key>] [--data <json\|@file>] | 回写处理结果 |

  • sub create 默认 --events product.updated,product.deleted、--resource-type product;--disabled 创建为停用态(默认启用)。
  • delivery complete 的 --status 仅接受 completed / ignored / failed,其它值直接报错退出;不要长时间停留在 claimed 不回写。
  • --result-action 建议值:supplemental_knowledge / product_association / rerun_product_study / refresh_recommended_qa / ignore_change / manual_follow_up。
  • 各子命令 --data <json|@file> 为高级用法,提供时覆盖对应结构化选项。
# 1. 创建订阅(该工作空间全部商品 更新/删除 事件)
cs-cli change-consumer sub create --workspace-id <ws> --events product.updated,product.deleted

# 2. 轮询待消费项
cs-cli change-consumer delivery list --workspace-id <ws> --statuses pending

# 3. 认领
cs-cli change-consumer delivery claim <delivery_id> --claimed-by ops-assistant-1

# 4. 处理后回写
cs-cli change-consumer delivery complete <delivery_id> --status completed \
  --result-action supplemental_knowledge --result-note "已补充商品知识"

运营监控 (monitor)

直接调用 /v1/operation 底层接口,返回原始数据,由调用方决定如何聚合统计。fields、tickets list/delete 要求内部普通权限;其余六个数据查询命令要求 SYSTEM_ADMIN。

字段说明

| 命令 | 说明 | | --- | --- | | monitor fields [resource] | 查看监控资源的指标字段说明;本地静态输出,仍要求内部普通权限 |

Agent 生命周期

| 命令 | 说明 | | --- | --- | | monitor agents [--page N] [--page-size N] | Agent 生命周期列表(含构建进度、会话统计等原始数据) |

监控工单

| 命令 | 说明 | | --- | --- | | monitor tickets list [--agent <id>] [--status <状态>] [--severity <级别>] | 列出监控工单 | | monitor tickets delete <ticket_id> | 删除监控工单 |

监控快照

| 命令 | 说明 | | --- | --- | | monitor snapshots hourly --agent <id> --start <ISO> --end <ISO> | 查询小时快照 | | monitor snapshots daily --agent <id> --start <日期> --end <日期> | 查询日快照 | | monitor snapshots daily-range --agent <id> --start <日期> --end <日期> | 查询日快照范围(含趋势) |

Agent 运营统计

| 命令 | 说明 | | --- | --- | | monitor statistics [--start <ISO> --end <ISO>] [--page N] [--page-size N] | Agent 运营统计(会话量、转人工率、响应时间等) |

运营工作空间

| 命令 | 说明 | | --- | --- | | monitor workspaces [--has-agent] [--page N] [--page-size N] | 运营工作空间列表(含合同、客户信息) |

模型 Token 成本(token-usage,需超级管理员(SYSTEM_ADMIN))

成本以 customer-observability-api 账本为准;cost_cny 是刊例价,payable_cost_cny / discount_rate 是实付。

| 命令 | 说明 | | --- | --- | | token-usage summary --start <时间> --end <时间> [--workspace-id <id>] [--agent <id>] [--engine sol\|luna\|classic] [--include-test] | 时间窗内的成本汇总 |

数据看板 (dashboard)

转人工率 / 接待量 / AI 回复量等运营指标。数据 T+1(--end 不能晚于昨天,否则后端返回 400);--start / --end 为闭区间。渠道枚举:qianniu(千牛/淘宝)/ jingdong / pinduoduo / douyin。CLI 只产结构化数据,运营报告由上层(如 LLM)按场景加工。

| 命令 | 说明 | | --- | --- | | dashboard summary [--config-id <id>] [--start <d>] [--end <d>] [--channel <c>] | 全局或单店 KPI 汇总 + 环比(不传 --config-id 为全店铺聚合) | | dashboard trend [--config-id <id>] [--start <d>] [--end <d>] [--granularity day/week/month] [--channel <c>] | 趋势(每日/周/月接待客户数、转人工数、转人工率),--granularity 默认 day | | dashboard shops [--start <d>] [--end <d>] [--channel <c>] | 全部店铺统计列表(默认按转人工客户数降序),用于横向对比 | | dashboard export --start <d> --end <d> [--config-id <id> ...] [--channel <c>] [--out <path>] | 店铺维度每日明细。默认解析为 JSON 行;--out 落盘原始 CSV。--config-id 可重复传,不传=全部店铺 | | dashboard intent --config-id <id> [--start <d>] [--end <d>] | 单店各意图(一级/二级标签)消息级转人工统计,默认按转人工消息数降序 | | dashboard intent-conversations --config-id <id> --event-one <l> --event-two <l> [--start <d>] [--end <d>] [--page <n>] [--page-size <n>] | 某意图下会话列表下钻 |

口径要点:

  • summary / trend / shops / intent 直接透传后端 JSON(total_customers / transfer_rate / avg_* 等英文 key)。
  • export 把 CSV 表头映射为稳定英文 key:date / shop_name / channel / customers / ai_independent_customers / ai_independent_rate / transfer_customers / transfer_rate / ai_reply_messages;计数字段转 number,比率字段保留原始字符串(如 "46.0%")。
  • 接待客户数(customers) 按客户去重,是看板口径的"会话/接待量";AI 回复消息数(ai_reply_messages) 是真实 AI 回复条数;对话轮次 ≈ ai_reply_messages / customers。
  • dashboard export --out <path> 落盘原始 CSV 时,stdout 仅返回 {path, bytes, count}。

输出格式

默认输出 JSON:

{
  "success": true,
  "data": { ... }
}

错误时:

{
  "success": false,
  "error": { "code": 1, "message": "错误信息" }
}

使用 --table 选项可以表格形式输出。

退出码

| 退出码 | 含义 | | --- | ------------------- | | 0 | 成功 | | 1 | 业务错误 / CLI 角色权限不足或未知 / 批量全部失败 | | 2 | 认证错误(未登录或 Token 过期) / 批量部分失败 / debug ask·reproduce 的 --data-overlay 带 sop 子树而引擎是 Sol 或 Luna(未发送) | | 3 | 网络/服务器错误 / debug ask·reproduce 的 --data-overlay 一项都没生效 | | 130 | 批量执行中收到 SIGINT,等飞行中请求结束后退出 |

使用示例

# 测试 Agent 回复
cs-cli debug ask --agent a0901fe383064c2abefb0bf1cd52988e --text "你好"

# 获取调试信息(返回 flow_info 和 trace_id)
cs-cli debug record <record_id>

# 根据 trace_id 查询 Langfuse Trace 详情
cs-cli debug trace <trace_id>

# 各工作空间 Issue 统计
cs-cli issue stats --start 2026-03-01 --end 2026-03-23

# 列出工单(按日期筛选)
cs-cli issue list --agent <id> --start 2026-03-01T00:00:00 --end 2026-03-22T23:59:59

# 批量改派(花名 → user_id 自动解析,走 cs-admin BFF 原子改派 + 飞书通知)
cs-cli issue update-owner --ids iss-1,iss-2,iss-3 --owner xinghe --yes

# 批量改派 dry-run(不写):仅解析 owner + 列出 ID
cs-cli issue update-owner --ids iss-1,iss-2 --owner xinghe --dry-run

# pipe-first:先 list 拿 id,再 xargs 批量改派
cs-cli issue list --status open --priority high \
  | jq -r '.data.items[].issue_id' | tr '\n' ',' \
  | xargs -I{} cs-cli issue update-owner --ids "{}" --owner xinghe --yes

# 批量关闭工单(串行 PATCH,部分失败末尾报告)
cs-cli issue update --ids iss-1,iss-2,iss-3 --data '{"status":"closed"}' --yes

# 从文件批量创建工单(user_name 反查 + content 拼装在 CLI 完成)
cs-cli issue create --file ./issues.json --dry-run    # 先预览,发现 NOT_FOUND/AMBIGUOUS
cs-cli issue create --file ./issues.json --yes        # 确认 → 实际创建

# 上游 LLM 直接 pipe 进 stdin
cat meeting-notes.md \
  | <llm-extract-issues> \
  | cs-cli issue create --stdin --yes

# 搜索场景动作
cs-cli sa search --agent <id> --keyword "退款"

# 创建场景动作
cs-cli sa create --agent <id> --first-label "售后咨询" --second-label "退款" --situation "用户要求退款" --action "引导用户提交退款申请"

# 查看场景动作修改记录
cs-cli sa versions --agent <id> --id 3

# 使用 JSON 文件更新 Agent
cs-cli agent update <config_id> --data @config.json

# 在明确指定来源 Agent 与目标空间后复制 Agent
cs-cli agent fork \
  --source-customer-config-id <source_config_id> \
  --target-workspace-id <target_workspace_id> \
  --clone-tools

# 全量复制工具(含店铺授权)
cs-cli agent fork \
  --source-customer-config-id <source_config_id> \
  --target-workspace-id <target_workspace_id> \
  --clone-tools --copy-authorized-shop-id

# 更新商品卖点
cs-cli product update --agent <id> --product-id 977691714398 --update '{"卖点":"新卖点"}'

# 更新商品标签
cs-cli product update --agent <id> --product-id 977691714398 --update '{"tag":"春季新品,热卖"}'

# 更新 SKU 补充知识(按 sku_id 定位,推荐)
cs-cli product update-sku --agent <id> --sku-id 6072595054179 --update '{"补充知识":"粉红色为浅粉调"}'

# 添加 FAQ
cs-cli faq add --agent <id> --file "常见问题" --questions "怎么退款,如何退款" --answers "答案=请联系客服处理退款"

# 列出文件内答案组(拿 answer_group_id,供下面 update/delete 用)
cs-cli faq content --agent <id> --file "常见问题" --keyword 退款

# 更新已有 FAQ 组答案
cs-cli faq update --agent <id> --file "常见问题" --group-id 2 --answers "答案=请通过订单页面申请退款"

# 更新 FAQ 组问题 + 删除旧 chunk
cs-cli faq update --agent <id> --file "常见问题" --group-id 2 --questions "如何退款,怎么申请退款" --delete-chunks 3,5

# 删除整个 FAQ 答案组
cs-cli faq delete --agent <id> --file "常见问题" --group-id 2

# 列出 Agent 的扩展知识库
cs-cli knowledge list --agent <id>

# 列出某扩展知识库的段落
cs-cli knowledge content list --knowledge-id 622474

# 新增段落(插入到末尾)
cs-cli knowledge content add --knowledge-id 622474 --content "退换货需保留商品吊牌" --keyword 退换货 吊牌

# 用文件内容作为段落
cs-cli knowledge content add --knowledge-id 622474 --content @./rules.txt

# 修改段落内容并重设关键词
cs-cli knowledge content update --knowledge-id 622474 --chunk-id 2 --content "新的规则说明" --keyword 规则 说明

# 停用某段落
cs-cli knowledge content update --knowledge-id 622474 --chunk-id 2 --disable

# 删除段落
cs-cli knowledge content delete --knowledge-id 622474 --chunk-id 2

# 商品 URL 异步学习
cs-cli product learn --agent <id> --url https://detail.tmall.com/item.htm?id=997678657962

# 多个 URL 一次提交,且跳过自动识别
cs-cli product learn --agent <id> --url https://a.example/1 https://a.example/2 --no-identify

# 直接传入结构化商品数据(JSON 数组),或从文件读取
cs-cli product add --agent <id> --data '[{"title":"商品A","price":99}]'
cs-cli product add --agent <id> --data @products.json --source batch --no-identify

# 通过上下文内容模糊搜索对话记录(自动使用当前工作空间,查询窗口最多 3 天)
cs-cli conversation context-search --query "退款问题" --start 2026-03-22T00:00:00 --end 2026-03-22T23:59:59

# 查询转人工会话及对应转人工消息记录(按 MANUAL_TAKEOVER_REQUIRED 事件时间过滤,查询窗口最多 7 天,自动 cursor 翻页)
cs-cli conversation transfer-human --agent <customer_agent_config_id> --start 2026-05-24T00:00:00 --end 2026-05-24T23:59:59

# 复现某条回复(自动获取上下文、原始用户名、Agent 配置)
cs-cli debug reproduce <record_id>

# 用另一个 Agent 复现同一段上下文(A/B 对比)
cs-cli debug reproduce <record_id> --agent <other_config_id>

# 仅查看截断后的上下文,不实际发送
cs-cli debug reproduce <record_id> --dry-run

# 重放对话测试 Agent
cs-cli debug ask --agent <id> --messages @conversation.json

# 列出某工单的修复记录
cs-cli repair-record list --issue <issue_id>

# 创建修复记录
cs-cli repair-record create --issue <issue_id> --agent <agent_id> --action "更新 SA 策略"

# 更新修复记录状态
cs-cli repair-record update <record_id> --data '{"repair_status":"success","duration_ms":1200}'

# 列出运维操作记录
cs-cli ops-record list --workspace <workspace_id> --agent <agent_id>

# 创建运维操作记录
cs-cli ops-record create --workspace <workspace_id> --agent <agent_id> --remark "更新配置文件"

# 更新运维操作记录
cs-cli ops-record update <record_id> --data '{"remark":"已完成配置更新","path":"/data/config"}'

# 删除运维操作记录
cs-cli ops-record delete <record_id>

Ops Agent (ops-agent)

| 命令 | 说明 | | --- | --- | | ops-agent conversations [--agent-id <id>] [--customer-id <id>] [--page N] [--page-size N] | 查询客服助手会话列表 |

ops-agent conversations 对接 customer-servhub-api /v1/ops-agent/conversations,返回字段固定为 workspace_id、customer_id、title、agent_id、created_at、updated_at。命令会自动带当前 workspace-id;--agent-id 对应 Ops Agent 配置 ID(customer_agent_config_id),--customer-id 可选。

# 查询当前 workspace 下某个客服运维助手的会话
cs-cli ops-agent conversations --agent-id <customer_agent_config_id>

# 按 customer 进一步过滤
cs-cli ops-agent conversations --agent-id <customer_agent_config_id> --customer-id <customer_id>

商品尺码资料

product size 独立保存原图、描述和完整转写,不依赖商品总结。先读取集合版本,再预演或应用;适用范围未确认的资料供查看,不默认套给全部 SKU。

cs-cli product size list --agent <agent_id> --product-id <product_id>
cs-cli product size sources --agent <agent_id> --product-id <product_id>
cs-cli product size refresh --agent <agent_id> --product-id <product_id> --if-revision 0
cs-cli product size refresh --agent <agent_id> --product-id <product_id> --if-revision 0 --apply
cs-cli product size get --agent <agent_id> --product-id <product_id>
cs-cli product size set --agent <agent_id> --product-id <product_id> --if-revision 1 --data @guide.json
cs-cli product size changes --agent <agent_id> --product-id <product_id> --after-revision 0

guide.json 是单份资料,必填 image_url、description、content;可填 guide_id、applicability、applicability_status(unknown / confirmed,确认时必须填写适用说明)、locked(默认 true)。set / delete / refresh 默认服务端预演,--apply 才写;已有锁定资料的校正或删除必须另带 --override-lock 并有用户授权。版本冲突时重新读集合和差异,再决定如何提交。

refresh 只从当前已有 OCR 归集候选,未找到候选不删除旧资料;sources 返回全部主图、详情图和可用 SKU 图供 AI 查漏。它们不重新识图,也不保证同 URL 图片字节已更新。需要重新识图时先用现有 product image-identify 获取结果,再经 size set 缓存核验后的完整转写。本批不自动对生产商店全量回填,也不改变 Sol 的运行时工具;服务端对应接口必须先部署。

product size 始终输出完整 JSON(全局 --table 也保留 JSON),确保集合版本和预演结果可读取。