181 lines
8.7 KiB
Markdown
181 lines
8.7 KiB
Markdown
# Open Agent API 对接说明
|
||
|
||
更新时间:2026-07-27
|
||
|
||
## 1. 已完成范围
|
||
|
||
本项目新增 `agent_integration/`,用于调用 DeerFlow / NianxxAgent `Agent Profile Open API`:
|
||
|
||
- 为外部会话创建并复用 Agent Session;
|
||
- 以 SSE 流式发送消息;
|
||
- 非流式创建 Run,并查询或取消 Run;
|
||
- 使用 SQLite 保存 `conversation_id -> session_id` 映射;
|
||
- 以 JSONL 输出流事件,便于后续转发到 WebSocket、微信或 CRM;
|
||
- 所有密钥只从环境变量读取。
|
||
|
||
底层 `agent_integration` 只负责文本 Agent API。Opera XML 远程任务由独立 `arr_processing` 边界建模:ARR 代码先上传私有 OSS,再向 Agent 发送一个不含密钥的 `oss_attachments` 描述对象,由 runtime 的 `fetch_oss_file` 取件;结果只接受经受信 runtime 签名的 path-free 回调。具体处理规则仍只在 `arr-opera-daily-ingest` 确定性 Skill 内。
|
||
|
||
## 2. 安装
|
||
|
||
建议使用项目隔离环境:
|
||
|
||
```bash
|
||
cd /path/to/wyndham-ARR
|
||
python3 -m venv .venv
|
||
.venv/bin/python -m pip install -r requirements.txt
|
||
```
|
||
|
||
不要使用用户压缩包内的 Windows `.venv`,也不要复制其中的 `.env`。
|
||
|
||
## 3. 配置
|
||
|
||
参考 `.env.example`,在运行环境中设置:
|
||
|
||
```bash
|
||
export DEERFLOW_BASE_URL="https://superagent.nianxx.cn"
|
||
export DEERFLOW_OPEN_API_KEY="df_open_替换为新密钥"
|
||
export DEERFLOW_AUTH_MODE="bearer"
|
||
export DEERFLOW_SESSION_DB="runtime/agent_sessions.sqlite3"
|
||
```
|
||
|
||
代码不会自动读取 `.env`,避免开发目录中的凭据被意外加载。可由部署平台、容器 Secret 或进程管理器注入环境变量。
|
||
|
||
本机 ARR 部署使用 macOS Keychain account `arr-web`、service `com.chillishark.arr.deerflow-open-api-key` 保存 Agent key,由受控 launcher 在进程启动时映射为 `DEERFLOW_OPEN_API_KEY`。Keychain 不解决 XML 文件 Tool 或回调契约;它只是本机凭据保存方式。
|
||
|
||
原压缩包中的 Token 已经被打包传播,建议不要继续使用;请在 Ops 中撤销并生成新 Token。
|
||
|
||
## 4. 配置检查
|
||
|
||
```bash
|
||
.venv/bin/python -m agent_integration doctor
|
||
```
|
||
|
||
`doctor` 只做本地配置检查,不访问远端,也不会输出 Token。没有配置密钥时会返回状态 `missing_api_key` 和退出码 `2`。
|
||
|
||
## 5. 流式对话
|
||
|
||
```bash
|
||
.venv/bin/python -m agent_integration chat \
|
||
--conversation-id "crm-conversation-001" \
|
||
--external-subject-id "crm-customer-001" \
|
||
--message-id "crm-message-001" \
|
||
--message "你好,请介绍一下你能做什么" \
|
||
--metadata '{"source":"crm"}'
|
||
```
|
||
|
||
默认每行输出一个经过过滤的公开 JSON 事件:
|
||
|
||
```json
|
||
{"event":"message.delta","data":{"content":"你"}}
|
||
```
|
||
|
||
公开事件只包含 `run.started`、`message.delta`、`message.completed`、`run.warning/run.error` 和 `run.end`,不会转发 LangGraph 内部推理、服务器路径、标题中间件或跟踪 metadata。
|
||
|
||
调试终端可追加 `--output text`。只有排查协议问题且输出位置受控时才使用 `--output raw-jsonl`;原始流可能包含内部推理和服务器运行信息,不得直接转发给最终用户或写入普通业务日志。
|
||
|
||
`conversation-id` 和 `external-subject-id` 应使用稳定、不含姓名或证件信息的内部 ID。上游有消息 ID 时务必传 `--message-id`;同一个 ID 会生成同一个幂等键,便于安全重发。
|
||
|
||
## 6. 非流式 Run
|
||
|
||
```bash
|
||
.venv/bin/python -m agent_integration send \
|
||
--conversation-id "crm-conversation-001" \
|
||
--message-id "crm-message-002" \
|
||
--message "执行一个非流式任务" \
|
||
--poll
|
||
```
|
||
|
||
也可以单独查询或取消:
|
||
|
||
```bash
|
||
.venv/bin/python -m agent_integration get-run \
|
||
--conversation-id "crm-conversation-001" \
|
||
--run-id "run_xxx"
|
||
|
||
.venv/bin/python -m agent_integration cancel-run \
|
||
--conversation-id "crm-conversation-001" \
|
||
--run-id "run_xxx"
|
||
```
|
||
|
||
同一 Session 已有活跃 Run 时,服务可能返回 HTTP 409。CLI 会输出 `active_run_conflict: true`;调用方应等待、查询或取消旧 Run,不要盲目换 Session。
|
||
|
||
当前真实服务的非流式 Run 可以正常从 `running` 变为 `success`,但查询结果中的 `final_content` 仍可能为 `null`。此时 CLI 会输出 `run_result_unavailable` warning;Run 本身成功,退出码仍为0。需要取得答案时优先使用流式接口,或配置服务端 webhook。
|
||
|
||
真实服务可能在流中已经给出可见答案后仍发送 `open_agent_final_content_missing`,同时 Run 查询显示 `success` 但 `final_content=null`。接入层会在确有可见内容时把它降级为 `run.warning`;没有可见内容时仍按 `run.error` 和非零退出码处理。
|
||
|
||
## 7. 会话映射维护
|
||
|
||
首次发送消息会自动创建 Session。也可显式创建、查看或遗忘本地映射:
|
||
|
||
```bash
|
||
.venv/bin/python -m agent_integration ensure-session \
|
||
--conversation-id "crm-conversation-001"
|
||
|
||
.venv/bin/python -m agent_integration show-session \
|
||
--conversation-id "crm-conversation-001"
|
||
|
||
.venv/bin/python -m agent_integration forget-session \
|
||
--conversation-id "crm-conversation-001"
|
||
```
|
||
|
||
只有确认远端 Session 已失效或绑定错误时才应遗忘映射。SQLite 文件属于运行状态,已被 `.gitignore` 排除。
|
||
|
||
默认 SQLite 适合本地开发或单实例服务。不同环境、不同外部应用应使用不同的 `DEERFLOW_SESSION_DB`。多实例部署应实现 `SessionStore` 协议,把映射迁移到共享数据库;Agent 客户端和 `OpenAgentService` 无需因此改写。
|
||
|
||
## 8. Python 调用
|
||
|
||
```python
|
||
from agent_integration import AgentConfig, OpenAgentAPIClient, OpenAgentService, SQLiteSessionStore
|
||
|
||
config = AgentConfig.from_env()
|
||
|
||
with SQLiteSessionStore(config.session_db) as store:
|
||
with OpenAgentAPIClient(
|
||
base_url=config.base_url,
|
||
api_key=config.api_key,
|
||
auth_mode=config.auth_mode,
|
||
timeout=config.timeout_seconds,
|
||
connect_timeout=config.connect_timeout_seconds,
|
||
) as client:
|
||
service = OpenAgentService(client, store)
|
||
for event in service.stream_message(
|
||
"crm-conversation-001",
|
||
"你好",
|
||
message_id="crm-message-001",
|
||
metadata={"source": "crm"},
|
||
):
|
||
print(event.to_dict())
|
||
```
|
||
|
||
## 9. 文件链路与结果回写
|
||
|
||
当前 Open API 契约没有附件上传或文件登记接口。远端 Agent 无法访问调用机上的 `/absolute/input.xml`,所以不能把本地路径写进消息后假定 Agent 能读取。
|
||
|
||
当前已实现 `arr_processing` 的 job/run 关联、有界重试、直接 OSS 输入描述、runtime 结果发布、独立 HMAC 签名、OSS 输出重取、ARR 独立复验和 PostgreSQL 原子落库。输入 message 符合 `arr_opera_daily_program_input.schema.json`:只含 bucket、endpoint、精确 object key、哈希、字节数与任务 ID,不含 OSS AccessKey、XML 正文、签名 URL 或本机路径。`fetch_oss_file` 的平台 credential provider 独立持有读权限。
|
||
|
||
结果不从 `final_content`、`present_files` 或 Agent 本地路径取回。受信 runtime adapter 把产物发布到私有 OSS 交换前缀,然后签名回调 ARR;ARR 从 OSS 重新下载并复验后才入库。回写接口、状态码、ID 对应和部署变量见 `AGENT_WRITEBACK_CONTRACT.md`;实现边界见 `arr_processing/README.md`。
|
||
|
||
## 10. 测试
|
||
|
||
```bash
|
||
.venv/bin/python -m unittest discover -s tests -p 'test_*.py' -v
|
||
```
|
||
|
||
Agent API 测试使用 `httpx.MockTransport`,不会访问真实服务。配置新密钥后,真实联调应先用虚构会话和无隐私测试消息验证 scopes、SSE 事件类型及 409 行为。
|
||
|
||
## 11. 当前真实联调状态
|
||
|
||
2026-07-27 已使用无个人信息的临时会话完成真实验证:
|
||
|
||
- Bearer 鉴权通过;
|
||
- Session 创建与复用通过;
|
||
- SSE 流式消息通过,并验证公开事件过滤;
|
||
- 非流式 Run 提交与状态查询通过;
|
||
- Run 取消通过,状态从 `running` 经 `cancelling` 进入 `interrupted`。
|
||
|
||
联调密钥未写入项目文件或 SQLite,测试本地状态已清理。当前仍存在服务端 `final_content=null` 聚合问题,处理原则见第6节。
|
||
|
||
2026-07-28 已完成结果回写开发:机器入口为 `POST /api/integrations/super-agent/results`,回调会验签、核对 job/attempt/remote run、从 OSS 重取并校验工件、独立重放业务规则,然后在 PostgreSQL 事务中写入 ingestion/finance 并最后切换 current version。远程测试库已通过合成 delivery 的幂等重放验证。
|
||
|
||
这仍不等于线上竖切已经接通。只有 Agent Profile 开启 Open API 并发布、实际 OSS/RAM、独立 HMAC、公网 HTTPS callback URL 和 runtime writeback hook 均注入,`GET /api/health` 返回 `processing_ready=true` 与 `agent_writeback_ready=true`,并成功提交一笔无隐私测试任务后,才可宣告 Super Agent 结果可实时回传落库。
|