Ch10. Subagents, Workflows, Remote Agents
Eve 0.82.0의 task 기반 위임, root 복사와 specialist 격리, 구조화 출력, workflow와 원격 인증을 설계합니다.
핵심 요약
- 모델이 호출한 subagent는 taskId가 있는 접수 정보를 먼저 반환하고, child의 답변은 나중에 task 결과로 도착합니다.
- built-in agent는 root 전용이며 sandbox를 공유합니다. declared subagent는 자체 도구·지시·sandbox를 가집니다.
- 결과에 의존하는 후속 작업은 workflow에서 명시적으로 기다리고, 구조화 schema는 child의 send 호출에 둡니다.
위임 방식과 격리
| 방식 | 실행 계약 | 선택 기준 |
|---|---|---|
root의 built-in agent | root 복사, 공유 sandbox, 새 history/state | 같은 작업 환경에서 범위를 나눈 병렬 작업 |
| declared local subagent | 자체 authored capabilities·sandbox | 전문 역할과 권한 축소 |
| remote agent | 별도 배포, outbound auth | 팀·서비스의 운영 책임 분리 |
root 복사에는 root-only agent 도구가 다시 주어지지 않습니다. 서로 다른 child가 같은 파일을 덮어쓰지 않도록 write 범위를 나눕니다. child는 parent 대화 전체를 자동으로 받지 않으므로 message에 필요한 근거와 범위를 전달합니다.
작업 접수와 완료를 구분한다
모델이 호출하는 local/remote subagent는 task로 동작합니다. 접수 직후 parent가 계속 작업할 수 있으며, child가 작업 중인 동안 parent turn은 끝나지 않습니다. 같은 taskId로 후속 메시지를 보낼 수 있고 child 실패는 task 실패로 처리합니다.
interface DelegationInput {
message: string;
taskId?: string;
}의존 작업은 접수 성공만 보고 실행하지 않습니다. 검토 결과 이후 publish처럼 순서가 필요하면 하나의 authored workflow에서 child 결과를 기다린 뒤 다음 단계를 수행합니다. eve__task_wait는 기다리기, eve__task_cancel은 현재 작업 취소이며 두 동작을 구분합니다.
Declared subagent
import { defineAgent } from "eve";
export default defineAgent({
description: "Review proposed operations for risk and missing approvals.",
model: "anthropic/claude-opus-5.5",
tool: false,
});description은 필수입니다. tool: false는 parent 모델의 직접 도구 노출을 숨기지만 workflow의 ctx.agent() 호출을 막지 않습니다. 선언된 child의 instructions·tools·connections·skills·sandbox를 별도로 검토합니다.
구조화 결과를 기다리는 workflow
import { defineWorkflowTool } from "eve/tools";
import { z } from "zod";
export default defineWorkflowTool({
description: "Obtain a structured risk review of a proposed plan.",
inputSchema: z.object({ plan: z.string() }),
async execute({ plan }, ctx) {
"use workflow";
const reviewer = ctx.agent("reviewer");
const response = await reviewer.send(plan, {
outputSchema: z.object({
risk: z.enum(["low", "medium", "high"]),
findings: z.array(z.string()),
}),
signal: ctx.abortSignal,
});
const result = await response.result();
if (!result.data) throw new Error("Missing structured review.");
return result.data;
},
});ctx.agent와 ctx.ask는 workflow body의 기능입니다. 일반 defineTool이나 channel/schedule handler에 같은 API가 있다고 가정하지 않습니다. 부작용·시간·난수·환경 변수 접근은 "use step" helper로 분리합니다. 고위험 후속 실행은 리뷰 결과 외에 실행 시점 인가와 승인도 검사합니다.
모델이 만드는 workflow
예전 ExperimentalWorkflow export 대신 다음 factory를 사용합니다.
import { workflow } from "eve/tools/workflow";
export default workflow({ maxSubagents: 20 });모델이 제공한 프로그램의 host 기능은 ctx.agent(name, { message, outputSchema? })로 제한됩니다. 일반 도구·credential·임의 import에 직접 접근하지 않습니다. 각 호출은 새 child session을 만들며 반환값은 JSON 직렬화 가능해야 합니다. maxSubagents는 기본 100, 허용 범위 1–128입니다. Promise.all fan-out은 지원하지만 Promise.race로 일부 child만 끝났을 때 즉시 재개된다고 가정하지 않습니다. 이 tool도 task로 실행되므로 결과 도착을 기다립니다.
Remote agents와 신원
import { defineRemoteAgent } from "eve";
import { vercelOidc } from "eve/agents/auth";
export default defineRemoteAgent({
url: "https://weather-agent.example.com",
description: "Answers weather and forecast questions.",
auth: vercelOidc(),
});outbound 인증과 수신 측 검증을 함께 구성합니다. forwardPrincipal은 기본 false이며, 사용자 신원 전달은 수신 서비스가 호출자를 신뢰하도록 명시적으로 구성할 때만 사용합니다. 배포 인증이 사용자·tenant 인가를 자동 해결하지 않습니다. remote의 model·limits·보존 정책도 해당 배포 책임입니다.
릴리스 회귀 기준
| 검증 | 통과 조건 |
|---|---|
| root-copy 재귀 | child가 root-only agent 도구로 다시 복제하지 못함 |
| 공유 파일 | 병렬 child의 쓰기 범위가 충돌하지 않음 |
| 접수/완료 | receipt를 실제 성공 결과로 표시하지 않음 |
| schema | 해당 turn에서 검증되고 누락/오류 결과를 처리 |
| 취소·사용량 | parent/child 취소와 limit 집계 동작 확인 |
| 원격 신원 | 거부 토큰·잘못된 tenant·principal forwarding 정책 확인 |