周五下午的日报,写不出手

周五下午 4 点,打开飞书文档,要写周报和日报。我盯着屏幕想了十分钟,昨天开了三个会,上午改了个 bug,下午好像在建报表。具体细节?记不清了。这种时刻多了,我就琢磨着能不能让 AI 自己把日报写了。我试过把聊天记录粘给 DeepSeek 网页版,让它生成,但每次都粘来粘去,聊天记录里一半是表情包,生成出来的日报全是废话。后来换了个思路:让 Agent 自己去看代码仓库、看文件变化、看命令历史,然后调 DeepSeek 生成。这套东西用 Hermes 搭,从装到跑通,大概花了 20 分钟。

先装 Hermes。我用的是 Python 3.11,一台 Windows 11 的笔记本,一台 Ubuntu 22.04 的服务器,都装上了。命令很简单:

pip install hermes-agent

装完跑一下 hermes --version,能输出版本号就行。我装的是 0.4.2。如果你用 Python 3.12 以上,可能会碰到一个报错,说 pydantic-core 编译不过去,报错信息里会带 Rust 工具链的字样。解决办法别去折腾 Rust,直接装 Python 3.11,用 conda 或者 pyenv 都行,两分钟搞定。

还有个小坑:在公司内网 pip 装包容易超时,报一堆 Read timed out。换国内镜像:

pip install hermes-agent -i https://pypi.tuna.tsinghua.edu.cn/simple

装完先别急着配东西,跑一下 hermes doctor,它会检查 Python 环境、配置文件路径、Git 依赖之类的。我第一次跑的时候它提示 Git 没找到,因为 Windows 上没把 Git 的 bin 目录加进 PATH。把 C:\Program Files\Git\bin 加进去,重新跑一次就过了。

把 DeepSeek 接进 Hermes

Hermes 的配置文件在 ~/.hermes/config.yaml,没有就手动建一个。我用的配置长这样:

provider: deepseek
api_key: sk-你的key
base_url: https://api.deepseek.com/v1
model: deepseek-chat

model 那行容易写错。有人写 deepseek-v3,有人写 deepseek-r1,实际上去 DeepSeek 开放平台看一眼,对话模型的名字是 deepseek-chat,推理模型是 deepseek-reasoner。写错了会报 404 model not found,不是 401。我第一次就写成了 deepseek-v3,报错之后去平台查文档才发现。

api_key 要去 platform.deepseek.com 申请,新建一个,格式是 sk- 开头的一长串。别用网页版对话里的那个 key,那个不是 API key。配好了跑个测试:

hermes run "用一句话介绍你自己"

能正常输出就说明 DeepSeek 通了。这里有个容易忽略的点:DeepSeek 的 API 兼容 OpenAI 格式,但 base_url 要写全,https://api.deepseek.com/v1https://api.deepseek.com 都行。如果你用的是 one-api 或者 new-api 之类的网关,base_url 要换成网关的地址,这个看你的部署情况。

DeepSeek 的计费是输入 2 元/百万 tokens,输出 8 元/百万 tokens,一篇日报大概消耗 800 tokens,成本不到一分钱,随便跑。

还有个小问题:如果你在服务器上跑,注意环境变量。Hermes 会读 DEEPSEEK_API_KEY 这个环境变量,而且它的优先级比 config.yaml 高。我一开始在服务器上 .env 里写了个旧 key,配置文件怎么改都不生效,就是这个原因。把环境变量清掉,或者更新 .env 里的值就好了。

写一个日报技能

Hermes 的技能放在 ~/.hermes/skills/ 下,每个技能一个目录。我建了一个 daily-report:

~/.hermes/skills/daily-report/skill.yaml
~/.hermes/skills/daily-report/script.py

skill.yaml 里写:

name: daily-report
description: 自动收集今日工作内容并生成日报
script: script.py

script.py 是真正干活的东西。逻辑分三步:收集数据、拼 prompt、调 DeepSeek 生成。收集数据我用 Git 和文件系统。假设你一天的工作都在代码仓库里,那 git log 就是最好的素材。在 script.py 里跑命令:

git log --since="24 hours ago" --pretty=format:"%h %s" --author="你的名字"

这条命令列出最近 24 小时你的提交记录。如果你用 Jira 或者飞书,也可以把任务列表导出来,拼接进去。拼 prompt 的时候,我给 DeepSeek 一个模板,要求它输出这样的结构:

