☰
OpenClaw 自动化实战:用 AI 写周报的 config.toml 配置与完整代码
2026/9/26 3:50:18 网站建设 项目流程

1. 周五下午五点的周报焦虑,OpenClaw 能接住多少

周五下午五点,日历提醒弹出来「提交周报」,你打开空白文档,脑子里只剩一句「这周干了啥」。翻 Git 提交记录、翻会议纪要、翻聊天记录,凑出一份自己都不想看的流水账。这个场景我太熟了,所以这次直接动手把 OpenClaw 接上 AI,做一条从 Git 日志到成稿周报的自动化链路。

OpenClaw 是一个可编排的自动化 Agent 运行框架,你可以把它理解成一个「能读文件、能跑脚本、能调模型」的调度中枢。它本身不替你写周报,但它能把「收集原始素材 → 调用模型生成 → 落盘输出」这三步串成一条可重复执行的流水线。适合谁?适合每周要交周报、又不想把时间花在「回忆和排版」上的开发者、测试、产品同学。这篇会交付一份可复制的config.toml骨架、一个周报生成脚本、一次端到端验证动作,你照着跑就能出第一份 AI 周报。

核心检索词先摆出来:OpenClaw 周报自动化、config.toml 配置、AI 生成周报代码。这三个词贯穿全文,你搜到的其他教程如果只讲概念不讲配置,可以直接跳过。

2. 前置准备:TaoToken 接入与 OpenClaw 环境

2.1 为什么周报生成要接 TaoToken

周报生成脚本最后一步是调模型把结构化数据转成自然语言。这一步需要一个稳定的模型 API 入口。TaoToken 提供统一的模型调用地址,你不需要在脚本里硬编码多家厂商的 key,换模型只改一个配置项。官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基址是 https://taotoken.net/api ,注意 API 地址不带 UTM 参数,配置时别写错。

2.2 拿 Key 与确认模型

登录后进控制台,在 API Keys 页面创建一个新 key,复制保存。这个 key 只显示一次,丢了就重建。创建入口:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。拿到 key 后,建议先去模型对话页面确认你要用的模型能正常响应,避免脚本跑一半报 401。模型对话入口:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 。

2.3 环境要求

Node.js 需要 18 及以上,OpenClaw 的脚本执行依赖它。Python 可选,如果你后续要解析 Excel 或 PDF 会议纪要再装。Git 必须可用,因为周报素材主要来自git log。检查命令:

node --version # 期望 >= 18 git --version # 期望 >= 2.30

2.4 项目目录结构

在本地建一个独立目录,别混在业务仓库里,避免误提交:

mkdir -p ~/workspace/openclaw-weekly cd ~/workspace/openclaw-weekly mkdir -p scripts templates data output touch scripts/collect-git.js scripts/generate-report.js touch templates/report-template.md config.toml .env

目录职责:scripts放采集和生成脚本,templates放周报模板,data放中间产物,output放最终周报,config.toml是 OpenClaw 的编排配置。

3. 可复制配置:config.toml 骨架与脚本代码

3.1 config.toml 完整骨架

OpenClaw 的config.toml决定「什么时候跑、跑什么、用什么模型」。下面这份是周报场景的最小可用配置,字段含义我写在注释里:

# OpenClaw 周报自动化配置 [agent] name = "weekly-report-agent" description = "从 Git 日志生成周报初稿" # 模型接入:指向 TaoToken 统一入口 [model] provider = "openai-compatible" base_url = "https://taotoken.net/api" api_key_env = "TAOTOKEN_API_KEY" # 从环境变量读取,不写死在文件里 model = "claude-sonnet-4-20250514" max_tokens = 4096 temperature = 0.3 # 周报要稳,温度调低 # 任务编排:先采集,再生成 [[tasks]] name = "collect" type = "shell" command = "node scripts/collect-git.js" output = "data/git-log.json" [[tasks]] name = "generate" type = "shell" command = "node scripts/generate-report.js" depends_on = ["collect"] output = "output/weekly-report.md" # 定时触发:每周五 17:00 [schedule] cron = "0 17 * * 5" timezone = "Asia/Shanghai"

注意api_key_env这一行,它让脚本从环境变量读 key,而不是把 key 写进config.toml。这是基本安全习惯,别偷懒。

3.2 环境变量文件

.env内容:

TAOTOKEN_API_KEY=你的key GIT_REPO_PATH=/path/to/your/project OUTPUT_DIR=./output

.env要加进.gitignore,别提交。

3.3 Git 日志采集脚本

scripts/collect-git.js负责把最近 7 天的提交拉出来,按类型分类,输出 JSON:

#!/usr/bin/env node const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); const repoPath = process.env.GIT_REPO_PATH || '.'; const days = 7; function collectCommits() { const since = new Date(Date.now() - days * 86400000) .toISOString().slice(0, 10); const cmd = `git -C ${repoPath} log --since="${since}" ` + `--pretty=format:"%h|%an|%ad|%s" --date=short`; try { const out = execSync(cmd, { encoding: 'utf-8' }); if (!out.trim()) return []; return out.split('\n').map(line => { const [hash, author, date, message] = line.split('|'); return { hash, author, date, message }; }); } catch (e) { console.error('Git 读取失败:', e.message); return []; } } function classify(commits) { const buckets = { feature: [], fix: [], refactor: [], docs: [], other: [] }; commits.forEach(c => { const m = c.message.toLowerCase(); if (m.startsWith('feat')) buckets.feature.push(c); else if (m.startsWith('fix')) buckets.fix.push(c); else if (m.startsWith('refactor')) buckets.refactor.push(c); else if (m.startsWith('docs')) buckets.docs.push(c); else buckets.other.push(c); }); return buckets; } const commits = collectCommits(); const result = { total: commits.length, buckets: classify(commits) }; fs.mkdirSync('data', { recursive: true }); fs.writeFileSync('data/git-log.json', JSON.stringify(result, null, 2)); console.log(`采集完成,共 ${commits.length} 条提交`);

