# 把提供方已有的报价 Agent 接给同事：合成资料 starter

这里接入的是提供方已经维护的 **Claude Code 项目**：保留该项目的目录、报价说明和经过审阅的 MCP 配置，在原机器启动真实 Claude Code。不是把另一平台的聊天记录导出，也不是用一个新报价函数替代原 Agent。

当前附件能检查启动路径；没有运行真实模型，也没有完成独立同事授权验收。跟进本示例的 Agent 不得自动安装软件、登录、调用模型、注册或授权。先检查文件和本地测试，只有用户明确同意后才执行对应步骤。

## 提供方先准备什么

提供方选择原项目中**双方已共同批准的合成资料环境**，例如 TEST-TEAM-11 的虚构客户需求、测试价目表、已有的例外规则。目录中必须已有一份审阅过的 `CLAUDE.md`。应能解释：为什么选择某个产品、数量如何影响单价、哪些例外要人工确认。不要仅为通过测试放一条“回答成功”。这份 starter 不附加凭空编造的业务规则。

已有项目如果能访问真实客户或生产写入工具，不适合直接注册。先由提供方准备同一套工作方法的合成测试范围：审阅项目/用户/组织设置、hooks、skills、自动记忆以及每个 MCP 服务的资料和工具权限。需要调用其他进程的 hooks 也在审阅范围内。工作目录不是 OS 沙箱，`dontAsk` 也不会把已有允许规则撤销。不要以提示词替代数据隔离。

将这三个下载文件保存在提供机器的一个固定目录：

- `agent_entry.py`：可审阅的启动器，不修改现有项目。
- `provider.example.json`：在本机复制为 `provider.json`，用编辑器填写。
- `prompt.txt`：双方同意后再用于真实模型测试。

`provider.json` 的字段全部由**提供方**填写；不是让同事填写，也不从请求里读取：

| 字段 | 填什么 |
| --- | --- |
| `claude_binary` | 已安装 Claude Code 可执行文件的绝对路径，可用 `command -v claude` 查看；不能填 shell 命令或别名 |
| `workspace` | 上述现有合成测试项目的绝对目录，包含 `CLAUDE.md` |
| `mcp_config` | 审阅后的 MCP JSON 绝对路径，必须有 `mcpServers` 对象；不用 MCP 时显式提供 `{"mcpServers": {}}` 文件 |
| `model` | 提供方账号实际可用、同意承担费用的模型标识；不要照抄占位符 |
| `reviewed_for_shared_synthetic_data` | 完成前述审阅后由提供方改为 `true`；这是人为确认，不是程序证明数据安全 |

配置文件不放模型密钥。Runtime 进程的 OS 用户必须已经有获准使用的 Claude 认证。启动器继承该进程环境，不读取 `.env`，不把密钥加入 CLI 参数，不改变 HOME。MCP 文件与现有项目配置由提供方保管，不上传到公共附件或发给同事。

## 先检查，再注册提供端

以下 `/absolute/...` 全部替换成提供方刚确定的真实路径。Python 也用 `command -v python3` 得到可执行文件的绝对路径，避免 daemon 的 PATH 与终端不同。

```bash
/absolute/path/to/python3 /absolute/path/to/teammate-agent/agent_entry.py \
  --config /absolute/path/to/private/provider.json --check

easynet agent add quotation-agent --type external \
  --command /absolute/path/to/python3 \
  --arg /absolute/path/to/teammate-agent/agent_entry.py \
  --arg=--config \
  --arg /absolute/path/to/private/provider.json \
  --label "Shared synthetic quotation agent"

easynet agent list
```

`--check` 只检查文件、JSON 和确认字段，不认证、不连接 MCP、不启动 Claude。配置缺失、路径错误或未确认时失败。`agent add` 则是实际 Runtime 写操作，要求提供机器已有兼容、已配对的 EasyNet Runtime；它发布 chat 入口，不等于完成同事授权。

启动器固定只开放 Read/Glob/Grep 这些内建工具，并显式加载所选 MCP 配置；原项目若依赖 Bash、写文件等操作，此 starter 会改变其可用工具，不能宣称完全等同原交互运行。不要为了跑通改成权限绕过。MCP 工具不受内建 `--tools` 列表限制，必须在所选服务和 Claude 有效权限中审定。缺少预先允许的工具调用由 `dontAsk` 拒绝；本例不自动增加 allowedTools。

用户同意模型费用后，提供方可执行下面的本地业务检查。此时会真正调用模型，最多 8 个模型 turn；这不是费用或耗时硬上限。EasyNet 的调用 deadline 另行管理，不应承诺上游费用已取消。

```bash
easynet agent send quotation-agent \
  '仅使用双方已批准的合成客户 TEST-TEAM-11 和测试报价规则生成草稿，列出依据和待确认项，不发送或提交。' \
  --timeout 180
```