- 今日完成:
- 遇到的问题:
- 明日计划:

第一次写 script.py 的时候,我犯了个错:直接把 git log 塞进 prompt,没有做裁剪。结果提交记录一多,token 超了,DeepSeek 报 400 错误,提示 context length exceeded。解决办法是把提交记录按时间排序后,只取前 50 条,每条限制 80 个字符以内。代码里加一行截断就行。

另一个报错是 YAML 缩进问题。skill.yaml 里如果 description 写太长,换行时没有对齐,Hermes 解析会报 yaml.parser.ParserError。注意用两个空格缩进,别用 Tab。

写完后测试:

hermes skill run daily-report

它会执行 script.py,把结果打印出来。第一次跑的时候,脚本报 python 找不到模块,原因是 Hermes 用的是当前环境的 Python,而脚本里 import 了 requests,这个库没装。在 script.py 里改用 urllib,或者 pip install requests 都行。我图省事,直接用了 urllib。

让日报更像人话

光有 git log 生成的东西,读起来像流水账。我给 script.py 加了两个数据源:文件修改记录和终端历史。文件修改记录用 find 命令:

find . -type f -mtime -1 -not -path "./node_modules/*" | head -50

这条命令列出最近一天改过的文件,排除 node_modules。终端历史读 ~/.bash_history 或者 ~/.zsh_history,取最后 50 条,去掉重复。这两个数据源拼进 prompt 之后,DeepSeek 生成的日报从"修复了登录页 bug",变成了"排查登录页验证码失效的问题,定位到是 Redis 缓存 key 过期导致,已修复并补了测试"。这个变化还是比较明显的。

这个阶段会遇到一个比较烦的问题:DeepSeek 的输出偶尔带 Markdown 格式,比如 # 标题、** 加粗。日报要发到飞书或者钉钉,这些格式符号就很碍眼。我在 script.py 里加了一步清洗,用正则把 Markdown 符号去掉,再把连续空行合并:

import re
text = re.sub(r"[#>*_`]", "", text)
text = re.sub(r"\n{3,}", "\n\n", text)

还有一个细节:日报里的人称。DeepSeek 默认会用"我们"开头,比如"我们修复了什么问题"。但日报是个人日报,用"我"更合适。在 prompt 里明确写一句"使用第一人称,主语是我",输出的风格就对了。这个不改的话,每篇日报读起来都像团队周报。

如果当天 git 记录是空的,script.py 会拿到空字符串,这时候 DeepSeek 会瞎编,生成一堆没发生过的内容。我在脚本里加了个判断:如果数据源加起来不到 20 个字符,就输出"今日无代码提交记录",不调用 API。省 token,也避免编造。

用 cron 定时跑起来

日报要每天自动生成,得挂定时任务。Hermes 自带 cron 功能,命令是:

hermes cron create --name daily-report --schedule "0 18 * * *" --skill daily-report

意思是每天 18:00 执行 daily-report 技能。看到输出 cron created 就成功了。列出任务用 hermes cron list,删除用 hermes cron remove daily-report

这里有个大坑:Hermes 的 cron 默认用服务器本地时区。我服务器是 UTC 时区,18 点执行实际上成了北京时间凌晨 2 点。解决方式是在 config.yaml 顶层加一行:

timezone: Asia/Shanghai

改完重启 hermes 服务,再 hermes cron list 看一下,输出里会显示 next run 时间,确认和你预期的一致。

还有一个坑:cron 任务执行后,结果不会自动发到任何地方。它只是生成了日报文本,存在日志里。我写了个简单的推送:在 script.py 里,生成完日报后,调用飞书自定义机器人的 webhook,把文本 POST 过去。飞书 webhook 地址形如 https://open.feishu.cn/open-apis/bot/v2/hook/xxxx-xxxx,POST 一个 JSON 过去,{"msg_type": "text", "content": {"text": "..."}},十几行代码就能搞定。钉钉的话接口类似,就是加签逻辑稍微麻烦一点。

如果你不想折腾 webhook,也可以让 Hermes 把日报写到文件里,比如 ~/daily-report/2025-06-14.md,然后自己打开看。我是在服务器上配了飞书推送,下班路上在手机上看一眼就完事。

定时任务跑挂了怎么排查?先看 Hermes 的日志,一般在 ~/.hermes/logs/ 下。常见报错是 cron 里的 Python 环境找不到模块,或者 git 命令在 cron 环境里没有 PATH。解决办法是在 script.py 开头强制指定环境变量:

