客服平台 MVP 使用说明
后端为 Python / FastAPI,执行层为异步 LangGraph,数据与队列保存在 PostgreSQL;前端为 TypeScript / React。普通客服工具直接调用固定 API,无需代码沙箱。
升级与启动
已有项目请在后端目录执行(保留已有 .env):
cd C:\code\ai-project\backend
uv sync
uv run alembic upgrade head
uv run python -m agent_platform.applications.seed
uv run uvicorn agent_platform.applications.customer_service.main:app --reload --host 127.0.0.1 --port 8000seed 是可选的示例初始化,创建“示例服务知识库”“示例客服 Agent”和 sample-support 会话。重复执行不会覆盖已编辑内容。必须先配置 AGENT_DATABASE_URL 并执行迁移;平台业务表自 0002_platform 起加入,后续版本必须继续升级到当前 head,不能只执行单个迁移。
另开终端启动前端:
cd C:\code\ai-project\frontend
npm ci
npm run dev访问 http://127.0.0.1:5173。默认 AGENT_MODEL_BACKEND=demo 可离线演示知识查询和工单流程,回复会明确显示演示模式;它不是通用语言模型。知识检索、工单和人工协作演示无需启动外部工具服务。使用 lookup_demo 才需要 Runtime 文档 中的 mock_business。
真实模型需要在后端设置 AGENT_MODEL_BACKEND=openai、AGENT_MODEL_NAME、AGENT_MODEL_API_KEY,可选 AGENT_MODEL_BASE_URL。API 与独立 Worker 必须使用相同运行配置。密钥不传入前端。
模块与操作流程
| 模块 | 已实现能力 | 管理台入口 |
|---|---|---|
| Agent 配置 | 草稿修订、工具与知识库授权、不可变发布版本、版本回滚 | Agent 管理 |
| Runtime | 模型—工具循环、异步队列、并发预算、取消、SSE 阶段事件与模型文本增量 | 会话工作台 / 运行与审计 |
| 模型网关 | 演示模式、OpenAI 适配、超时和 Token 用量 | 访问与策略展示配置 |
| 知识服务 | 本地文档解析、文档版本、分块索引、关键词/向量/混合检索、引用 | 知识库 |
| 工具网关 | 固定 GET/JSON POST API 注册、参数校验、主机白名单、启停和超时 | 工具目录 |
| 会话管理 | 消息账本、Agent 绑定、自动/等待/人工/关闭状态 | 会话工作台 |
| 客服业务 | 工单提案、确认/拒绝、幂等创建和工单状态流转 | 会话工作台 / 服务工单 |
| 人工协同 | 转接、摘要、接管、人工回复、恢复 Agent、关闭 | 人工协同 |
| 渠道接入 | 独立令牌/HMAC、通用 Webhook、企业微信/微信客服/飞书/钉钉/Slack/Telegram/Discord 原生适配、消息去重、会话映射、回复拉取与主动投递 | 渠道接入 |
| 策略权限 | admin/operator/viewer、部署租户隔离、工具及知识范围、预算 | 访问与策略 |
| 观测审计 | 24 小时统计、运行记录、事件回放、管理操作审计 | 运行与审计 |
| 质量评测 | 用例、模拟业务工具、输出/工具断言、按版本保存报告 | 质量评测 |
建议按以下顺序体验:
- 在知识库中创建服务文档并检索验证;或使用初始化示例。
- 新建 Agent,选择
knowledge_search、propose_ticket及知识库,保存草稿后发布。未发布草稿不会进入真实运行;提交的 Run 固定当时发布版本。 - 新建会话时选择已发布 Agent,发送“什么时候发货?”,查看回复及
knowledge.retrieved事件中的文档引用。默认 Runtime 只使用服务器配置的工具。 - 发送“请创建工单”,等待运行结束,在待确认卡片中确认。只有确认成功后才会创建 PostgreSQL 工单,重复确认返回同一张工单。
- 点击转人工,或发送精确文本“转人工”/“人工客服”。在人工协同页接管,到会话页回复,完成后恢复 Agent 或关闭会话。
- 创建评测用例,填入模拟工具结果及预期文本后运行。业务工具不会调用真实接口;真实模型模式仍会调用模型服务。
会话首次加载显示最近 200 条消息;接口 after 可增量读取之后的消息。模型上下文独立受 AGENT_HISTORY_TURNS 限制,不等于消息存储保留期限。
权限及工具配置
| 环境变量 | 作用 |
|---|---|
AGENT_API_TOKEN | 管理员令牌;非 development 环境必填 |
AGENT_OPERATOR_API_TOKEN | 可选客服操作令牌 |
AGENT_VIEWER_API_TOKEN | 可选只读令牌 |
AGENT_TENANT_ID | 服务端固定租户,不接受模型或请求指定租户 |
AGENT_TOOL_ALLOWED_HOSTS | 可注册工具主机 JSON 数组,例如 ["crm.internal"] |
AGENT_TOOL_ALLOW_PRIVATE_NETWORKS | 是否允许已加入主机白名单的私网或链路本地工具地址;默认 false |
AGENT_TOOL_SECRET_* | 工具请求头引用的服务端凭据 |
三个服务令牌角色使用不同令牌。开发环境未配置管理员令牌时允许本地管理员访问;共享部署应设置令牌。工作台“访问与策略”填写服务令牌,保存在当前浏览器 sessionStorage 中。admin 管理配置、渠道和评测;operator 操作会话、人工接管与工单;viewer 只读。员工账号、固定角色和权限码见用户权限;服务令牌角色与员工身份是不同的认证入口。
API 注册工具只能使用 AGENT_TOOL_ALLOWED_HOSTS 中的固定主机。每次调用前都会重新解析主机名,拒绝回环、私网、链路本地、组播、保留和未指定地址,并把通过校验的地址固定到本次 TCP 连接;默认只有显式列入白名单的本地回环地址可用于开发。将 AGENT_TOOL_ALLOW_PRIVATE_NETWORKS=true 仅用于明确列入白名单的内部开发服务。参数要求 JSON Schema type=object、additionalProperties=false;GET 使用标量查询参数,POST 将参数整体作为 JSON 请求体发送,暂不支持 multipart 或表单编码。headers_from_env 只能引用 AGENT_TOOL_SECRET_ 前缀的环境变量;实际凭据由启动进程环境注入。服务器上的 AGENT_TOOLS_FILE 属于受信任运维配置。停用数据库工具会阻止后续实际调用;不会撤回已经发出的 HTTP 请求。
工具目录的注册和编辑表单支持“接口鉴权”:选择“密钥鉴权”后默认直接输入密钥,不需要设置工具环境变量。Authorization 填写完整的 Bearer <实际密钥>,X-API-Key 直接填写实际密钥;可以添加多个请求头。已保存密钥不回显,留空保留、输入新值替换,移除请求头或选择“无需鉴权”后保存会清空草稿中的对应配置。修改接口地址或请求头名称时必须重新输入密钥。原环境变量方式保留兼容入口。
首次启用直接输入密钥前,执行 uv run alembic upgrade head 并重启后端及独立 Worker。新增迁移为 0021_tool_credentials。密钥使用共享密钥库加密,独立保存在 tool_credentials,配置、版本、Agent 快照与审计只含引用和请求头名称。安装主密钥沿用 model_credential_key_file(默认 backend/data/credentials/master.key,由后端首次保存密钥时自动创建),无需为工具手动创建环境变量。API 与独立 Worker 必须使用同一持久化主密钥文件;备份数据库时同时备份该文件,已有加密记录时文件丢失会拒绝保存和调用,不能重新生成替代。
密钥配置随工具版本固定:保存草稿不会改变正在使用的发布版本,修改后需发布工具版本并重新发布 Agent。旧版本继续使用对应旧密钥;如需立即阻断调用,可停用工具或在上游撤销旧密钥。
接口分组
基础路径 /api/v1;详细字段和校验规则在后端 /docs。
| 路径 | 操作 |
|---|---|
/me、/policy | 当前角色及运行策略 |
/agents、/agents/{id} | 列表、创建、修改草稿 |
/agents/{id}/versions、/publish、/rollback | 版本查询、发布、回滚 |
/tools、/tools/{id} | 注册、列表、启停 |
/knowledge-bases、/{id}/documents | 知识库及文档维护 |
/documents/{id}、/knowledge/search | 文档启停、检索 |
/conversations、/{id}、/{id}/messages | 会话及客户消息 |
/conversations/{id}/human-replies、/handoffs | 人工回复、转接 |
/handoffs、/handoffs/{id}/transition | 队列、接管/恢复/关闭 |
/actions/{id}/decision、/tickets、/tickets/{id} | 确认动作、工单维护 |
/channels、/channels/{id} | 渠道配置、启停 |
/channels/providers、/channels/{id}/config | 可用 provider 清单、原生渠道配置 |
/channels/{id}/deliveries、/deliveries/{did}/retry | 主动投递记录、失败重试 |
/ingress/channels/{id}/messages、/replies | 通用渠道消息及回复 |
/ingress/channels/{id}/webhook/{provider} | 原生渠道回调(验签、解密、标准化、出站投递) |
/observability/summary、/runs | 统计及运行列表 |
/audit | 管理员操作审计 |
/agents/{id}/evaluation-cases、/evaluation-reports、/evaluate | 用例、报告、运行评测 |
表中相邻缩写路径继承同一资源前缀,例如发布为 /agents/{id}/publish,统计运行列表为 /observability/runs。原 /runs Runtime 接口仍可用,会遵守绑定 Agent 及人工接管状态。
渠道分为通用协议与原生适配两类。
通用渠道(provider=generic_webhook)是可信服务端之间的接口:创建时返回一次明文 token,数据库只保存摘要。调用方传 X-Channel-Token,提交:
{"message_id":"upstream-unique-id","session_id":"customer-session","text":"什么时候发货?"}同一渠道相同 message_id 和内容返回已处理结果;同一 ID 不同内容返回 409。通过 /replies?session_id=customer-session&after=0 拉取回复并推进游标。渠道令牌不应发给终端客户;上游服务负责认证客户并保证 session_id 所有权。
原生渠道(provider 为 wecom/wecom_kf/feishu/dingtalk/slack/telegram/discord)通过 /ingress/channels/{id}/webhook/{provider} 接收平台回调。适配器负责验签/解密、challenge 应答与入站消息标准化,无需渠道 Token;回调只写入 channel_inbound_events(入站 outbox,按渠道+消息号去重)并立即返回平台 ACK,随后由入站 worker 建立会话并执行 Agent,避免 Slack/Discord 等 3 秒 ACK 时限导致平台重试或禁用订阅。Agent 与人工回复由出站投递 worker 主动推送到对应平台,投递记录与失败重试可通过 /channels/{id}/deliveries 及其 retry 接口查看与重放。渠道按渠道行解析租户,支持多租户。平台侧凭据在服务端加密保存,不回显、不入日志。
验证和当前边界
cd C:\code\ai-project\backend
uv run ruff check .
# 集成测试只对专用测试库运行,先对该库执行 alembic upgrade head
$env:TEST_DATABASE_URL='postgresql+asyncpg://agent:password@127.0.0.1:5432/agent_platform_test'
uv run pytest -q
cd C:\code\ai-project\frontend
npm run build
# 启动使用专用测试库、demo 模型、无令牌的 API 与前端后执行;会创建测试业务数据
npx playwright install chromium
npm run test:e2e可通过 E2E_CHROME_PATH 使用已安装 Chrome,通过 E2E_BASE_URL 指定测试站点。没有 TEST_DATABASE_URL 时 PostgreSQL 测试会跳过。
平台已覆盖基础客服流程及后续身份、知识和渠道能力,仍有以下扩展边界:
- 员工账号、固定角色 RBAC、企业 OIDC/SSO 与嵌入聊天已实现;更细粒度的组织授权和渠道客户身份体系仍需按实际场景扩展。
- 知识库支持本地文档解析、异步索引、关键词及向量/混合检索;真实 OCR、旧格式转换和大文件流式解析等边界见知识库工作台。
- 工单写入本地 PostgreSQL;外部 CRM、订单、退款等写入接口仍需专用适配器。普通 API 调用不需要沙箱,未来开放代码执行再独立设计沙箱。
- 渠道内置企业微信/微信客服/飞书/钉钉/Slack/Telegram/Discord 原生适配,均具备验签/解密、回调标准化与主动出站投递;Discord 采用应用交互端点(普通消息需 Gateway),其余平台(微信公众号、Teams 等)仍需按需新增适配器。
- SSE 同时提供持久化阶段事件与瞬态模型文本增量;增量不保证重放,最终答案以完成事件为准。Worker 失联会把运行标为失败,不支持 LangGraph 节点检查点续跑。
- 评测最多 20 个用例、单次总预算 60 秒,当前通过请求执行,进程内限流;尚无分布式评测队列和模型效果基准。
- 列表采用有限条数,管理台暂无全量搜索/分页、数据保留清理及附件对象存储。耗时与并发仍需针对实际模型和业务 API 压测;本次验证不代表生产容量承诺。