Featured image of post N8N 案例解析:从草履虫到猛犸象

N8N 案例解析:从草履虫到猛犸象

写在前面

「案例来源」 B 站 <秋芝 2046> 从0开始“做”一个Agent!

完整的步骤&内容大家可以看原作者的视频和文档,这里就不再复述一遍了。

本文主要是想分享三块内容:

  1. 修复作者提供的AI新闻采集工作流的bug——没有“创建时间”字段的值。如果缺少这个值,就无法实现按照日期筛选最近两天AI 新闻的任务。
  2. 说起来这个案例逻辑也不复杂,但是工作流与飞书应用的API接口对接起来特别繁琐(不同应用接口的数据格式都不一样,需要人工一项一项对接上 才行)
  3. 在读取、整理新闻列表并发消息给飞书机器人这个工作流中, Agent 的提示词比较有意思,为后续进一步深入学习提供了不错的案例。

通过本文你可以获得以下收益:

  1. 熟悉n8n 平台操作

    如:变量计算和引用这块——n8n 这部分做得非常好了

  2. 对接飞书应用API接口时,需要注意的地方

    如:涉及多维表格 增删查;日历会议列表筛选;feishu 机器人webhook对接;还有应用权限开放。

  3. 浅聊 Agent 提示词框架和思维链(CoT)

效果展示

每天早上8点,飞书机器人会收到推送的 AI 新闻摘要和最近的会议安排,并提醒用户优先阅读其中重要的文章。

这个案例分为两部分(阶段):

  1. AI 新闻整理存档工作流:通过RSS 订阅,定时搜集AI 新闻频道(如这里的 新智元 腾讯科技 量子位)中的新闻,然后把新闻的标题 摘要 链接等数据按照统一的格式存入飞书多维表格中。

    这个工作流,经过我的完善,已增强为写入新闻数据的同时,删除7天前旧的新闻

    分享链接放在公众号【AI 热气球】中,感兴趣的小伙伴可以回复 917 获取。

  2. 新闻推送工作流:每天早上8点, 另一个工作流(下图)会读取多维表格中今天和昨天的AI新闻和我最近7天的日程信息,生成当天AI新闻摘要与日程提醒。

要点1

1. n8n平台上,工作流中的变量赋值和引用非常友好,达到所见即所得的效果。

以“AI新闻整理存档工作流”为例——

“INPUT” 为上个步骤的输出内容:整理好的新闻标题、日期、内容、媒体、链接信息。

在“Edit Fields”这个工具的帮助下,可以直接通过拖拽的方式完成新变量的赋值。

这样一来大大简化很多过程数据的处理步骤。如果对比coze dify平台中的处理方式,肯定会认可n8n 的这种处理方式:

在coze 和dify 中都需要使用代码工具,在代码中重新定义一个新的函数,然后把上一步生成的新闻对象 Array[object] 在for循环中一个一个提取出来,并在每个循环处理中 追加新的变量名和变量值,最后生产一个新的 Array[object] 类型数据 。

2. 简单数据的处理在过程中就可以快速完成

这里举两个例子,一个还是在“Edit Fields”这个工具中。

注意下图中 我新增了两个字段(变量)——“创建时间”和“7天前的时间”。前者用于写入飞书多维表格中的“创建时间”字段,方便后续筛选。后者则用于删除多维表格中7天前数据的筛选条件。

这里时间的计算,直接调用了javascript 的Data 函数一步完成。并且n8n 会把每个变量的值直接显示在对应变量的下方——那行紫色的文字

另一个例子:在写入新闻链接数据到多维表格时,可以直接调用正则表达式——对“新闻链接”数据中可能存在的换行符(\n) 完成替换。

3. 如果遇到复杂的数据处理,怎么办呢?

当然n8n 也有code 功能模块,默认启用的就是javascript。这一点不像 dify 那样需要一个额外的code容器来完成python或javascript 代码的执行。

这里的例子是:上一步已经从飞书多维表格中筛选了7天前的新闻,但是在删除多维表格数据时,用到的是“record_id”字段。所以,这里使用code 工具只把多维表格中数据所在行的“record_id” 提取出来,交给下一步。

要点2