import os
os.environ["PATH"] = "/usr/local/bin:/usr/bin:/bin"

这个坑我踩过,cron 环境下 PATH 很精简,git 和 python 都可能找不到。

用 memory 让日报更聪明

跑了一周,日报基本能用了,但有个问题:它记不住上下文。周一你查了某个 bug,周二日报里它不会关联。Hermes 有个 memory 功能,可以存一些长期信息。用法很简单:

hermes memory add "项目 X 的登录服务在 6 月 10 日重构过,入口在 auth/login.go"
hermes memory list

存进去之后,写日报的技能可以把 memory 里的内容也拼进 prompt。比如"今天改的文件涉及上次重构的登录模块",DeepSeek 就能结合记忆里的背景,写出来的日报更有连续性。我在 script.py 里加了一行调用:

import subprocess
mem = subprocess.run(["hermes", "memory", "list"], capture_output=True, text=True).stdout

然后把 mem 拼进 prompt 的末尾,告诉 DeepSeek "以下是相关历史记忆,如果有用就参考,没用就忽略"。这样日报不会跑偏。

memory 存多了也有问题:内容太杂,拼进 prompt 会浪费 token。我后来只存那些跨天相关的事情,比如某个模块的架构调整、某个线上问题的处理方案。临时性的内容不存。删除用 hermes memory delete <id>,id 在 hermes memory list 里能看到。

到这里,整个链路是通的:cron 每天 18 点触发 → script.py 收集 git log、文件修改、终端历史 → 调 DeepSeek 生成日报 → 清洗 Markdown → 推送到飞书。整个过程不需要人参与,我只需要在周五下午打开飞书,把日报复制粘贴到公司系统里。

💬 你用过哪些AI工具?

这套东西跑起来之后,我身边的同事也开始折腾类似的自动化。有人用 Claude 写周报,有人用 Gemini 做会议纪要,还有人直接用 ChatGPT 的定时任务。每个工具都有自己的脾气,DeepSeek 便宜,Hermes 灵活,搭配起来干活还行。你平时用哪些 AI 工具?有没有自己搭过类似的自动化流程?如果你还没想好选哪个模型,可以去 AI House 排行榜(aibunkhouse.com/rankings/)看看最新的模型排名,给喜欢的模型投一票,说不定能找到更适合你的组合。

常见问题 / FAQ

周五下午的日报,写不出手

周五下午 4 点,打开飞书文档,要写周报和日报。我盯着屏幕想了十分钟,昨天开了三个会,上午改了个 bug,下午好像在建报表。具体细节?记不清了。这种时刻多了,我就琢磨着能不能让 AI 自己把日报写了。我试过把聊天记录粘给 DeepSeek 网页版,让它生成,但每次都粘来粘去,聊天记录里一半是表情包,生成出来的日报全是废话。后来换了个思路:让 Agent 自己去看代码仓库、看文件变化、看命令历史,...

把 DeepSeek 接进 Hermes

Hermes 的配置文件在 ~/.hermes/config.yaml,没有就手动建一个。我用的配置长这样: provider: deepseek api_key: sk-你的key base_url: https://api.deepseek.com/v1 model: deepseek-chat model 那行容易写错。有人写 deepseek-v3,有人写 deepseek-r1,实际上...

写一个日报技能

Hermes 的技能放在 ~/.hermes/skills/ 下,每个技能一个目录。我建了一个 daily-report: ~/.hermes/skills/daily-report/skill.yaml ~/.hermes/skills/daily-report/script.py skill.yaml 里写: name: daily-report description: 自动收集今日工作内...

让日报更像人话

光有 git log 生成的东西,读起来像流水账。我给 script.py 加了两个数据源:文件修改记录和终端历史。文件修改记录用 find 命令: find . -type f -mtime -1 -not -path "./node_modules/*" | head -50 这条命令列出最近一天改过的文件,排除 node_modules。终端历史读 ~/.bash_history 或者 ~...

用 cron 定时跑起来

日报要每天自动生成,得挂定时任务。Hermes 自带 cron 功能,命令是: hermes cron create --name daily-report --schedule "0 18 * * *" --skill daily-report 意思是每天 18:00 执行 daily-report 技能。看到输出 cron created 就成功了。列出任务用 hermes cron lis...