☰
GitHub Actions运行开源AI Agent:定时自动化任务实操指南
2026/10/26 14:01:46 网站建设 项目流程

开头部分,我直接用从业者口吻切入,说明“跑在 GitHub Actions 上的开源 AI Agent 框架”是什么:用 GitHub Actions 的免费云环境来跑 AI Agent,让 Agent 定期自动执行任务,并把结果提交回仓库或者推送到自己的终端。说明适合谁:想低成本搭建个人自动化、又不想维护服务器的人。然后展开。

我要写大约6000字以上的内容。开始拟写,留意自然、流畅、丰富。 最近我把一套开源 AI Agent 框架实际跑在了 GitHub Actions 上,用免费的云环境定时执行任务,agent 自己决策、自己调工具、自己把结果写回仓库。折腾了大半个月,踩了不少坑,也总结出一套真正能用的做法,这里完整分享一下。

先说这东西是什么:所谓“跑在 GitHub Actions 上的开源 AI Agent 框架”,本质就是借助 GitHub 提供的公有云 CI/CD 运行环境,把 LLM 驱动的 Agent 程序打包成一个 workflow,由 cron 定时触发、仓库事件触发或手动触发。GitHub 免费账号每月有 2000 分钟运行时长,单次任务最长 6 小时,对绝大多数个人自动化场景完全够用。这个方案适合不想维护服务器、又想搞定时型 AI Agent 的人,比如自动收集行业信息、应急响应巡检、自动生成日报、监控开源项目动态等。

先提醒一句:这个思路不是把 Actions 当作无限算力的“免费白嫖机”,而是借助它的托管环境加产物存储来做有状态任务。它解决的核心痛点是“Agent 需要一个稳定可靠的宿主”,而 Actions 恰好提供了一整套现成的触发、隔离、日志、存储机制,连运维都省了。

1. 为什么把 AI Agent 放到 GitHub Actions 上跑

1.1 这不是 CI/CD,这是免费的消息驱动沙盒

很多人对 GitHub Actions 的第一印象停留在“代码推送后自动跑测试、构建、部署”。但它本质上是一个事件驱动的分布式任务执行系统,我把它当“云函数 + 定时任务 + 文件仓库”的组合拳用。

一个 workflow 能收三类事件:schedule定时、workflow_dispatch手动、push/pull_request代码事件。这就意味着,只要把 Agent 代码写进 job 里,它就能被 cron 在任意时间点唤醒。GitHub 官方仓库给的别名是“Actions 上的定时机器人”,社区里也有不少把 Actions 当免费 cron 服务器用的例子,但真正把 LLM Agent 跑进去的人还不多。

举例:我在一个公开仓库里放了每天凌晨 3 点自动运行的 Agent,它负责扫描指定开源项目的 release 和 issue,让大模型判断哪些变化值得关注,然后整理成摘要提交回仓库并推送通知。整个过程不占用我本地任何资源,也不需要在任何云厂商那里注册 cron 服务。

1.2 这个思路真正能干什么

定时型 Agent 是强需求,但绝大多数人卡在“没有地方跑”。常见的替代方案是 PythonAnywhere、VPS、家里的树莓派,它们要么收钱、要么要维护、要么断网失灵。GitHub Actions 把这三件事全包了:它自带 Ubuntu 系统、公网 IP、包管理器、常用运行时,跑完还能把产物直接推回 git 仓库,天然保留历史记录。

适合做这四类事情:

  • 信息收集类:定期抓取 RSS、GitHub 仓库动态、特定关键词搜索结果,交给 Agent 聚合去重、生成摘要。
  • 决策辅助类:每天定时分析行情/天气/指标,让 Agent 结合上下文给出解读和建议。
  • 自动维护类:对项目自动做依赖更新检查、issue 分类打标、Pull Request 审查。
  • 知识沉淀类:定期把收集到的数据整理成 Markdown,提交到仓库,形成可检索的知识库。