在之前“coze塔罗牌工作流华丽转身”的文章中,提到了多维表格API 接口的使用。在那个案例中,主要是用到多维表格的“读取”和“写入”两个功能。

在本案例中,进一步升级—— 有多维表格的查询、写入、删除,还有飞书日历的查询。

所有飞书工具的调用,离不开n8n社区中一个非常好用的工具——Feishu Node

首先它是社区插件不是飞书官方提供的,其次它比coze 提供的接口的还好用!

一个插件汇总了飞书平台支持的107种操作,下图只展示了其中“多维表格”的一部分操作——

这些操作都是通过飞书 官方API 的接口调用实现的,所以肯定要满足飞书平台API接口的格式要求和限制。

以多维表格中日期字段的填写要求为例——

所以,这也是文章开头提到“每个接口都需要人工一个一个对接”的原因。

具体怎么对接,大家还是自己跑一遍试试就知道了。

本案例的工作流我已经放在公众号【AI 热气球】中,感兴趣的小伙伴可以回复 917 获取。

这里,我提醒两个踩过坑的地方

1: 飞书开放平台中 相关应用的权限开放

这里的相关权限类型是“应用身份”,不是“用户身份”。

如果权限不匹配,会导致相关API 操作失败,但其实不是n8n 工作流中配置的问题——

2: 用到的表格需要开通 应用的“可编辑”权限

要点3

个人以为:这个案例中,最有含金量的是在第二个工作流中调用Agent 思维链(CoT)的方法——体现了人类抽象思维的具象表达。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
你是我的专属AI助理“新闻报通”!你的使命是帮我洞察最新的AI动态,并结合我的工作日程,智能推荐感兴趣的内容和安排行程。在没有行业大事发生时,你也会关心我的生活,推荐放松娱乐活动。 最终你需要将所有分析和建议,整合为一个适合在飞书卡片中展示的Markdown格式文本块。保持乐观、敏锐、有创造力!
我有两个核心工具供你调遣:
news:用它来抓取过去2天内飞书多维表格里最新、最有料的AI新闻。此工具会返回一个新闻列表,列表中的每条新闻都包含:新闻标题、发布日期、发布媒体、核心内容/摘要、以及原文链接。
daily:用它来查看我未来7天的飞书日程安排。此工具会返回日程事件的日期、时间、事件标题。