跑一下确认能出数据:

node scripts/collect-git.js cat data/git-log.json

3.4 AI 周报生成脚本

scripts/generate-report.js读取上一步的 JSON,拼 prompt,调 TaoToken,落盘:

#!/usr/bin/env node const fs = require('fs'); const path = require('path'); const API_URL = 'https://taotoken.net/api/v1/chat/completions'; const API_KEY = process.env.TAOTOKEN_API_KEY; async function callModel(prompt) { const res = await fetch(API_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${API_KEY}` }, body: JSON.stringify({ model: 'claude-sonnet-4-20250514', messages: [ { role: 'system', content: '你是周报助手,输出 Markdown,结构清晰,不编造数据。' }, { role: 'user', content: prompt } ], temperature: 0.3 }) }); if (!res.ok) throw new Error(`API ${res.status}: ${await res.text()}`); const data = await res.json(); return data.choices[0].message.content; } function buildPrompt(gitData) { const b = gitData.buckets; const fmt = arr => arr.map(c => `- ${c.message} (${c.hash})`).join('\n') || '- 无'; return `根据以下 Git 提交记录生成周报初稿。 本周提交总数:${gitData.total} 新功能: ${fmt(b.feature)} Bug 修复: ${fmt(b.fix)} 重构: ${fmt(b.refactor)} 文档: ${fmt(b.docs)} 其他: ${fmt(b.other)} 要求: 1. 按「本周完成 / 问题与思考 / 下周计划」三段输出 2. 本周完成部分按功能、修复、其他分组 3. 问题与思考和下周计划留占位符,标注需人工补充 4. 不要编造未在提交中出现的功能`; } async function main() { const raw = fs.readFileSync('data/git-log.json', 'utf-8'); const gitData = JSON.parse(raw); const prompt = buildPrompt(gitData); const report = await callModel(prompt); fs.mkdirSync('output', { recursive: true }); const file = path.join('output', `weekly-${new Date().toISOString().slice(0, 10)}.md`); fs.writeFileSync(file, report, 'utf-8'); console.log(`周报已生成:${file}`); } main().catch(e => { console.error(e.message); process.exit(1); });

4. 端到端验证:跑一次看结果

4.1 设置环境变量并执行

export $(cat .env | xargs) node scripts/collect-git.js node scripts/generate-report.js

4.2 预期输出

output/weekly-2025-XX-XX.md里应该出现类似结构:

## 本周完成 ### 新功能 - 完成用户登录模块 (a1b2c3d) - 新增订单查询接口 (m0n1o2p) ### Bug 修复 - 修复 token 过期问题 (e4f5g6h) ## 问题与思考 > 待补充 ## 下周计划 > 待补充

4.3 用 OpenClaw 编排执行

如果你已经装好 OpenClaw CLI,直接:

openclaw run --config config.toml

它会按[[tasks]]顺序先跑采集再跑生成。看到周报已生成就说明链路通了。想手动触发模型对话验证 key 是否有效,可以去 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 发一条测试消息。

5. 本篇常见错排查

5.1 401 Unauthorized

九成是TAOTOKEN_API_KEY没导出。检查echo $TAOTOKEN_API_KEY是否有值。如果.env里写了但没export,脚本读不到。另一个可能是 key 复制时带了空格,重新去 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 复制一次。

5.2 Git 读取为空

GIT_REPO_PATH指向的目录不是 Git 仓库,或者最近 7 天确实没提交。先用git -C $GIT_REPO_PATH log --oneline -5确认。如果仓库在子目录,路径要写对。

5.3 模型返回内容被截断

max_tokens设太小。周报如果提交多,4096 可能不够,调到 8192。同时检查temperature,设太高会导致输出发散,周报场景 0.2 到 0.4 之间比较稳。

5.4 config.toml 解析报错

TOML 对缩进和引号敏感。base_url必须带引号,cron表达式用双引号。如果报expected key,检查是不是用了 Tab 缩进,统一用空格。

5.5 脚本找不到模块

collect-git.js和generate-report.js用的是 Node 内置模块,不需要npm install。如果你加了dayjs之类的依赖,记得在项目根目录npm init -y && npm install dayjs。

6. 长期编码与 Agent 场景的延伸

周报只是 OpenClaw 的一个入口场景。同样的config.toml结构,你可以把collect任务换成拉 Jira 任务、拉会议纪要、拉代码评审记录,generate任务换成生成项目周报、迭代总结、风险预警。如果你打算把这类自动化长期跑在编码流程里,比如让 Agent 每天自动整理提交、生成 changelog、甚至辅助 code review,可以了解 Coding Plan 的接入方式:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有完整的 API 参数和错误码说明,排障时对着查比猜快。

我自己的习惯是每周五 16:50 让 OpenClaw 先跑一遍采集和生成,17:00 收到草稿后只补「问题与思考」和「下周计划」两段,十分钟内交掉。模板放在templates/report-template.md,改样式不用动脚本。先跑通,再迭代,别一上来就追求完美模板。

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

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

立即咨询