不适合做的事情也很明确:实时性要求很高的任务不建议放 Actions,因为 cron 任务误差可能到分钟级;需要长连接或 WebSocket 的不适合,因为每次运行都是全新环境;重度依赖本地 IP 或内网服务的也不行,Actions 和你本机不互通。

1.3 Actions 与普通 VPS 的边界划分

在实际选型时,我习惯把任务分成两类:一次性计算型和非交互长驻型。Actions 擅长前者,VPS 擅长后者。Agent 如果只运行几分钟、输出结果后就退出,Actions 几乎是零成本最优解;但如果 Agent 需要保持状态、持续对话、监听回调,还是得老老实实用服务器。

还有一个容易被忽略的点:Actions 的日志、环境变量加密、权限控制都是现成的,不需要自己搭 prometheus 和 alert。每个 workflow 的每次运行都有完整日志,失败时支持 webhook 通知和邮件通知,对 Agent 这种“不可控输出”较多的程序来说,可观测性非常重要。

2. 开源 AI Agent 框架怎么选

2.1 我比较过的三派方案

目前主流的开源 AI Agent 框架大致分三个流派。第一派是 LangChain 系(尤其是 LangGraph),依赖生态最丰富,什么工具都有,但抽象层级极多,学习成本高。第二派是 Anthropic 官方出的 Claude Agent SDK、OpenAI 出的 Agents SDK,跟对应模型深度绑定,好用但换模型麻烦。第三派是轻量级单文件 agent,例如各路 Go 和 Python 社区自己写的 agent 包,几百行代码就能跑,灵活但工具生态靠手搓。

我在 Actions 里没有一开始就用最重的框架,而是先跑通了原生 API 直调。原生直调的 Agent 逻辑很简单:大模型负责规划,代码负责执行,中间用 JSON 协议做函数调用。等到确实需要多步推理和复杂工具编排时,才引入框架。

这里给大家一个具体选择建议:如果任务简单(一次调用、一次工具结果拼接),直接用原生 API 或者轻量 SDK;如果要构建多步骤、有循环、需要记忆的任务,选 LangGraph 最稳妥。Claude Agent SDK 也适合,尤其当你的工具定义相对固定时,它的 agent loop 和工具调用处理得很简洁。

2.2 核心权衡:工具调用与记忆管理

Agent 框架的所谓“智能”,其实集中在两块:工具调用和记忆管理。工具调用就是让模型按照 JSON Schema 输出参数,然后代码去执行对应函数返回结果。记忆管理则决定了大模型能否在多次推理之间保持上下文。

GitHub Actions 有个天然优势——每次运行环境是全新的,这反而逼着你把记忆外置化。我把对话记录和中间结果写入仓库中的 JSON 文件,下一次运行时用actions/checkout把上一次的结果拉下来,再放进本次 prompt 上下文。这样 Agent 的“记忆”就持久化了。

推荐用文件做记忆,而不是向量数据库。因为 Actions 环境下每次构建都要重新安装依赖,如果引入 chromadb 或者 qdrant,光是依赖安装就可能耗掉几分钟。对定时任务来说,纯文件 + 结构化 JSON 足够支撑大多数场景,而且 Git 本身就是一个版本化存储,随时可以回溯 Agent 之前的状态。

2.3 一个可复用的极简 Agent 骨架

这里给出一段核心代码思路,它足够支撑日常的信息收集类 Agent:

import json from openai import OpenAI client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) tools = [ { "type": "function", "function": { "name": "fetch_webpage", "description": "抓取网页并提取正文文本", "parameters": { "type": "object", "properties": {"url": {"type": "string"}}, "required": ["url"], }, }, } ] messages = [ {"role": "system", "content": "你是一个信息收集助手,只做有依据的判断。使用工具获取数据后再总结。"}, {"role": "user", "content": "请查看 https://example.com 上的内容,总结最新动态"}, ] for _ in range(5): resp = client.chat.completions.create( model="gpt-4o-mini", messages=messages, tools=tools, tool_choice="auto" ) msg = resp.choices[0].message if not msg.tool_calls: break messages.append(msg) for call in msg.tool_calls: result = fetch_webpage(json.loads(call.function.arguments)["url"]) messages.append({ "role": "tool", "tool_call_id": call.id, "content": result, }) final_answer = messages[-1].content

