# 跨 Agent 工作流

使用现有 SDK 和 MCP contract，在指定 Agent 之间传递决策、实现修复和范围受限的上下文。

- Canonical: https://docs.xmemo.dev/zh/docs/operations/cross-agent-workflow
- Locale: zh-CN
- Content-Locale: zh-CN
- Canonical-Content-Digest: 601017a1cc889872d5526e3d5cb8ee1ac73c89512eb78d284d88811d2349b611
- Edition-Digest: e7fe006709bc2a840cbe88dae8a835635fd849dd916b46dc41c39eec227ba4e1
- Source-Revision: sha256:9e1f7f01cc46df74b247f9cecea3b932f1b046cd1751624acdfd046a7b7fedd2

## 一次交接，两个现有 surface

跨 Agent 交接不会新增 API。写入 Agent 可以使用 TypeScript SDK workflow helpers taskStart、recordDecision、recordBugFix 和 taskEnd；接收 Agent 可以使用 MCP tool recall_context 或 SDK method recallContext。下面的 Agent 名称是现有请求携带的 attribution 值，而 API key 或 OAuth grant 以及 memory:read / memory:write scope 仍然负责授权访问。

- Claude 通过已连接的 adapter 或 SDK client 写入决策。
- Codex 召回范围受限的上下文，记录修复并结束任务。
- 当已认证 owner 和请求的 scope 允许时，Claude 再次调用 recall_context 即可收到共享的决策和修复。

## 交接时间线

生命周期顺序是 taskStart → recall_context → recordDecision → recordBugFix → taskEnd → 另一个 Agent 的 recall_context。taskStart 和 taskEnd 默认使用 status 为 started 和 completed 的 working memory type；recordDecision 和 recordBugFix 默认使用 semantic memory。每个 SDK capture helper 都会解析为 CaptureResult，因此 caller 必须检查 shouldCapture，不能直接假设 memory 已写入。

```text
1. Claude: client.taskStart(...)
2. Codex: recall_context({ query, max_items, max_tokens })
3. Claude: client.recordDecision(...)
4. Codex: client.recordBugFix(...)
5. Codex: client.taskEnd(...)
6. Claude: recall_context({ query, max_items, max_tokens })
```

## 使用 SDK 写入决策

SDK method 使用现有的 AgentWorkflowOptions fields。交接期间保持 source、agent identity、sessionId、taskId 和 scope 稳定；不要把 API key 放进 options 或记录的 content。

```ts
const scope = 'memory-os';
const sessionId = 'handoff-session-1';
const taskId = 'handoff-1';

await claude.taskStart('Review the deployment adapter', {
  source: 'claude', sessionId, taskId, scope,
});
const decision = await claude.recordDecision(
  'Use the hosted network MCP transport for remote agents.',
  { source: 'claude', sessionId, taskId, scope },
);
if (!decision.shouldCapture) {
  throw new Error('Decision was not captured: ' + decision.reason);
}
```

## 召回、修复并结束任务

MCP recall_context 是需要 memory:read 的有界多 memory context pack。SDK 的 recallContext method 会调用 POST /v1/recall/context 并返回结构化 JSON object。Codex 可以使用任一 surface 读取，然后使用现有 SDK helpers 完成 bug fix 和 task close。

```ts
const context = await codex.recallContext(
  'deployment adapter decision and current bug',
  { scope, maxItems: 6, maxTokens: 1200, preferWorking: true },
);

await codex.recordBugFix(
  'Fixed streamable-http token identity fallback.',
  { source: 'codex', sessionId, taskId, scope },
);
await codex.taskEnd(
  'Deployment adapter fix completed for handoff.',
  { source: 'codex', sessionId, taskId, scope },
);
console.log(context.version, context.items);
```

## 等价的 MCP read

在公共 MCP surface 上，使用现有的下划线命名 tool 及其 public snake_case arguments：query、max_items 和 max_tokens。连接的 profile 提供已认证 owner 和 agent identity；server 会用 agent boundary object 标注返回的 items。max_items 和 max_tokens 会限制整个 context pack。该 tool 返回以 ### XMemo Context 开头的 public text response。

```text
recall_context({
  query: "deployment adapter decision and current bug",
  max_items: 6,
  max_tokens: 1200
})
```

## 不要只读 content，还要读 boundary fields

Recall result 会带有现有的 agent boundary object 注释。如果 Codex 读取 agent_id=claude 写入的 memory，relation 和 ownership 就是 other_agent；如果逻辑 agent_id 相同但 installation hash 不同，relation 就是 same_agent_other_instance。agent_id 与 agent_instance_id_hash 都匹配时才是 self。boundary_authority 保持 attribution_only；只有 identity source 是 token-bound 时 current_agent_trust 才是 token_bound，否则是 client_asserted。

```json
{
  "relation": "other_agent",
  "ownership": "other_agent",
  "current_agent_id": "codex",
  "current_agent_trust": "client_asserted",
  "boundary_authority": "attribution_only",
  "memory_agent_id": "claude",
  "explanation": "memory agent_id differs from this caller"
}
```

## 使用相同 scope 和有界 query 继续

Claude 后续的 recall 使用同一已认证 account 和 scope，但使用自己的 agent_id 与 agent_instance_id 值。只有 caller 的 credential、memory:read scope、owner boundary 和请求的 retrieval filters 都允许时，memory 才会共享；Agent boundary label 是 attribution 证据，不是绕过授权的手段。

```text
recall_context({
  query: "deployment adapter decision, Codex fix, and handoff status",
  max_items: 6,
  max_tokens: 1200
})
# Inspect the returned context and boundary summary before continuing.
```

