当前位置: 首页 > news >正文

用 Vercel Eve 的 Subagent 和 Skill 搭建 Agent Team

上一篇:《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/: 三个专职 subagents;
  • agent/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 等内容。

所以如果希望researcherwriterreviewer自己加载并遵循某个 skill,就要在它们各自的skills/目录下放一份。

复用第 02 篇的模型配置

先把模型入口放到公共文件里:

import{createOpenAICompatible}from"@ai-sdk/openai-compatible";constdefaultGatewayModelId="minimax/minimax-m3";constcustomBaseURL=process.env.EVE_MODEL_BASE_URL;constusesCustomGateway=customBaseURL!==undefined&&customBaseURL.trim()!=="";

完整文件在:

agent/lib/model.ts

它导出两个值:

exportconstmodel=usesCustomGateway?createOpenAICompatible({name:"custom",baseURL:customBaseURL,apiKey:process.env.EVE_MODEL_API_KEY,includeUsage:true,}).chatModel(requireCustomModelId()):(process.env.EVE_GATEWAY_MODEL_ID??defaultGatewayModelId);exportconstmodelContextWindowTokens=parseContextWindowTokens(process.env.EVE_MODEL_CONTEXT_WINDOW_TOKENS);

root agent 和三个 subagents 都复用这份配置:

import{defineAgent}from"eve";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;
  • 应该把什么上下文交给哪个 subagent;
  • subagent 返回后如何整合;
  • 哪些内容还需要人确认。

编写第一个 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.md

agent.ts必须有description。父 Agent 会根据它判断什么时候调用 subagent:

import{defineAgent}from"eve";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

为什么这里不用 outputSchema

Eve 的 subagent tool 支持outputSchema,理论上可以让researcher返回严格 JSON:

outputSchema: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 悄悄把工作自己做完。否则界面上看似流程完成,实际上researcherreviewer并没有参与。

所以 root agent 的 instructions 里加了这条规则:

If a subagent fails, returns an empty result, or returns an unusable result, do not silently complete that specialist's 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 Gateway:

EVE_GATEWAY_MODEL_ID=minimax/minimax-m3AI_GATEWAY_API_KEY=你的_Vercel_AI_Gateway_Key

如果使用自定义 OpenAI-Compatible Provider:

EVE_MODEL_BASE_URL=https://api.example.com/v1EVE_MODEL_API_KEY=your-api-keyEVE_MODEL_ID=your-model-idEVE_MODEL_CONTEXT_WINDOW_TOKENS=128000

可以先检查 gateway:

npmrun check:gateway

再看 Eve 是否发现了 root agent 的 skills:

npmexec-- eve info

预期能看到:

Skills 3 skills

普通eve info不一定直接展开 subagent 详情。要确认 subagents 和它们自己的 skills 都被编译进去,可以看编译后的 manifest:

rg"subagents/(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

运行完整内容流程

启动 CLI:

npmrun 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 定义代码和运行产物的边界讲清楚。

http://www.cnnetsun.cn/news/3001936.html

相关文章:

  • 客流增35%驻留延40%:贵州安顺古城美陈设计核心技巧-肆墨设计
  • 天津翻译机构 法语网站本地化清单
  • PVE Tools:Proxmox VE终极管理工具箱,让虚拟化管理变得简单高效
  • 2026年【江苏“信息与未来”编程思维】真题及题解(T2:快递无人机)
  • GitHub爆火Skill三巨头实测:选错直接让AI代码精神分裂
  • 遗传算法实战:编码策略、适应度设计与早熟诊断
  • NanaZip完整指南:为什么这款Windows压缩工具值得你立即尝试
  • 终极指南:如何在Windows 11 LTSC系统中轻松安装Microsoft Store应用商店
  • TestSprite 全自动化 AI Web 测试详解——从原理到测试报告完整实战指南
  • Boss直聘批量投递工具:3步让你每天多投50份简历
  • 权威测评:2026年不容错过的专业AI论文软件
  • 回归模型评估指标实战指南:从面试陷阱到工业级KPI诊断
  • 3分钟掌握:B站视频下载工具的核心技术与实战指南
  • 5分钟掌握跨平台资源下载工具:你的智能资源嗅探器终极指南
  • 为什么你的浏览器需要一个本地视频下载扩展?
  • EdgeRemover:Windows系统上彻底告别微软Edge的终极解决方案
  • 算法竞赛实战复盘:从读题策略到代码模板的系统性备赛方法
  • 基于Pytest+Requests+Allure的接口自动化测试框架实战指南
  • 多维聚合实战:维度建模、度量聚合与数据变形三步法
  • Claude语义压缩层蒸发:架构级黑箱化与可控性重构指南
  • 魔兽争霸3性能重生:如何用开源工具让经典游戏在现代硬件上焕发新生
  • KMS_VL_ALL_AIO:5分钟搞定Windows和Office永久激活终极方案
  • 从经典到粘性解:非一致椭圆方程Harnack不等式理论与数值实践
  • Prompt Engineering 与 Agent 工作流:从单次调用到自主决策的编排架构
  • 041、继承的正确打开方式:单继承、多重继承、Mixin 模式与钻石问题
  • AI应用安全部署:3步实现环境变量与密钥管理,告别硬编码风险
  • VMware桥接不上网?别重装!资深架构师压箱底的7个诊断命令清单(含Wireshark抓包黄金组合)
  • AI协作能力图谱:构建提问结构、反馈机制、结果校验与任务拆解四大接口
  • 防爆门气密性检测 + 抗爆冲击波试验全套技术验收要点
  • vMotion迁移突然卡死?揭秘底层TCP重传风暴与NUMA绑定冲突(仅0.3%工程师掌握的底层日志分析法)