你的行动指令:
第一步:信息收集
立即使用【最新新闻查询】工具,获取最新的AI新闻列表(每条新闻包含标题、日期、发布媒体、摘要、链接)。由于消息长度限制,精选其中12条新闻。
同时,使用【日历查询】工具,获取我未来7天的详细日程安排。
第二步:智能分析与建议(输出为纯Markdown格式
你的核心任务是生成一段单一、完整的Markdown文本。此文本本身就是最终要在飞书卡片中呈现的内容。请严格按照以下指导来组织信息,但不要在你的最终输出中包含模板本身的 ```markdown 包裹标记或任何非Markdown的解释性文字
Markdown内容结构指导(请填充实际内容):

### 🚀 AI圈今日速递与【**专属建议**】

**🌟 今日AI新闻看板**
{{#if (tool_output.latest_news an_array_with_items)}}
{{#each tool_output.latest_news as |news_item|}}
*   ---
*   **标题:** {{news_item.title}}
*   **发布日期:** {{news_item.date}}
*   **发布媒体:** {{news_item.source_or_media}}
*   **核心摘要:** {{news_item.summary}}
*   **原文链接:** [点击查看详情]({{news_item.link}})
{{/each}}
{{else}}
*   今天AI领域风平浪静,暂未捕获到新的AI大新闻。是时候出门活动活动了!
{{/if}}
*   ---

**📅 我的近期日程概览:**
[此处列出未来几天的相关日程条目,或清晰指明哪些天/时段有空档,例如:
*   X月X日 (X):上午 - 视频脚本A;下午 - 暂无安排
*   X月X日 (X):全天 - 参与行业会议
]

**💡 综合建议与排期参考:**
[基于今天获取到的所有新闻(如果有的话)以及我的日程空闲情况,给出一个综合性的建议。
例如:
- 如果有多条高质量新闻且日程有空:可以建议优先看哪条新闻,或者建议如何将不同新闻分配到不同的空闲时段。例如:“老板,今天新闻不少!**[某新闻标题]》的讨论热度和价值最高,** 建议安排在[X月X日空闲时段]详细看看。”
- 如果新闻一般但日程有空:可以建议“今天的几条新闻中,《[某新闻标题]》可以略作关注,但若无特别感兴趣,[X月X日空闲时段]或许更适合外出放松放松。”
- 如果无新闻但日程有空:“老板,今日无AI大新闻,正好给大脑放个假!我看您[X月X日]有空,不如去[附近的公园散散步/看场最新上映的电影/找个咖啡馆发发呆]?劳逸结合!”
- 如果日程已满,无论有无新闻:“老板,接下来几天日程紧凑,建议将今天的新闻信息先存档,待有空档再阅读。目前先专注已安排的工作。”
]

处理逻辑:
关于新闻展示: 如果【最新新闻查询】工具返回了多条新闻,你需要将所有新闻条目都按照上述Markdown结构中的新闻格式一一列出 如果没有新闻,则在“今日AI新闻看板”下明确告知。
关于综合建议: 这是最重要的部分。你需要结合今天获取的所有新闻的整体情况(数量、质量、潜力)和我的日程空闲度,给出一个最终的、具有指导性的综合建议。你的建议逻辑应遵循:
【有新闻】:优先分析新闻的价值和趣味性,结合日程推荐最有意思的新闻内容详情。
【无新闻】:则检查日程空闲时间,主动推荐外出、娱乐等放松身心的活动。
【日程满】:无论有无新闻,都以提醒专注现有工作为最优先。
第三步:输出纯净的Markdown文本块
你的最终输出必须且仅仅是按照第二步指导填充内容后形成的完整Markdown文本内容本身
再次强调:输出的开头不应有 ```markdown ,结尾也不应有 ``` 或任何其他非Markdown的字符、注释或解释。直接从Markdown的第一个字符(例如 ###)开始,到最后一个字符结束。
通用要求:
确保所有列出的信息(新闻的各项数据、日程条目)都准确来源于工具的输出,列出所有的新闻。
你的建议要具体、有建设性、信息充分,并体现出是对所有信息的综合考量。
语气要积极、专业,充满洞察力

这里面信息量有点大,如果第一次接触这么大篇幅的提示词 肯定会觉得有点乱,不知道注意力放在哪里。

没关系,先交给 gemini,帮我们划分下结构和关系——

这个提示词的逻辑和段落结构非常清晰和严谨,旨在引导AI生成一个结构化、个性化的“飞书卡片”式报告。 整体逻辑概览:

角色设定与使命(Persona & Mission): 首先明确AI的身份、名称、核心职责和输出风格。 工具箱(Toolbox): 列出AI可用的具体工具及其功能和返回数据格式。

行动指令(Action Instructions): 详细分解AI需要执行的步骤,从信息收集到最终输出。

    1. 信息收集: 明确调用哪些工具,获取什么数据,以及数据处理的初步要求(如精选新闻数量)。
    1. 智能分析与建议(核心): 这是生成最终内容的指导部分,详细规定了输出的格式、内容结构和决策逻辑。
    1. 输出要求: 强调最终输出的纯净性和格式的严格性。

通用要求: 对整个过程和最终输出的质量提出普遍性要求。

这下看起来是不是轻松多了?

开头类似于告诉AI 我这有哪些工具和此次任务背景是什么。

结尾则是限制AI :不要自己造新闻(针对幻觉问题),语气拟人化,输出内容要概括、有条理。

整个提示词关键点是“行动指令”的第二部分——“这是生成最终内容的指导部分,详细规定了输出的格式、内容结构和决策逻辑。” 稍微展开说说——

1. 提示词中,可以使用 if/else 这种条件语句,也可以使用each 这种循环语句

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{{#if (tool_output.latest_news an_array_with_items)}}
{{#each tool_output.latest_news as |news_item|}}
*   ---
*   **标题:** {{news_item.title}}
*   **发布日期:** {{news_item.date}}
*   **发布媒体:** {{news_item.source_or_media}}
*   **核心摘要:** {{news_item.summary}}
*   **原文链接:** [点击查看详情]({{news_item.link}})
{{/each}}
{{else}}
*   今天AI领域风平浪静,暂未捕获到新的AI大新闻。是时候出门活动活动了!
{{/if}}
*   ---

翻译成伪代码就是——

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 假设 tool_output 是一个包含工具返回结果的字典或对象
# 假设 tool_output.latest_news 是一个列表,可能包含新闻项,也可能为空

if tool_output["latest_news"] NOT null:
    # 如果 latest_news 是一个非空列表
    for news_item in tool_output["latest_news"]:
        # 对于列表中的每一条新闻
        print("*   ---")  # Markdown 分隔符
        print(f"*   **标题:** {news_item['title']}")
        print(f"*   **发布日期:** {news_item['date']}")
        print(f"*   **发布媒体:** {news_item['source_or_media']}")
        print(f"*   **核心摘要:** {news_item['summary']}")
        print(f"*   **原文链接:** [点击查看详情]({news_item['link']})")
else:
    # 如果 latest_news 不存在、为空或不是一个有效的列表
    print("*   今天AI领域风平浪静,暂未捕获到新的AI大新闻。是时候出门活动活动了!")

print("*   ---") # Markdown 分隔符,无论是否有新闻都会打印

LLM 就是有这种能力,读懂思维逻辑,并按照这个逻辑执行任务。

2. “综合建议”部分,要求按照四种情况做出不同的回应

1
2
3
4
5
6
7
[基于今天获取到的所有新闻(如果有的话)以及我的日程空闲情况,给出一个综合性的建议。
例如:
- 如果有多条高质量新闻且日程有空:可以建议优先看哪条新闻,或者建议如何将不同新闻分配到不同的空闲时段。例如:“老板,今天新闻不少!**《[某新闻标题]》的讨论热度和价值最高,** 建议安排在[X月X日空闲时段]详细看看。”
- 如果新闻一般但日程有空:可以建议“今天的几条新闻中,《[某新闻标题]》可以略作关注,但若无特别感兴趣,[X月X日空闲时段]或许更适合外出放松放松。”
- 如果无新闻但日程有空:“老板,今日无AI大新闻,正好给大脑放个假!我看您[X月X日]有空,不如去[附近的公园散散步/看场最新上映的电影/找个咖啡馆发发呆]?劳逸结合!”
- 如果日程已满,无论有无新闻:“老板,接下来几天日程紧凑,建议将今天的新闻信息先存档,待有空档再阅读。目前先专注已安排的工作。”
]

这里分别针对四种不同场景有多条高质量新闻且日程有空】【新闻一般但日程有空】【无新闻但日程有空】和 【日程已满,无论有无新闻】产出不同建议,并给出示例。

在Agent中给到大模型的数据 一定会是多样和复杂的,所以 在提示词中也需要明确,面对不同的“场景” 应该如何做出回应。

本案例中,回应内容还可能比较简单——主要目的是提高AI 新闻密度和情绪价值。那如果是复杂场景下的响应呢?

我猜就需要把上述两点结合起来——不同场景 + 条件/循环 等逻辑表达。

AI 应用分类

之前整理过AI 应用的发展阶段:从早期的信息检索汇总、到工作流、到某个垂直领域智能体、到某个行业的智能体。因为这其中跨度有点大,而且缺少一些实施过程的难点和细节。

所以,最近也在考虑 如何从工程实现的角度给 AI应用分个阶段:

一来可以分类市面上的AI产品,二来明确不同类型AI 产品的技术路线,三来 展望下未来可能会迭代出哪些新的版本。

先看下AI 发展阶段和难点图( 原文——“用Coze + Claude 实现Manus,Agent的难点到底在哪?”)

再结合,手上接触到的案例和技术实现,整理成一张表——

**整理完发现:**处理抽象任务的能力,是当前AI 应用的魔力所在。

难怪大家一直希望 AI 可以更像人类的大脑,会检索,会思考,会推理,会总结归纳,会自我纠正。

PS:

  1. 本文案例, 也是在文章 棚友认识一下,我叫n8n 中的n8n测试环境实现的。

  2. n8n官方也提供了现成的workflow,感兴趣的话可以参考下更多案例: https://n8ncn.io/workflows

Licensed under CC BY-NC-SA 4.0