简介:这份PDF资料源自北大青鸟人工智能研究院、北大计算机学院及北大教育学院学习科学实验室联合发布的讲座内容,面向对AI工具感兴趣的技术探索者、效率实践者以及希望提升工作与学习效率的专业人士。它跳出单纯讲解工具使用的思路,以“完成任务”为主线,围绕知识探索与深度研究、行业洞察与时机分析、内容创作与媒体制作、创意设计与成果转换四大高频场景,系统梳理Manus、Skywork、Genspark、扣子空间等11个AI Agent产品的特点与协同策略,并配有任务分解、信息整合与流程优化的案例解析。资源包共1个PDF文件,约27.03MB,内容涵盖AI工具全景概览、各Agent基础操作与适用场景,以及公众号日更、播客制作、学术调研、品牌营销设计等实战方向的操作指南与工具组合建议。目前已有29人学习,适合希望找到适合自己的“最佳拍档”、在人机协作中兼顾效率与创意的读者参考。
1. 从单点工具到协同网络:AI Agent 工具协同到底在解决什么
你可能已经装了七八个 AI 工具:用 Coze 搭工作流、用 Manus 跑任务、用某个代码助手写脚本,但真到干活的时候,还是手动在几个窗口之间来回粘贴。问题不在于工具不够强,而在于它们各干各的,没有形成协同。北京大学这套「从 AI 工具到最佳拍档」的思路,核心就是让多个 Agent 各司其职、互相调用,把「我操作工具」变成「工具自己流转」。它适合已经用过至少一个 AI 工具、想进一步把重复流程自动化的从业者,也适合正在评估 Agent 中台方案的技术负责人。读完你能判断自己的场景该不该做协同、用 Coze 还是自建框架、以及第一个可跑通的协同链路怎么搭。
2. 协同的底层逻辑:Agent 之间靠什么对话
2.1 三种协同模式与选型依据
Agent 协同不是把两个工具图标画在一起就完事。常见做法有三种:串行流水线、主从调度、对等协商。串行流水线最简单,A 的输出直接喂给 B,适合格式转换、内容加工这类线性任务,比如 Coze 工作流里「抓取网页 → 摘要 → 转 Markdown → 存文件」。主从调度是有一个 Orchestrator Agent 负责拆任务、分发给子 Agent,子 Agent 干完回报,适合任务边界清晰但步骤多的场景,比如「收集竞品信息 → 分析定价 → 生成报告」。对等协商最复杂,多个 Agent 共享上下文、互相质疑和补充,适合需要多视角校验的决策类任务,但落地成本高,新手不建议一上来就做。
选型的判断标准就一条:你的任务能不能画成一张没有环的流程图。能画成 DAG 的,用串行或主从;画出来有回环、需要反复讨论的,才考虑对等协商。我见过太多人一上来就追求「多 Agent 辩论」,结果连最基本的串行链路都没跑稳,调试成本直接翻倍。
2.2 用 Coze 工作流搭一条最小协同链路
下面这条链路实现的是:输入一个技术标题,自动搜索背景资料,生成一段摘要,再把摘要转成 Markdown 文件。这是最基础的串行协同,两个 Agent 节点加一个工具节点。
# Coze 工作流配置(简化结构,实际在可视化界面拖拽) workflow: name: "title_to_summary" nodes: - id: start type: input schema: title: string # 用户输入的技术标题 - id: search_agent type: llm model: "doubao-pro" prompt: | 你是一个技术资料检索助手。根据用户输入的标题:{{start.title}} 生成 3 条相关的背景检索关键词,只输出关键词,用换行分隔。 output: keywords - id: search_tool type: plugin plugin: "web_search" input: "{{search_agent.keywords}}" output: raw_results - id: summary_agent type: llm model: "doubao-pro" prompt: | 根据以下检索结果,写一段 200 字以内的技术摘要: {{search_tool.raw_results}} output: summary - id: markdown_tool type: plugin plugin: "text_to_file" input: content: "{{summary_agent.summary}}" format: "markdown" output: file_url逻辑说明:search_agent负责把标题转成可检索的关键词,这一步用 LLM 而不是直接拿标题去搜,是因为标题往往太长、太具体,直接搜召回率低。search_tool是 Coze 内置的联网搜索插件,输入关键词数组,输出原始结果。summary_agent做信息压缩,把可能几千字的检索结果压到 200 字。最后markdown_tool负责落盘。
参数说明:model选doubao-pro是因为它在中文摘要任务上响应稳定,如果你的场景以英文为主可以换。prompt里的{{变量名}}是 Coze 的变量引用语法,必须和上游节点的output字段名一致,否则运行时会报「变量未定义」。text_to_file的format参数支持markdown、txt、json,选markdown会保留标题层级。
注意:Coze 工作流调试时,每个节点都可以单独运行看输出。先逐个节点验证,再连起来跑,比整条链路一起调效率高得多。
2.3 自建 Agent 协同:Spring AI 的编排方式
如果你需要把 Agent 协同嵌到自己的 Java 后端里,Spring AI 是目前比较顺手的选择。它的核心抽象是ChatClient和ToolCallback,多个 Agent 通过共享ChatMemory来传递上下文。
// Spring AI 中两个 Agent 串行协同的简化示例 @Service public class SummaryPipeline { private final ChatClient searchAgent; private final ChatClient summaryAgent; public SummaryPipeline(ChatClient.Builder builder) { this.searchAgent = builder .defaultSystem("你是一个检索关键词生成助手,只输出关键词。") .build(); this.summaryAgent = builder .defaultSystem("你是一个技术摘要助手,输出 200 字以内。") .build(); } public String run(String title) { // 第一个 Agent:标题转关键词 String keywords = searchAgent.prompt() .user(title) .call() .content(); // 模拟检索(实际接搜索引擎 API) String rawResults = mockSearch(keywords); // 第二个 Agent:检索结果转摘要 return summaryAgent.prompt() .user(rawResults) .call() .content(); } }逻辑说明:两个ChatClient实例各自持有独立的 system prompt,互不干扰。run方法里先调searchAgent拿关键词,再用关键词去检索,最后把检索结果交给summaryAgent。这就是最朴素的串行协同。
参数说明:defaultSystem设定了每个 Agent 的角色边界,这一步很关键——如果不设,两个 Agent 的行为会趋同,协同就退化成一次普通对话。prompt().user().call().content()是 Spring AI 的链式调用,content()返回纯文本。如果你需要结构化输出,可以用.entity(SomeClass.class)替代.content()。
3. 把协同链路做稳:上下文传递与错误处理
3.1 上下文在 Agent 之间怎么传才不丢
协同链路最容易翻车的地方就是上下文丢失。串行链路里,上游 Agent 的输出直接作为下游的输入,看起来简单,但实际会遇到三个问题:格式不匹配、长度超限、语义漂移。
格式不匹配的典型场景:上游 Agent 输出了一段带 Markdown 标记的文本,下游 Agent 期望的是纯文本,结果下游把##也当成了内容的一部分去处理。解决办法是在上游的 prompt 里明确输出格式,比如「只输出纯文本,不要任何 Markdown 标记」,或者在下游加一个清洗节点。
长度超限更常见。LLM 的上下文窗口有限,如果上游输出几千字,下游可能直接截断。我一般会在中间加一个「压缩节点」,用一个小模型把上游输出压到 500 字以内再传给下游。Coze 里可以用一个 LLM 节点专门做这件事,Spring AI 里可以加一个ContentCompressor组件。
语义漂移是最隐蔽的。上游 Agent 输出的内容,下游 Agent 理解成了另一个意思。比如上游说「这个方案的成本较高」,下游理解成「这个方案不可行」。避免方法是让下游 Agent 在 prompt 里明确「你收到的输入来自上游 Agent,请基于以下内容继续处理,不要自行推断未提及的信息」。
3.2 错误处理:Agent 执行失败时怎么办
Agent 协同链路里,任何一个节点失败都会导致整条链路中断。常见做法是给每个节点加重试和降级。
重试策略:LLM 调用失败(超时、限流)时,重试 2 次,间隔 1 秒。Coze 工作流里可以在节点设置里配重试次数,Spring AI 里可以用 Spring Retry 注解。
降级策略:如果检索节点失败,不要让整条链路挂掉,而是让下游 Agent 基于已有信息继续生成,并在输出里标注「检索结果缺失」。这样至少能拿到一个不完整但可用的结果。
// Spring AI 中带重试和降级的节点调用 @Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000)) public String callWithRetry(String input) { return chatClient.prompt().user(input).call().content(); } public String callWithFallback(String input) { try { return callWithRetry(input); } catch (Exception e) { // 降级:返回一个占位提示,让下游继续 return "[检索失败,以下内容基于已有信息生成]"; } }逻辑说明:@Retryable注解让方法在抛出异常时自动重试,最多 3 次,每次间隔 1 秒。callWithFallback包了一层 try-catch,重试耗尽后返回降级内容,保证链路不中断。
参数说明:maxAttempts不要设太大,3 次足够,再多会拖长整体响应时间。delay设 1000 毫秒是因为大多数限流错误的恢复窗口在 1 秒左右。降级返回的占位文本要足够明确,让下游 Agent 知道「这里缺了东西」,而不是把占位文本当成真实内容。
3.3 用 Coze 工作流做条件分支
不是所有任务都适合一条直线走到底。有些场景需要根据中间结果决定下一步走哪条路。Coze 工作流支持条件分支节点,可以根据上游输出的内容判断走哪个分支。
# Coze 工作流中的条件分支配置 nodes: - id: classify_agent type: llm prompt: | 判断以下内容属于哪一类,只输出 "tech" 或 "business": {{start.input}} output: category - id: branch type: condition conditions: - when: "{{classify_agent.category}} == 'tech'" next: tech_agent - when: "{{classify_agent.category}} == 'business'" next: business_agent - id: tech_agent type: llm prompt: "你是一个技术分析助手,请分析:{{start.input}}" - id: business_agent type: llm prompt: "你是一个商业分析助手,请分析:{{start.input}}"逻辑说明:classify_agent先做一次分类,branch节点根据分类结果决定走tech_agent还是business_agent。这样两个下游 Agent 各自有独立的 prompt,不会互相干扰。
参数说明:condition里的表达式语法是 Coze 特有的,==是精确匹配。如果你的分类结果可能带空格或换行,建议在classify_agent的 prompt 里加一句「只输出一个词,不要任何标点或空格」。
4. 避坑与排查:协同链路跑不通时先看这几处
4.1 变量引用报「未定义」
现象:工作流运行到某个节点时报错,提示变量未定义或为空。
原因:上游节点的output字段名和下游节点prompt里的{{变量名}}不一致。Coze 里变量名是大小写敏感的,summary和Summary会被当成两个不同的变量。
解决:逐个节点检查output字段名,复制粘贴到下游的引用位置,不要手动敲。如果上游节点有多个输出字段,确认引用的那个字段确实有值。
4.2 LLM 节点输出格式不稳定
现象:上游 Agent 有时输出纯文本,有时带 Markdown 标记,有时多一段解释性文字,导致下游解析失败。
原因:LLM 的输出本身有随机性,prompt 里如果没有强约束,模型会「自由发挥」。
解决:在 prompt 末尾加硬约束,比如「只输出结果,不要任何解释、不要 Markdown 标记、不要换行」。如果还是不稳定,在下游加一个清洗节点,用正则把非目标内容去掉。更稳妥的做法是用结构化输出,Coze 里可以配 JSON Schema,Spring AI 里用.entity()。
4.3 链路太长导致超时
现象:工作流节点超过 5 个之后,整体运行时间超过平台限制,报超时错误。
原因:每个 LLM 节点平均耗时 3-5 秒,串行下来总时间线性增长。Coze 免费版的工作流超时限制比较紧。
解决:把能并行的节点改成并行。比如两个独立的检索任务,不要串行跑,用并行分支同时跑。另外,把不必要的小模型调用合并成一个节点,减少 LLM 调用次数。
4.4 检索插件返回空结果
现象:检索节点返回空数组,下游 Agent 拿到空输入后输出一段无关内容。
原因:检索关键词太具体或太生僻,搜索引擎没有匹配结果。或者关键词里带了特殊字符,插件解析失败。
解决:在检索节点后面加一个判断,如果结果为空,走降级分支,让下游 Agent 基于标题本身生成内容,而不是基于空检索结果。另外,关键词生成时让 LLM 输出 3-5 个不同角度的词,不要只输出一个。
4.5 自建 Agent 时内存泄漏
现象:Spring AI 项目跑一段时间后响应变慢,最终 OOM。
原因:ChatMemory如果没有设置上限,每次对话都会往内存里追加消息,长时间运行后内存被撑满。
解决:给ChatMemory设置maxMessages上限,比如 20 条,超出后自动淘汰最早的消息。或者用InMemoryChatMemory的替代方案,把对话历史存到 Redis 里,设置 TTL。
5. 进阶:让协同链路自己判断该不该继续
前面讲的都是「预设好的链路」,节点和分支在运行前就定死了。但真实场景里,你往往希望 Agent 自己能判断「这一步的结果够不够好,要不要再来一轮」。这就是自省循环,也是从「工具协同」走向「最佳拍档」的关键一步。
实现方式是在链路末尾加一个「质检 Agent」,它检查最终输出是否满足要求,如果不满足,把问题反馈给上游,触发一轮重做。Coze 工作流里可以用循环节点实现,Spring AI 里可以用一个 while 循环包住整条链路。
// Spring AI 中的自省循环:质检不通过就重做 public String runWithReflection(String title, int maxRounds) { String result = ""; for (int i = 0; i < maxRounds; i++) { result = pipeline.run(title); String feedback = qualityAgent.prompt() .user("请检查以下内容是否满足要求:\n" + result + "\n如果满足,只输出 PASS;如果不满足,输出具体问题。") .call() .content(); if ("PASS".equals(feedback.trim())) { return result; } // 把质检反馈作为额外上下文,重新跑一轮 title = title + "\n[上一轮问题:" + feedback + "]"; } return result; // 达到最大轮次后返回最后一版 }逻辑说明:qualityAgent负责质检,输出PASS或具体问题。如果通过,直接返回;如果不通过,把问题追加到输入里,重新跑一轮。maxRounds控制最大重做次数,防止无限循环。
参数说明:maxRounds建议设 2-3,再多收益递减且耗时翻倍。质检 Agent 的 prompt 要写得具体,比如「检查是否包含至少 3 个数据点、是否有明确的结论」,而不是笼统的「检查质量」。反馈信息要能指导下一轮改进,所以质检 Agent 输出的问题描述要足够具体。
一个我踩过的坑:质检 Agent 本身也可能误判。有一次它把一段完全合格的输出判为不合格,导致链路白跑了两轮。后来我在质检 prompt 里加了一句「如果不确定,倾向于输出 PASS」,误判率明显下降。这个策略叫「宽松质检」,适合对准确性要求不是极端高的场景。
另一个技巧是把质检结果存下来,跑一段时间后统计「哪些问题最常被质检 Agent 标记」,然后针对性优化上游 Agent 的 prompt。这比盲目调 prompt 有效得多。
希望帮到你。
本文还有配套的精品资源,点击获取