这段代码体现了 Agent 的核心循环:模型输出工具调用请求,程序执行真实函数,结果回填到上下文,模型再继续推理。在 Actions 里跑的时候,只需要把fetch_webpage替换成任意代码能力(读 API、查询数据库、操作文件),Agent 就能处理不同类型的信息。

3. 从零搭建一个跑在 Actions 上的 Agent:实操记录

3.1 仓库结构与 secrets 准备

搭建的第一步是在 GitHub 建一个专用仓库,目录结构尽量简单:

repo/ ├── .github/workflows/agent.yml ├── src/agent.py ├── src/tools.py ├── storage/ │ └── state.json └── output/

storage目录保存 Agent 的持久化状态,output目录保存每次运行结果。这两个目录建议直接提交进 git,虽然会产生一点仓库体积,但换来的是免费的对象存储和版本历史,非常划算。

然后是 secrets 设置。在仓库 Settings -> Secrets and variables -> Actions 中添加以下内容:

  • OPENAI_API_KEY或ANTHROPIC_API_KEY:大模型服务的密钥。
  • MY_API_TOKEN:如果 Agent 要访问第三方 API,单独放一个 token 方便审计。

注意:不要在代码里写死任何密钥,GitHub 会自动对 Secrets 打码,但历史提交里的明文密钥不会自动清除,真泄露了必须立即吊销并清理提交历史。

3.2 workflow 的写法与常见陷阱

以下是完整的 workflow 配置文件,已经过实际验证:

name: daily-agent on: schedule: - cron: "0 3 * * *" workflow_dispatch: permissions: contents: write concurrency: group: daily-agent cancel-in-progress: false jobs: run-agent: runs-on: ubuntu-latest timeout-minutes: 20 steps: - name: Checkout repo uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 with: python-version: "3.12" cache: "pip" - name: Install dependencies run: | pip install --upgrade pip pip install -r requirements.txt - name: Run agent env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} MY_API_TOKEN: ${{ secrets.MY_API_TOKEN }} run: | python src/agent.py - name: Push output run: | git config user.name "agent-bot" git config user.email "agent-bot@users.noreply.github.com" git add storage/ output/ git diff --cached --quiet || git commit -m "Update agent output $(date -u)" git push

几个容易踩的坑:

  • schedule事件用的是 UTC 时间。很多人在中国时区设置cron: "0 3 * * *",以为凌晨三点跑,实际是北京时间上午十一点跑。要按北京时间配置的话,记得换算成 UTC。比如北京时间早上八点,对应 UTC 就是“0 0 * * *”。实际执行会有监控机制,虽然大多数时候能够准点触发,极端情况下也可能延迟几分钟。
  • job 的并发控制。cron 和手动触发可能在同一天内重叠,如果没有concurrency字段,两个任务会并行跑,同时写同一个 storage 文件导致冲突。加上concurrency就是为了避免这种情况。
  • 默认分支和保护规则。如果仓库默认分支是main且有推送保护,bot 直接 push 会被拦截;要么去掉保护,要么给操作加上BYPass条件。个人仓库一般没这个问题,团队仓库需要注意。
  • timeout-minutes一定要设。LLM 调用一旦出现网络超时重试,工作流可能拖很久,免费额度会被白白消耗。个人经验是常规任务给 20 分钟足够。
  • Actions 支持cache: "pip",它会缓存 pip 依赖。在 Ubuntu 环境下开缓存后,第二次运行安装依赖的时间从三分钟降到二十秒,效果明显。

