上一篇:《Vercel Eve 接入自定义 AI Provider》里我们把 SpringForAll 内容运营助手的模型入口改成了两条路径默认走 Vercel AI Gateway配置EVE_MODEL_BASE_URL后切换到自定义 OpenAI-Compatible Provider。模型入口稳定之后就可以开始做内容团队的工作流了。这一篇的目标很明确把前两篇搭好的 Agent 升级成一个内容创作团队。我们会用 skills 沉淀选题、写作、审核流程再用 subagents 拆出研究员、撰稿人、审核人三个角色。root agent 只负责像内容主编一样分派任务、整合结果并交给人确认。项目初始化和自定义 Provider 接入不再重复展开直接参考前两篇文章即可。为什么需要 skill 和 subagent前两篇里的 Agent 本质上还是聊天助手。它知道自己是 SpringForAll 内容运营助手但选题、写作、审核和协作规则都挤在同一个上下文里选题应该怎么判断写作应该用什么结构审稿应该检查哪些风险谁负责研究谁负责写作谁负责审核某一步失败时应该重试还是交给人判断。如果全部塞进agent/instructions.md它很快会变成难维护的长期提示词也会让每次调用都带上不需要的流程细节。所以这里按职责拆instructions 写稳定身份、长期边界和团队协作规则skills 写可按需加载的工作流subagents 写角色边界和各自独立上下文。放到内容团队里就是topic_planning: 选题流程article_writing: 写作流程review_checklist: 审核流程researcher: 研究员负责研究和选题writer: 撰稿人负责大纲和草稿reviewer: 审核人负责审校和发布前风险检查root agent: 内容主编负责任务拆解和结果整合。本节样例结构最终目录如下example/03-content-team/ package.json tsconfig.json .env.example scripts/ check-custom-gateway.mjs agent/ agent.ts instructions.md lib/ model.ts skills/ topic_planning.md article_writing.md review_checklist.md subagents/ researcher/ agent.ts instructions.md skills/ topic_planning.md writer/ agent.ts instructions.md skills/ article_writing.md reviewer/ agent.ts instructions.md skills/ review_checklist.md channels/ eve.ts和第 02 篇相比主要增加了agent/skills/: root agent 可加载的三份流程说明agent/subagents/: 三个专职 subagentsagent/subagents/*/skills/: subagent 自己可加载的 skill。注意一个 Eve 设计细节declared subagent 不会继承 root agent 的 authored slots。root agent 有agent/skills/topic_planning.md不代表researcher自动拥有这个 skill。每个 declared subagent 都是独立的 agent root只发现自己目录下的 instructions、skills、tools、connections、sandbox 等内容。所以如果希望researcher、writer、reviewer自己加载并遵循某个 skill就要在它们各自的skills/目录下放一份。复用第 02 篇的模型配置先把模型入口放到公共文件里import{createOpenAICompatible}fromai-sdk/openai-compatible;constdefaultGatewayModelIdminimax/minimax-m3;constcustomBaseURLprocess.env.EVE_MODEL_BASE_URL;constusesCustomGatewaycustomBaseURL!undefinedcustomBaseURL.trim()!;完整文件在agent/lib/model.ts它导出两个值exportconstmodelusesCustomGateway?createOpenAICompatible({name:custom,baseURL:customBaseURL,apiKey:process.env.EVE_MODEL_API_KEY,includeUsage:true,}).chatModel(requireCustomModelId()):(process.env.EVE_GATEWAY_MODEL_ID??defaultGatewayModelId);exportconstmodelContextWindowTokensparseContextWindowTokens(process.env.EVE_MODEL_CONTEXT_WINDOW_TOKENS);root agent 和三个 subagents 都复用这份配置import{defineAgent}fromeve;import{model,modelContextWindowTokens}from#lib/model.js;exportdefaultdefineAgent({model,modelContextWindowTokens,});这样可以把重点留给 skills 和 subagents避免每个 subagent 都复制 Provider 配置。当然实际应用不同 subagent 需要配置不同模型的话 也可以为他们配置各自的 Provider 和 Model本篇不做展开读者也可以自己尝试。编写 root agent内容主编root agent 的 instructions 升级为内容主编# SpringForAll Content Editor You are the managing editor for the SpringForAll community content team. Your mission is to help Java, Spring, Spring AI, Spring Cloud, JVM, backend engineering, and developer tooling creators turn rough ideas into useful Chinese technical articles.声明团队协作规则Use the content team as three specialist roles: - Use the researcher subagent when the task needs topic discovery, trend analysis, source collection, or uncertainty checks. - Use the writer subagent when the task needs an outline, first draft, rewrite, title options, or article packaging. - Use the reviewer subagent when the task needs editorial review, technical risk checks, source checks, or publish-readiness feedback.再声明 skill 加载规则Load the relevant skill before delegating or doing the work yourself: - topic_planning for topic discovery, audience fit, source requirements, and topic scoring. - article_writing for brief-to-draft writing, article structure, examples, and SpringForAll voice. - review_checklist for final review, risk classification, missing evidence, and revision requests.root agent 不负责亲自完成所有事只负责判断当前任务属于哪一步应该加载哪个 skill应该把什么上下文交给哪个 subagentsubagent 返回后如何整合哪些内容还需要人确认。编写第一个 skill选题流程agent/skills/topic_planning.md是 root agent 可加载的选题流程。skill 文件的关键是 frontmatter 里的description--- description: Use when planning SpringForAll article topics, scoring candidate ideas, or turning a vague content direction into a research brief. ---Eve 会把description暴露给模型。任务匹配时模型再通过load_skill把完整 skill 加进上下文。选题 skill 里最重要的是避免“内置静态选题列表”Do not rely on a static built-in topic list. For each topic, identify the real source categories that should be checked before writing: - Spring official blog, reference docs, release notes, and GitHub repositories. - Spring AI, Spring Boot, Spring Cloud, Spring Security, and Spring Framework updates. - Java, JVM, build tools, observability, cloud-native, and backend architecture signals. - Community questions, migration pain points, production incidents, and developer workflow changes.内容运营 Agent 最容易凭空生成“看起来像热点”的标题。这里还没有接入真实搜索 tool也没有接历史内容库所以 skill 必须要求说明应该检查哪些真实来源如果无法访问实时来源要把待人工核验项列出来不要把猜测包装成事实。另外两个 skills 分别负责article_writing.md: 把选题简报变成标题、摘要、大纲、草稿review_checklist.md: 检查受众、事实、证据、结构、可发布风险。拆出 researcher subagent我们先拆出研究员 subagent也就是目录里的researcher。一个 declared subagent 最少需要agent/subagents/researcher/ agent.ts instructions.mdagent.ts必须有description。父 Agent 会根据它判断什么时候调用 subagentimport{defineAgent}fromeve;import{model,modelContextWindowTokens}from#lib/model.js;exportdefaultdefineAgent({description:Research SpringForAll content topics, collect source plans, compare candidate angles, and return evidence-aware topic briefs.,model,modelContextWindowTokens,});instructions.md则写researcher自己的身份和输出格式# SpringForAll Researcher You are the research subagent for SpringForAll content operations. Your job is to turn vague content directions into evidence-aware topic briefs. Load and follow the topic_planning skill before returning your result.这里说的是researcher自己要加载topic_planning。因为 declared subagent 不继承 root agent 的 skills所以还要放一份agent/subagents/researcher/skills/topic_planning.md这样researcher被调用时才能看到这个 skill。撰稿人writer和审核人reviewer也是同样结构agent/subagents/writer/ agent.ts instructions.md skills/article_writing.md agent/subagents/reviewer/ agent.ts instructions.md skills/review_checklist.md为什么这里不用 outputSchemaEve 的 subagent tool 支持outputSchema理论上可以让researcher返回严格 JSONoutputSchema:z.object({candidates:z.array(...),recommended_topic:z.string(),open_questions:z.array(z.string()),});但这个样例没有默认使用outputSchema。原因很直接从第 02 篇开始样例支持自定义 OpenAI-Compatible Provider而不同 gateway、不同模型对严格结构化输出的支持并不一致。实际测试时容易遇到could not produce a result matching the requested schema这通常不是 Eve 没发现 subagent而是模型没有产出符合结构要求的结果。为了让读者复制后更容易跑通这里采用更稳的方式不在 subagent 的agent.ts里配置outputSchema不让 root agent 调用 subagent 时传outputSchema用固定 Markdown 标题约束结果结构。例如researcher的输出要求是Use exactly these headings: ## Candidate Topics For each candidate, include title, reader, core question, angle, source plan, confidence, risk, and next step. ## Recommended Topic Name the strongest topic and explain why. ## Open Questions List unresolved questions for the editor.这比严格 JSON 弱但对教程更稳。等后面要做评测evals或自动处理结果时再评估是否引入结构化输出。处理 subagent 失败subagent 失败时不要让 root agent 悄悄把工作自己做完。否则界面上看似流程完成实际上researcher或reviewer并没有参与。所以 root agent 的 instructions 里加了这条规则If a subagent fails, returns an empty result, or returns an unusable result, do not silently complete that specialists work yourself. Report the failed step, summarize what context was sent, and ask the user whether to retry with a smaller request.这条规则是为了让流程可观察。教程阶段宁愿明确看到“researcher 这一步失败了是否缩小任务重试”也不要得到一份看似完整、但不知道谁做了什么的结果。验证 Eve 是否发现了 skills 和 subagents进入样例目录cdexample/03-content-team安装依赖并配置环境变量npminstallcp.env.example .env.local如果使用 Vercel AI GatewayEVE_GATEWAY_MODEL_IDminimax/minimax-m3AI_GATEWAY_API_KEY你的_Vercel_AI_Gateway_Key如果使用自定义 OpenAI-Compatible ProviderEVE_MODEL_BASE_URLhttps://api.example.com/v1EVE_MODEL_API_KEYyour-api-keyEVE_MODEL_IDyour-model-idEVE_MODEL_CONTEXT_WINDOW_TOKENS128000可以先检查 gatewaynpmrun check:gateway再看 Eve 是否发现了 root agent 的 skillsnpmexec-- eve info预期能看到Skills 3 skills普通eve info不一定直接展开 subagent 详情。要确认 subagents 和它们自己的 skills 都被编译进去可以看编译后的 manifestrgsubagents/(researcher|writer|reviewer)|skills/(topic_planning|article_writing|review_checklist).eve/compile/compiled-agent-manifest.json最后跑构建npmrun build如果本机默认 Node 不是 24可以临时切换PATH/Users/zhaiyongchao/.nvm/versions/node/v24.11.1/bin:$PATHnpmrun build运行完整内容流程启动 CLInpmrun dev然后发送请用完整内容团队流程为 SpringForAll 策划、写作并审核一篇文章。 方向Spring AI 在企业 Java 应用里的落地边界。 要求 1. 先用 topic_planning 做 3 个候选选题并请 researcher 给出来源计划和风险。 2. 选择最适合 SpringForAll 读者的一个选题请 writer 写出标题、摘要、大纲和文章草稿。 3. 请 reviewer 按 review_checklist 审核草稿给出 pass/revise/block 结论和必须人工核验的事实点。 4. 最后由你整合成一份包含选题简报、草稿、审核结论的中文结果。理想流程是root agent 先加载topic_planning调用researcher让它返回候选选题、来源计划和风险再加载article_writing调用writer让它写标题、摘要、大纲和草稿再加载review_checklist调用reviewer让它给出审核结论最后 root agent 统一整合成中文结果。这一版还没有接入真实搜索 tool所以researcher返回的来源计划只是“应该检查什么”不等于“已经检查过什么”。如果模型或 gateway 支持网页搜索web search也要把实际可用 tool、来源和核验结果讲清楚。小结这一篇构建了一个最小 SpringForAll 内容创作团队用 skills 拆出选题、写作和审核流程用 subagents 拆出研究员 researcher、撰稿人 writer、审核人 reviewer处理了 Eve declared subagent 不继承 root agent skills 的边界为了兼容自定义 OpenAI-Compatible gateway暂时用 Markdown 交付格式而不是默认使用严格outputSchema通过 CLI 验证选题、写作、审核完整流程。需要强调的是这个内容团队的拆法主要是为了尝试和说明 Eve 的 skills、subagents、Provider 配置和协作边界并不代表内容团队的最佳实践。真实项目里读者完全可以根据自己的业务场景重新设计适合自己的 Agent 团队、角色分工和交付流程。本篇对应的样例工程在这里example/03-content-team如果你在运行这个 example 时让 Agent 写文件会发现结果已经出现在/workspace下面。这个/workspace不是项目源码目录而是 Eve 默认提供的 sandbox 工作区。也就是说sandbox 其实从一开始就在工作只是我们还没有显式配置它。所以下一篇不再是“从零开启 sandbox”而是把这个默认机制讲清楚Eve 的文件类 tool 为什么默认写到/workspace哪些内容会被带进 sandbox哪些内容不会什么时候需要自己增加agent/sandbox/配置以及如何把 Agent 定义代码和运行产物的边界讲清楚。