Files
agent-call/AGENTS.md
T

103 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# agent-call:部署与开发约束
## 目录与实施范围
- 项目根目录用于部署,`docs/` 保存需求、计划与验收资料,不挪回根目录。
- 现有实现为 ASR Web 验证、Asterisk 配置和阿里云主机准备工具,不是完整外呼平台。用户已接受最终方案,后续按 `docs/最终开发部署监控与验收计划_v1.0.md` 开展契约驱动 Mock 开发,再替换真实依赖。
- 用户已决定**仅复用 voice_test 的 ASR**。禁止复制或启用该仓库的 LLM/TTS;新规范确认前,界面必须明确显示未启用。
- SaaS 指令与所有业务结果均走 RabbitMQ;录音先上传 OSS,再通过 MQ 回传 OSS ID。接口/消息规范由用户制定,不能擅自改成 HTTP 业务回调。
## 最终实施与 Mock 边界(用户已确认)
- 以最终开发部署监控与验收计划为实施入口,`docs/SaaS交互_OpenAPI与MQ契约规划_v0.1.md` 正文 v1.0 是字段/路径/状态的唯一维护来源;从 D01 生成 OpenAPI/共用 MQ Schema 开始,不重复等待已接受方案拍板。
- 外部 SaaS、数据库、RabbitMQ、SIP/AI、OSS/云条件并行协调。HTTP Mock 遵守 OpenAPIMQ 用真实测试 brokerSIP/ARI/RTP及AI流式通道按协议模拟,不改成HTTP业务回调;持久状态使用真实隔离数据库,不用内存字典代替。
- `mock/mixed/real` 必须可识别,Mock 默认隔离真实外网,正式模式拒绝 Mock/测试凭证,不静默回退。LLM/TTS 可开发新 Mock 适配,但不得复用旧实现或假称真实供应商已启用。
- 已接受原值key一对一绑定、超出224个UTF-8字节路由预算则停发保留原任务而非截断;控制CAS、整体补传、无应用收讫、整任务撤销屏障等规则以主契约为准。
- 最终计划的 DEV/SCALE-MOCK 数值是工程初始测试基线,不是生产SLA/业务额度/消费授权。真实预算、供应商能力、保留与RPO/RTO需在实际部署前登记核验;Mock通过不得替代真实1000路完整AI、N+1及供应商验收。
## 固定资源与云部署规则
1. 区域为阿里云北京 `cn-beijing`
2. 我方对 SIP 服务商登记的公网出口白名单 IP 是 **123.56.71.98**。它不是 SIP 服务端地址,不得填入 trunk contact。
3. 目标计算资源为阿里云竞价 ECS。必须先使用阿里云 CLI 查询 IP/EIP 与现有实例;确认没有可复用主机后,才允许按明确的实例规格、价格上限、磁盘/VSwitch/安全组/SSH KeyPair 创建。
4. 固定 IP 是否为本账号可操作的 EIP 必须查询。找不到该 EIP/现有公网 IP 时停止,**禁止新分配任意公网 IP 冒充白名单地址**。若属于非 EIP 的实例公网 IP,只能复用经明确指定的原实例;回收后的地址保留不能保证。
5. 不解绑或覆盖其他实例上的 EIP,不删除、停机或修改无关实例;多个候选实例、未知归属或未授权绑定一律停止。
6. 工具默认只读计划;`--apply` 才执行创建/绑定。用户未确认预算、云凭据未配置、现有绑定不明时,不能实际消费或改绑。竞价价格上限不包含系统盘/EIP/流量费用。
7. 创建使用持久化 ClientToken;创建后绑定失败保留实例ID供恢复,不自动再创建一台、不自动删除实例。竞价回收不等于自动迁移活动通话。
8. 使用 `aliyun` CLI 创建竞价 ECS 进行测试时,测试完成必须先询问用户是否清理。未获得明确清理指令时,保留唯一 `project=agent-call` 可用/运行实例,不自动删除或并行创建第二台;用户明确要求清理后,只停止并删除本次创建的实例,不删除、释放或解绑指定 IP/EIP。
9. 不把 AK/Secret、ASR Key、ARI 密码、SSH 私钥放入代码、文档、日志或聊天。优先配置 CLI RAM Role/STS,运行时通过环境或受控文件注入。
## SIP 接入信息
以下为用户提供的首组 SIP 参数,供应商名称待补充;已记录不代表已完成真实线路验证。
| 项目 | 参数 |
| --- | --- |
| SIP 服务端 | `61.132.228.221:5060` |
| 主叫号码/标识 | `BD93205882` |
| 被叫前缀 | `7089` |
| 我方出口白名单 IP | `123.56.71.98` |
## 测试呼叫号码
- 用户指定测试被叫号码:`18601013734`。仅用于已授权的 Mock/明确安排的测试;不得因写入此处而自动发起真实呼叫,原始号码保持不变。
- 主叫标识保留原值(包括 `BD`),不能按纯数字手机号清洗,也不能直接当成 Digest 认证用户名;具体 From/PAI 等字段映射仍需确认。
- 业务原始被叫号码保持不变;使用该线路时按其规则构造 `7089<被叫号码>`,避免重复添加或把该前缀带到其他供应商线路。
- 传输协议、IP/Digest 鉴权、是否注册及并发限制仍需供应商确认;当前供应商已反馈需使用 PCMA,Asterisk 配置以 `allow=alaw` 表示,仍需真实线路验证。
- 目前只提供一组服务端地址,未提供独立备用地址。不能把同一地址重复填写成主备并宣称具备容灾;现有生成器要求 primary/backup,单线路启动支持尚待调整。
## 多 SIP 供应商方案(用户已确认,运行代码待实现)
- 采用**供应商按需预接入 + 每次外呼动态选路**。先验证当前供应商,后续逐家新增,不等待所有供应商一次性接入完毕。
- 供应商/线路层预先维护独立 trunk:服务端、协议、鉴权、注册、允许的主叫、被叫改写规则和并发额度。不同供应商不能共用并逐呼覆盖同一份线路配置。
- 呼叫层只从服务端已配置且获授权的线路中选择,按该线路规则设置本次主叫与被叫;**不为每个号码重写 pjsip.conf、重载 Asterisk 或重建注册**。
- MQ 指令不能让调用方任意注入 SIP 地址、认证凭据或越权主叫;线路选择对应的具体消息字段仍由用户制定,不擅自定接口。
- SIP Trunk、codec、主叫/被叫规则、出口池及多机器 Cell 发布由独立 Asterisk/SIP 管理后台作为唯一写入面统一管理;SaaS 仅可读取受控 Trunk 目录/状态,不直接访问 Asterisk/ARI 管理面或写入 SIP 配置。
- 切换线路时从原始被叫重新应用目标线路规则,不能沿用上一家的前缀或主叫。重试/切换条件需按业务契约另行实现,不能默认重复拨打已接通的电话。
- 现有生成器仅支持固定 primary/backup,尚非完整多供应商路由;后续支持单线路启动、可扩展线路列表及逐呼选路,不为凑齐主备而虚构供应商。
## 生产容量与网络架构基线(用户已确认,运行代码待实现)
- 目标口径是**至少 1000 路同时已接通的完整 AI 通话**,包括 ASR/LLM/TTS;拨号、振铃、CPS 和故障冗余必须另行计入,不能把 1000 路在途呼叫当作验收结果。
- 生产主方案为**多机器 + 多 EIP 直连**:每个语音 Cell(Asterisk、媒体适配和本地执行器)绑定固定出口 IP;调度器选择 `trunk_id + egress_pool_id + cell_id`,一通电话从建立到结束固定在同一 Cell/出口,不逐呼重写共享 SIP 配置。
- 每个 Cell/出口要维护独立的供应商白名单、RTP 端口范围、并发上限、CPS 令牌、编解码和健康状态。供应商限制优先于本地理论容量;不能用随机轮询突破供应商配额。
- 采用 N+1 或更高冗余:按压测得到的单 Cell **安全容量**计算 `(Cell数量 - 1) × 单Cell安全容量 >= 1000`,并额外预留发布、线路降级和突发拨号余量。未完成真实 ASR/LLM/TTS、SIP/RTP 和供应商压测前,不承诺固定机器数或规格。
- 单 EIP+NAT 不再作为备选方案;当前及后续生产计划不设计、不实现、不验收该架构,不得以通用 SNAT 替代多 EIP 直连。
- 调度器只分配有完整资源租约的 Cell:供应商并发/CPS、Cell媒体端口、ASR/LLM/TTS配额、出口健康和节点容量必须同时满足;租约过期或心跳失效时停止新任务,活动通话不自动接管。
- RabbitMQ 只负责可靠传输,不作为活动通话唯一状态源;命令/结果采用持久化、发布确认、手动确认和幂等事件。业务状态、调度租约和 outbox 需要可靠持久化;重复投递不能造成重复拨号或重复业务结果。
- 1000 路容量必须同时验证 RTP 包率/带宽、RTP 端口对数量、连接数/文件描述符、NAT/conntrack、AI 首包及持续延迟、MQ 堆积、OSS 上传速度和供应商错误率。当前 RTP `1000010800` 仅为基线,绝不是 1000 路容量保证。
## 多租户队列与公平调度(用户已确认,运行代码待实现)
- SaaS 按可信 `tenant_key` 向**租户独立 RabbitMQ 命令队列** PUSH,呼出应用调度器负责租户间公平调度;不再用所有租户共享的执行 FIFO,不增加 HTTP 拨号入口。业务任务/重试决策仍属于 SaaS。
- 默认建议活跃且可调度租户等权轮询,差异化权重需按业务规则确认;每轮有界取数,租户额度耗尽或线路不可用时跳过。按租户及全局限制预取、未 ACK 和已持久化待发起窗口,不能先消费到无界内存 FIFO;重启恢复也必须公平。
- 租户并发/CPS 配额跨所有 Cell、调度实例汇总;并发覆盖预留、拨号、振铃、接通及待对账占用,CPS 包括 FALLBACK。实际发起同时满足租户额度、供应商、Cell/出口和 AI 完整资源租约。多实例须协调调度所有权和原子额度,不能各自发放一份;未知活动通话不能仅因租约到期直接释放占用。
- 平台负责队列创建、精确绑定、权限和安全停用/清理;`tenant_key` 是 SaaS 产生的业务数据,命令、队列路由及后续 MQ 回调均原样使用,不做清洗、编码或业务格式限制;必须校验正文值与队列/路由绑定精确一致。最终用户不直接连接 broker,不允许任意指定其他租户路由。命令重试/死信恢复回原租户调度域,不绕过配额。
- 每租户设置发布速率、队列消息数/字节和待执行窗口上限,并有全局 broker 水位保护。队列满明确拒绝发布,不丢弃队头旧命令;SaaS 持久保留未确认发布记录,使用原执行标识有限重试。独立队列不代表独享 broker 资源或无限积压。
- 公平调度分配新执行机会,不为公平挂断已接通电话;资源满需等待释放。固定开始时限必须另确认覆盖线路/AI/Cell 的保底容量或受限借用策略,不能仅用轮询宣称保证。
- 本轮不改变事件结果队列为一租户一队列。资源统一使用 `agent-call` 命名空间;命令 exchange 使用 direct,命令 routing key 为 `agent-call.tenant.{tenant_key}.call.execute`,事件 routing key 为 `agent-call.{event_type}`。轮转/预取、配额、保留与等待指标待 G0 冻结;须验收大租户积压下小租户公平、多实例配额不超额、背压不丢消息及租户路由安全。
## 其它环境前置
- 本地:Go 1.26、Python 3.11+、Node、Docker Engine/Compose;云操作另需 `aliyun` CLI 和北京区域权限。
- 云创建权限至少涉及 ECS Describe/RunInstances、VPC DescribeEipAddresses/AssociateEipAddress;已有 VSwitch、安全组、镜像和 SSH KeyPair。不得自动开放全部端口。
- Asterisk:镜像固定 digest;已提供的 SIP 参数见上节,其余供应商/备用地址及接入规则仍待补充。ARI 默认仅回环访问;跨机器使用管理网和受控 TLS。RTP、防火墙、NAT、编解码必须真机验证。
- ASR Web:服务访问令牌、百炼/火山凭据;默认仅宿主机回环暴露。远程麦克风需要 HTTPS,或通过 SSH 隧道访问 localhost;不要求用户关闭浏览器安全机制。
- 业务对接仍需 RabbitMQ VHost/队列/ACL、用户发布的消息契约、OSS 上传与 OSS ID 规范。测试台音频/识别输出不是已接入 SaaS 的 MQ 结果。
- LLM/TTS:供应商、协议、模型、参数、取消/打断与音频契约均待用户新规范;不得静默调用旧实现或宣称完整对话已验证。
## 参考资源
- <https://git.ipao.vip/rogee/sip-research> Asterisk 调研和 Mock 底座;不能把历史测试结果当成本环境验收。
- <https://git.ipao.vip/rogee/voice_test> :仅借用 ASR 协议代码;本项目访问控制、Web页面和生命周期独立实现。
- 最终实施入口为 `docs/最终开发部署监控与验收计划_v1.0.md`;主契约 `docs/SaaS交互_OpenAPI与MQ契约规划_v0.1.md`(路径保留,正文v1.0)。旧一期计划保留WBS/AT和历史估算,旧交付文档作实现细则;当前已存在服务的运行步骤仍见 `docs/部署接入_运行说明.md`,不能把未来产物当成已实现。
## 验证与交付
- Python`python3 -m unittest discover -s tests -v`
- Go`cd services/asr-web && go test -race ./...`;改动后执行格式化与静态检查。
- PCM`node --test tests/test_pcm.cjs`Shell`bash -n deploy/asterisk.sh`
- 不用真实云账号运行自动创建测试;使用可注入的 CLI runner 测试请求/恢复逻辑。
- 实际部署、真实 ASR、SIP、MQ/OSS、LLM/TTS测试必须分别报告,模拟测试通过不代表生产验收通过。