3.3 把状态持久化到 Git 仓库

Agent 在云端跑完,经常会带着新的信息状态,比如上次扫描到了哪个时间点、上一次输出摘要的哈希、某个资源是否已经被处理过。这些状态如果存在本地,第二次运行就又丢了;存在第三方对象存储还要配密钥;最省事的就是写回仓库。

具体做法是每次运行开始时先 checkout 仓库,读取storage/state.json;运行过程中更新内存中的 state 对象;运行结束写入文件后再 git push。这样状态、结果、运行日志全部以 git commit 的方式沉淀下来。

import json import os STATE_FILE = "storage/state.json" def load_state(): if not os.path.exists(STATE_FILE): return {} with open(STATE_FILE, "r") as f: return json.load(f) def save_state(state): with open(STATE_FILE, "w") as f: json.dump(state, f, ensure_ascii=False, indent=2)

3.4 调试技巧与手动触发

在把 Agent 交给 cron 前,一定先手动触发。方法是进入仓库的 Actions 页面,选中 workflow,点击 Run workflow 按钮。这样能观察到真实的运行环境、环境变量和网络状况。我在调试阶段几乎每一步都通过 workflow_dispatch 触发,因为在本地写好的代码放到 Ubuntu 容器里经常有细微差异。

日志查看也很重要。Actions 页面会输出步骤级日志,Python 的 print 输出直接可见。建议在 agent.py 里加上日志模块,打印每次模型调用消耗的 token 数和工具执行耗时。这样你能看清楚一次任务到底把时间花在了哪里,是网络请求慢,还是依赖安装慢,还是模型输出太长导致超时。

4. 常见问题与排查技巧实录

4.1 任务明明触发了,却什么都没有输出

这是最常见的状况。排查方法从 Actions 页面查看对应 job 的日志,先看Run agent这一步的完整输出,确认 Python 是否报错、API 是否返回 401、网络是否被限制。我遇到过一次报错原因是requirements.txt里有个包在新版 Ubuntu 上编译失败,属于系统依赖缺失。那种情况需要在 workflow 中先执行sudo apt-get update && sudo apt-get install -y ...。

还有一个极易忽略的问题:GitHub 对 workflow 第一次运行有白名单机制,如果仓库是私有仓库并且用户信息没配置,git push 阶段会报Please make sure you have the correct access rights。这个不是开发者的代码问题,而是 bot 使用的 token 权限不对。解决办法是,要么开permissions: contents: write,要么用GITHUB_TOKEN的默认权限把写权限打开。如果是用个人访问令牌(PAT)方式,要给 repo 权限且把仓库 owner 加进去。

4.2 模型调用频繁失败或超时

在 Actions 环境里访问 OpenAI 或 Claude 等外部模型服务,网络一般没问题,但确实会碰到限流和时区相关触发。尤其多个 workflow 同时运行时,容易出现 429。

我的处理方式是给所有外部调用加退避重试:

import time, random def call_with_retry(func, max_retries=4): for attempt in range(max_retries): try: return func() except Exception as e: if attempt == max_retries - 1: raise wait = (2 ** attempt) + random.uniform(0, 1) time.sleep(wait)

除此之外,几个细节要注意:

  • 用gpt-4o-mini或claude-sonnet这类便宜模型跑掉很多初始分类任务,只在需要真正推理时用贵模型。
  • 在 prompt 里限制输出长度,防止模型生成超大响应占满上下文。
  • 监控每个模型调用耗时,如果某步持续超过 30 秒,优先怀疑网络和限流。

4.3 并行与串行的取舍

大多数 Agent 技能循环是顺序执行:读数据、调用模型、执行工具、再调用模型。这个顺序在 Actions 上可以做,但不是最高效的。如果你的 Agent 要处理多个独立数据源,建议用 Python 的concurrent.futures做并行请求,能显著缩短运行时间。