人工核对结果是否引用正确的现有规则，而不只判断有没有输出。缺资料和权限拒绝也应清楚返回。启动器不传 `--resume` 或 `--continue`，并关闭 Claude 会话持久化，因此原会话不会自动继承，多个同事也不会自动共用聊天历史。EasyNet 自己的调用记录、Claude 自动记忆/其他现有配置、MCP 服务日志和上游留存是不同的范围，不能把这个 flag 当作“完全不存数据”。

## 同事端先确认身份，再发现实际入口

同事必须使用自己获准的 Runtime 调用主体。当前两 Runtime harness 的同用户测试不是此步骤的授权证明。部署负责人要先说明如何给这个独立主体开放 chat 入口，并验收允许、拒绝、撤销和提供方离线；没有这套授权操作时停在这里，不借用提供方凭据继续。

提供方交给同事的是其 Runtime 实际公布的 Device URA，不是机器昵称。同事在自己终端设置 `PROVIDER_DEVICE_URA` 后读取目录：

```bash
easynet ability list --node "$PROVIDER_DEVICE_URA" --format json
```

在输出中找到提供方确认的 `quotation-agent.chat`，确认归属和 RPC 模式，复制其真实 `ability_ura` 为 `CHAT_ABILITY_URA`，并保留 RPC `descriptor_ref` 为 `CHAT_DESCRIPTOR_REF`。不要只凭同名条目挑第一个，不要拼接 guessed realm、版本或 hash。再查看完整描述：

```bash
easynet ability show "$CHAT_ABILITY_URA" \
  --node "$PROVIDER_DEVICE_URA" --format json
```

核对上一步的 descriptor 与这里的版本/hash/admission action 对应，检查实际输入 schema；将这里真实的 `owner_ura` 记为 `CHAT_OWNER_URA`。如果安装版本没有公开 descriptor ref，先让维护者提供同一当前描述的 canonical ref，不自行拼造，也不绕过 descriptor 检查。

当前源码 harness 用 `prompt` 和 `skills.mode=none` 发起这类请求。只有实际 schema 同样支持时才照下例执行。每次新请求由同事生成新的 nonce；重试未知结果前先查原调用，不自动重跑可能计费的生成。

```bash
FRESH_NONCE_HEX="$(python3 -c 'import secrets; print(secrets.token_hex(16))')"
easynet ability invoke "$CHAT_DESCRIPTOR_REF" \
  --node "$PROVIDER_DEVICE_URA" \
  --subject "$CHAT_OWNER_URA" \
  --nonce-hex "$FRESH_NONCE_HEX" --causal-root \
  --args '{"prompt":"仅使用共同批准的合成客户 TEST-TEAM-11 和测试规则生成报价草稿，列出依据，不发送或提交。","skills":{"mode":"none"}}' \
  --raw
```

`CHAT_OWNER_URA` 是被调用的 Agent，不是把同事伪装成提供方的 caller。入口接受请求后，external 驱动只将 prompt 送给 Claude，不自动把同事的业务身份传播到 MCP；工具仍使用提供方已配置的账号。这就是本例只处理共同批准的合成资料的原因。不要把“我是某客户负责人”这样的提示词当作业务鉴权。

提供方可查看真实调用记录：

```bash
easynet invocation list --ability-ura "$CHAT_ABILITY_URA" --format json
```

记录执行结果不等于草稿正确，草稿正确也不等于独立主体授权完备。给最终交付记录分别写清：本地真实模型结果、实际 caller 身份、远端调用记录、拒绝/撤销/离线结果；没运行的项保持未验证。

## 本地测试与源码依据

```bash
python3 -m unittest discover -s Frontend/public/examples/teammate-agent -p 'test_*.py' -v
```

测试自己创建临时 fake 可执行文件，验证 argv、cwd、stdin/stdout/stderr、非零退出及配置失败。fake 不是示例 Agent，不提供报价能力，不证明模型质量、MCP 权限或跨用户授权。测试不安装依赖、不调用 EasyNet 或模型，临时目录由测试回收。

当前源码定位：`EasyNet-Cli/src/daemon/execution/mission/drivers/external.rs`（真实子进程输入输出）；`process_runner.rs`（环境/工作目录/退出）；`cli/commands/agent/mod.rs`（add 参数）；`tools/scripts/docker-two-node-easyremote-cli-e2e.sh:945–978`（目录、描述与远端 chat 调用顺序）。不要以 `ability teach` 的 descriptor 转移代替未验证的 chat 入口授权。

2026-09-07 核对的官方文档：[CLI reference](https://code.claude.com/docs/en/cli-reference)、[Headless](https://code.claude.com/docs/en/headless)、[Permission modes](https://code.claude.com/docs/en/permission-modes)。启动器使用 print/text、dontAsk、内建工具列表、显式 MCP 配置与会话选项；部署前记录实际安装版本并确认支持这些参数。未知 flag 应报错，不做静默兼容回退。