我用过的一个模式:把待处理的 URL 列表拆成 4 个并发桶,每个桶由一个 worker 依次调用模型。之后的合并阶段再让主进程汇总。这样做的好处是总耗时大约从 9 分钟降到 5 分钟以内,坏处是并发大时容易触发限流,所以并发数不宜过高,我一般控制在 4~6 个。

4.4 失败重试的工程写法

Agent 程序不像传统脚本,它可能因为模型输出 JSON 不合法、工具返回空值、第三方 API 临时挂掉而失败。如果只靠 Actions 原生失败重试,那会浪费大量时间。

我给 workflow 设计的失败重试策略有三层:

第一层,代码内 try/except 捕获外部调用异常,进入重试队列。第二层,模型输出 JSON 解析失败时,让模型重新生成一次,并在系统提示里说清楚上一轮解析的报错信息。第三层,workflow 失败后,Actions 支持retry策略,但我一般不开,因为如果每轮都领取新任务可以,但如果是幂等性不强的任务,可能重复产生脏数据。

真正靠谱的兜底是把“已经处理过的 key”记录到 storage 的 state.json 中。下一次 Agent 启动时读一下,已经在处理列表中并且成功结束的,直接跳过。这就实现了“断点续跑”的效果。

5. 进阶用法:让这个框架变成个人的自动化基础设施

5.1 用 Actions 做定时数据采集与 AI 摘要

我实际跑得最久的一个 Agent 是“每天定时采集开源项目动态”。它每 12 小时拉取特定 GitHub 仓库的 Issues 和 Releases,利用大模型判断哪些内容变化值得纳入简报,再把筛选结果汇总成 Markdown,提交到仓库并推送到 Telegram。

这里有一个很关键的经验:一定要给任务限数量,否则 Agent 会抓取太多数据导致 token 消耗爆炸。我用 state.json 记录每个项目的“上次活跃时间”,每次只抓取后这条时间的更新内容,这样日积月累下来,token 消耗只跟增量数据有关,不会无限膨胀。

5.2 把 Agent 结果推送到自己的消息终端

GitHub Actions 跑出来的结果不在本地,如果开发者没有打开 GitHub 页面习惯,很容易错过。这里可以把 Agent 的 output 写入 repo 后,通过 Telegram Bot 或 Discord webhook 主动推送到手机上。

5.3 多 Agent 的分工与调度

GitHub Actions 允许在同一个仓库里放多个 workflow 文件,一个文件就是一个独立 Agent。比如 12:00 跑新闻摘要 Agent,16:00 跑代码依赖检查 Agent,每天 9:00 跑日报汇总 Agent。

这些 Agent 之间千万不要通过写同一个文件来共享数据,容易出现竞态。更好的做法是让每个 Agent 有自己的存储目录,然后在最终汇总时用另一个“编排 Agent”去读取所有目录。这种“小 Agent 独立执行 + 总 Agent 汇总”的模式,比单纯一个大 Agent 做所有事情稳定得多,也更省 token。我现在的架构就是这样一个分布式多 Agent 结构,每个 agent 的职责边界非常清晰。

6. 最后再分享几个经验

我个人在实际操作中的体会是,这个模式最打动我的不是免费额度,而是“把模型能力变成可追溯、可回滚、可分享的自动化流程”。Actions 上跑 Agent,每一次执行都会留下永久日志和 Git 提交,出错时可以回滚到任意历史状态,这种透明性是我之前用 VPS 和 crontab 完全做不到的。

一个小技巧收尾:给 Agent 的输出文件写入时间戳和 commit hash,比如report-YYYYMMDD.md。如果 Git 仓库公开的话,你会得到一份能被索引、能被链接、能被人引用的时序化数据集,这比“在服务器上的某个隐藏目录里存文件”有价值得多。按照这个思路,你可以把个人的监控、摘要、数据采集需求都逐步迁移到 Actions 上来,形成一套完全托管、近乎免费、可随时徒手 cp 重来的公共基础设施。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询