1. 项目概述:这不是一个“发文章”的工具,而是一套可落地的AI内容工作流闭环
你有没有过这样的经历:写完一篇技术博客,从本地 Markdown 文件开始,要手动复制粘贴到后台编辑器、调整图片路径、补上标签分类、检查链接有效性、选发布时间、再点发布——整个过程看似简单,但每月重复20次,就消耗掉整整半天时间。更别提遇到平台接口更新、图片CDN失效、摘要截断异常这些“小问题”,每次都要临时排查半小时。Hermes Agent 就是为解决这类高频、确定、重复但又不能完全交给脚本黑盒处理的场景而生的。它不是传统意义上的“一键发布”插件,也不是大模型直接生成全文的玩具项目,而是一个以AI为调度中枢、以开发者意图为核心、以多平台兼容为底线的技术博客自动化系统。核心关键词包括:Hermes Agent、AI驱动、技术博客、自动发布、内容工作流、Markdown处理、平台适配、发布校验。它面向的是有稳定输出习惯的中高级开发者、技术团队内容运营者、以及希望把写作精力聚焦在“思考”而非“操作”上的独立博主。我用它在三个月内将个人博客发布耗时从平均47分钟/篇压缩到6分半,且零误发、零格式错乱、零图片丢失。下面所有内容,都来自真实部署在某云服务器上的生产环境记录,不讲概念,只说怎么跑起来、怎么调得稳、怎么防踩坑。
2. 整体架构设计与核心思路拆解:为什么必须是“Agent”,而不是“Script”
2.1 拒绝“脚本思维”:从线性执行到意图理解的范式转变
很多人第一反应是:“不就是个curl发请求吗?写个Python脚本不就完了?”——这恰恰是绝大多数失败尝试的起点。我试过三个版本:V1是纯 Bash 脚本,靠 sed 和 awk 处理 Markdown;V2 是 Python + requests,封装了各平台 API;V3 才引入 Hermes Agent 架构。前两个版本在单平台、固定模板下能跑通,但只要换一个平台(比如从 WordPress 切到 Hexo 静态站),或增加一个需求(比如“检测文中是否含未声明的第三方库引用,自动加免责声明”),就得重写 70% 逻辑。根本问题在于:它们是面向操作步骤的,而 Hermes Agent 是面向发布意图的。
举个具体例子:当你说“把这篇关于 Rust 异步运行时的文章,按技术博客规范发布到知识库平台,并同步推送到内部 Wiki”,传统脚本会逐条执行:①读取文件 → ②提取标题 → ③替换图片路径 → ④调用平台 A 的 POST /api/v1/posts → ⑤调用平台 B 的 webhook。而 Hermes Agent 的处理流程是:①接收原始 Markdown + 用户指令 → ②由 LLM 解析“技术博客规范”具体指什么(比如标题需含【Rust】前缀、代码块必须带语言标识、文末需加“本文基于 rustc 1.78 编写”)→ ③生成结构化任务清单(含校验项、转换规则、目标平台字段映射)→ ④交由专用模块执行,每个模块只关心自己那部分“是否达标”,不关心其他环节。这种设计让新增一个平台,只需新增一个“适配器模块”,无需动核心调度逻辑。
提示:Hermes Agent 的核心价值不在“快”,而在“可演进”。当你第5次修改发布规则时,脚本方案可能已面目全非,而 Agent 方案只需更新提示词和校验规则。
2.2 三层模块化结构:分离关注点,保障长期可维护性
Hermes Agent 不是一个单体程序,而是明确划分为三个协作层:
Orchestrator(调度层):基于轻量级 LLM(实测使用 Qwen2-1.5B-Instruct 本地部署,4GB 显存即可运行)作为“大脑”。它不直接处理文件或调用 API,只做三件事:①解析用户自然语言指令(如“跳过图片上传,用本地相对路径”);②将原始 Markdown 拆解为语义块(标题、正文、代码段、图片引用、参考文献);③根据当前配置,生成带优先级的任务序列(例如:先校验链接有效性,再处理图片,最后生成摘要)。它的输出永远是 JSON 格式的任务描述,不含任何平台相关代码。
Adapter(适配层):这是真正对接各平台的“手脚”。每个平台(WordPress、Notion、语雀、自建 Hexo)都有独立 Adapter,只接收 Orchestrator 发来的标准化任务包,并返回结构化结果。比如 WordPress Adapter 收到任务包后,会:①用 wp-cli 验证用户权限;②调用 REST API 创建草稿;③上传图片到媒体库并替换 Markdown 中的 src;④设置分类、标签、特色图像。关键在于:Adapter 内部可以自由选择技术栈(PHP、Node.js、Python),只要输入输出协议一致,就能即插即用。
Validator(校验层):这是保证质量的“守门人”。它在每个关键节点插入校验点:发布前检查图片是否全部可访问(HTTP 200)、代码块语言标识是否缺失(正则匹配 ```[a-z]+)、外部链接是否超时(curl -I -s -w "%{http_code}" -o /dev/null $url)、摘要长度是否在 120~180 字之间。校验失败不中断流程,而是生成带修复建议的报告(如“第3张图返回 404,建议检查 ./assets/flowchart.png 路径”),由 Orchestrator 决定是暂停、跳过还是自动重试。
这种分层不是为了炫技,而是为了解决一个现实问题:技术博客平台生命周期远短于内容本身。过去三年,我用过的发布平台换了4个,但 Orchestrator 的提示词只更新过2次,Adapter 层新增了3个,Validator 规则增加了5条——所有变更都互不影响。
2.3 为什么坚持本地轻量模型:响应速度、数据主权与调试确定性
有人会问:“既然用 LLM,为什么不直接调用 GPT-4 或 Claude?”答案很实在:延迟、成本、可控性。我做过压测:在 100 篇博客批量发布场景下,调用 OpenAI API 平均单篇等待 3.2 秒(含网络往返),而本地 Qwen2-1.5B 推理耗时稳定在 0.8 秒以内。更重要的是,当某天你发现发布的摘要总是漏掉关键参数(比如“支持 up to 16 cores”被截断),用本地模型你可以直接看 token 输出、改提示词、重跑验证;而闭源 API 你只能猜、只能试、只能等官方更新。另外,技术博客常含未公开的架构图、内部 API 文档片段,本地部署杜绝了敏感内容外泄风险。我们不是不用大模型,而是把它当作一个可调试、可预测、可审计的组件,而非黑盒服务。
3. 核心细节解析与实操要点:从配置到校验的每一处关键决策
3.1 Orchestrator 提示词设计:用“技术文档思维”写 AI 指令
Orchestrator 的效果,90% 取决于提示词质量。我放弃了一切花哨的“角色扮演”写法(如“你是一位资深技术编辑…”),转而采用技术规格说明书风格。以下是我当前生产环境使用的提示词主干(已脱敏):
你是一个技术博客发布调度器,严格按以下规则工作: 1. 输入:原始 Markdown 文件内容 + 用户指令(可能为空) 2. 输出:仅 JSON,无任何额外字符,格式: { "title": "提取的标题(去除#号,保留中文标点)", "summary": "生成150字内摘要,必须包含首段核心结论和关键技术指标", "image_tasks": [ { "original_path": "assets/diagram.png", "target_platform": "wordpress", "upload_required": true, "alt_text": "Rust Tokio 运行时架构图" } ], "code_blocks": [ { "language": "rust", "line_count": 24, "has_language_tag": true } ], "external_links": ["https://docs.rs/tokio/latest/tokio/"], "validation_rules": ["summary_length:120-180", "code_block_lang_tag:true"] } 3. 特别注意:若用户指令含“跳过图片上传”,则所有 image_tasks.upload_required = false; 若含“强制用绝对路径”,则 image_tasks.target_platform = "absolute"; 若含“添加免责声明”,则在 summary 末尾追加“【免责声明】本文内容基于实验环境验证...”这个提示词的关键在于:明确输入输出契约、定义原子化字段、用布尔值/枚举值代替模糊描述、将用户指令转化为确定性开关。我测试过,当提示词里写“请尽量生成好摘要”时,LLM 会自由发挥,有时加表情符号,有时漏关键参数;而写“summary 必须包含首段核心结论和关键技术指标”,它就老老实实从首段抽主谓宾+数值。这不是 AI 能力问题,而是接口定义问题。
注意:提示词必须配合严格的输出 Schema 校验。我在 Orchestrator 里加了 JSON Schema 验证,如果 LLM 返回了非法 JSON(比如多了逗号、少了引号),直接报错退出,绝不尝试修复——因为修复很可能引入新错误。宁可人工介入,也不让不确定输出流入下游。
3.2 Adapter 层的平台适配策略:不是“支持越多越好”,而是“每个都稳如磐石”
目前 Hermes Agent 官方维护 4 个 Adapter:WordPress、Notion、语雀、Hexo CLI。选择标准很功利:该平台是否占我实际发布量的 15% 以上?是否有稳定 API?是否允许自动化操作?我曾想加入知乎专栏 Adapter,但测试发现其 Web API 无文档、反爬极严、Token 有效期仅 2 小时,维护成本远超收益,果断放弃。
以 WordPress Adapter 为例,它的健壮性体现在三个细节:
权限降级设计:不依赖管理员账号,而是创建专用发布账号,仅授予
edit_posts和upload_files权限。即使账号密钥泄露,攻击者也无法删库或改主题。幂等性保障:每次发布前,先用
wp post list --post_status=draft --format=ids获取草稿 ID,再用wp post update [ID] --post_status=publish发布。避免重复创建导致草稿堆积。图片上传智能 fallback:当
wp media import失败(常见于大图超时),自动切换为curl -F "file=@./assets/xxx.png" -u user:pass https://site.com/wp-json/wp/v2/media,并重试 2 次。失败后才标记upload_required:false并记录日志。
Notion Adapter 则完全不同:它不走官方 API(速率限制太严),而是解析用户导出的 Notion 页面 HTML,用 Cheerio 提取结构,再通过 Notion 的私有 API(逆向工程所得,已封装为稳定 SDK)提交。这听起来“不正规”,但实测成功率 99.8%,且不受官方配额影响。技术选型没有对错,只有“是否解决我的问题”。
3.3 Validator 校验规则的工程化实现:从“能跑”到“敢发”的最后一道防线
校验不是摆设,而是发布前的“压力测试”。我的 Validator 包含 7 类硬性规则,全部可配置、可开关、可定制阈值:
| 校验类型 | 触发时机 | 默认阈值 | 处理方式 | 实际案例 |
|---|---|---|---|---|
| 图片可用性 | 发布前 | HTTP 200 | 失败则标记upload_required:true并报路径 | 本地开发时./assets/路径在服务器不存在,自动触发上传 |
| 外链存活 | 发布前 | 响应时间 < 3s,状态码 200/301/302 | 失败则记录警告,不阻断 | 某文档链接指向已关闭的 GitHub Gist,自动替换为存档链接 |
| 摘要长度 | Orchestrator 输出后 | 120~180 字 | 超出则重新生成 | 技术术语过多导致摘要过长,LLM 自动精简修饰词 |
| 代码块标识 | Markdown 解析后 | language字段存在且非空 | 缺失则插入<!-- CODE_LANG_MISSING -->注释 | 旧文迁移时大量 ```` 未标注语言,自动补rust |
| 标题层级 | Markdown 解析后 | 最高为##(二级标题) | 发现###以上则告警 | 团队规范要求技术博客不出现三级以下标题,强制统一 |
| 敏感词扫描 | 全文扫描 | 自定义词库(含公司名、未公开API名) | 发现则暂停并邮件通知 | 某次误将内部测试域名写入博客,及时拦截 |
| 平台字段映射 | Adapter 输入前 | 各平台必填字段(如 WordPress 的categories) | 缺失则用默认值填充 | Notion 数据库无分类字段,自动映射到Tags属性 |
所有校验结果生成 HTML 报告,包含截图、原始片段、修复建议。我把它集成到 CI 流程中:每次git push到publish分支,自动触发校验,只有报告全绿才允许进入发布队列。这比“人眼扫一遍”可靠十倍。
4. 实操过程与核心环节实现:从零部署到稳定运行的完整路径
4.1 环境准备与依赖安装:避开最经典的“权限地狱”
Hermes Agent 对环境要求不高,但几个细节决定成败。我推荐在 Ubuntu 22.04 LTS 上部署(Docker 也支持,但本地部署更易调试):
# 1. 安装基础依赖(注意:必须用 apt,不要用 snap) sudo apt update && sudo apt install -y \ python3-pip \ python3-venv \ curl \ git \ jq \ # WordPress Adapter 需要 wp-cli wget && sudo wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -O /usr/local/bin/wp && sudo chmod +x /usr/local/bin/wp # 2. 创建专用用户(严禁用 root!) sudo adduser --disabled-password --gecos "" hermes sudo usermod -aG www-data hermes sudo su - hermes # 3. 初始化项目目录 mkdir -p ~/hermes/{config,posts,logs,adapters} cd ~/hermes # 4. 创建虚拟环境(关键!避免系统 Python 冲突) python3 -m venv venv source venv/bin/activate # 5. 安装核心包(注意版本锁定) pip install --upgrade pip pip install torch==2.1.0+cpu torchvision==0.16.0+cpu -f https://download.pytorch.org/whl/torch_stable.html pip install transformers==4.35.2 accelerate==0.25.0 sentence-transformers==2.2.2 pip install markdown-it-py==3.0.0 mdit_py_plugins==0.4.0注意:PyTorch 版本必须严格匹配。我曾因升级到 2.2.0 导致 Qwen2 模型加载失败,报错
Unsupported device type,回退到 2.1.0+cpu 后立即解决。这不是 bug,而是模型编译时的 CUDA 版本绑定问题。
4.2 模型下载与量化:在 4GB 显存上跑通 Qwen2-1.5B
Qwen2-1.5B 是 Hermes Agent 的推理基石。官方提供 FP16 和 INT4 两种权重,我选择 INT4 量化版(Qwen2-1.5B-Instruct-GGUF),原因很实际:FP16 占用显存 3.2GB,INT4 仅 1.1GB,且实测推理质量损失小于 2%(用 BLEU 分数评估摘要一致性)。下载与加载步骤如下:
# 进入模型目录 cd ~/hermes/config # 下载 GGUF 量化模型(约 1.2GB) wget https://huggingface.co/Qwen/Qwen2-1.5B-Instruct-GGUF/resolve/main/qwen2-1.5b-instruct.Q4_K_M.gguf # 创建模型配置文件 model_config.json cat > model_config.json << 'EOF' { "model_path": "./qwen2-1.5b-instruct.Q4_K_M.gguf", "n_ctx": 2048, "n_threads": 4, "n_gpu_layers": 20, "temperature": 0.3, "top_p": 0.9, "repeat_penalty": 1.1 } EOF关键参数说明:
n_gpu_layers: 20:将前 20 层 offload 到 GPU,剩余在 CPU。实测 20 层时 GPU 显存占用 1.05GB,推理速度 18 tokens/s;设为 30 层会爆显存。temperature: 0.3:降低随机性,确保摘要、标题提取结果稳定。温度太高会导致同一篇文生成不同摘要。repeat_penalty: 1.1:轻微惩罚重复词,避免“的的的”、“是是是”等现象。
加载时用 llama.cpp 的 Python binding(llama-cpp-python),而非 HuggingFace Transformers,因为前者对 GGUF 支持更好,内存占用更低。
4.3 配置文件详解:一份 config.yaml 背后的 17 个决策点
config.yaml是 Hermes Agent 的“宪法”,它决定了整个系统的行为边界。以下是生产环境完整配置(已脱敏),每行都附带决策理由:
# 全局配置 global: log_level: INFO # DEBUG 仅调试时开启,否则日志爆炸 max_retries: 3 # 网络请求失败重试次数,3 次足够覆盖瞬时抖动 timeout: 30 # 单个操作超时秒数,避免卡死 # Orchestrator 配置 orchestrator: model_config: "./config/model_config.json" # 指向上面创建的模型配置 prompt_template: "./config/prompt_v3.txt" # 提示词文件路径 # 关键:启用缓存加速重复指令处理 cache_enabled: true cache_ttl: 3600 # 缓存 1 小时,避免相同文章反复解析 # Adapter 配置(按需启用) adapters: wordpress: enabled: true url: "https://your-blog.com" username: "hermes_publisher" password: "APP_PASSWORD_HERE" # 用 WordPress App Password,非登录密码 # 图片上传策略:开发环境用本地路径,生产环境强制上传 upload_images: true notion: enabled: true integration_token: "secret_xxx" # Notion Integration Token database_id: "xxx" # 目标数据库 ID yuque: enabled: true token: "yuque_xxx" # 语雀 Personal Token repo_slug: "tech-blog" # 仓库 Slug hexo: enabled: true site_path: "/var/www/hexo-site" # Hexo 站点根目录 theme: "next" # 主题名,用于生成封面图 # Validator 规则 validator: rules: image_availability: enabled: true timeout: 5 external_link_health: enabled: true max_response_time: 3 allowed_status_codes: [200, 301, 302] summary_length: enabled: true min: 120 max: 180 code_block_language: enabled: true sensitive_word_scan: enabled: true wordlist_path: "./config/sensitive_words.txt" # 自定义敏感词文件 # 发布策略 publish_strategy: # 每次最多并发发布 2 篇,避免平台限流 max_concurrent: 2 # 草稿模式:true 时只生成草稿不发布,用于预览 draft_mode: false # 时间偏移:所有发布时间 +2 小时,适配不同时区团队 time_offset_hours: 2这份配置背后是 17 次失败迭代:比如max_concurrent从 5 降到 2,是因为 WordPress 在并发 3 个图片上传时会返回 503;time_offset_hours是为跨国团队加的,避免北京同事写的“今晚 8 点发布”在旧金山变成凌晨 4 点。
4.4 一次完整的发布流程实录:从命令行到平台生效
现在,让我们走一遍真实发布流程。假设你刚写完一篇 Markdown 文件~/hermes/posts/rust-async-basics.md,内容如下(节选):
# Rust 异步编程入门:从 Future 到 Executor 异步编程是 Rust 的核心竞争力之一。本文带你从零理解 Future trait...  ```rust async fn hello_world() -> Result<(), Box<dyn std::error::Error>> { println!("Hello, world!"); Ok(()) }参考: Tokio 官方文档
执行发布命令: ```bash # 切换到项目目录 cd ~/hermes source venv/bin/activate # 执行发布(指定文件、平台、附加指令) python main.py \ --input posts/rust-async-basics.md \ --platform wordpress \ --instruction "添加免责声明,跳过图片上传,摘要强调性能指标"系统输出(精简):
[INFO] 开始处理: posts/rust-async-basics.md [INFO] Orchestrator: 加载模型中... [INFO] Orchestrator: 解析完成,生成任务包(摘要长度162字,图片上传禁用) [INFO] Validator: 图片 assets/tokio-arch.png 可用(200) [INFO] Validator: 外链 https://tokio.rs/docs 存活(200, 0.42s) [INFO] Validator: 摘要长度合规(162/120-180) [INFO] Validator: 代码块语言标识正确(rust) [INFO] Adapter(WordPress): 创建草稿 ID 12345 [INFO] Adapter(WordPress): 设置分类为 "Rust", 标签为 "async,future" [INFO] Adapter(WordPress): 插入免责声明到摘要末尾 [INFO] Adapter(WordPress): 草稿已保存,预览链接: https://your-blog.com/?p=12345&preview=true [SUCCESS] 发布完成!耗时 8.3 秒打开预览链接,你会看到:
- 标题自动变为【Rust】Rust 异步编程入门:从 Future 到 Executor(前缀由提示词规则注入)
- 摘要末尾有灰色小字:“【免责声明】本文内容基于 rustc 1.78 和 tokio 1.33 实验验证...”
- 图片仍为
assets/tokio-arch.png相对路径(因指令禁用上传) - 代码块显示正常,语言标识
rust清晰可见 - 外链
https://tokio.rs/docs可点击跳转
整个过程无人工干预,且每一步都有日志可查。这才是“自动发布”的应有之义。
5. 常见问题与排查技巧实录:那些文档里不会写的血泪教训
5.1 “模型加载失败:CUDA out of memory” —— 显存不够的终极解法
这是新手最高频报错。表面看是显存不足,但根源常是配置错误。我的排查清单:
确认
n_gpu_layers是否过高:用nvidia-smi查看当前显存占用,如果已有其他进程占 2GB,n_gpu_layers设为 20 就必然爆。公式:预估显存 = 1.1GB + (n_gpu_layers * 0.05GB)。安全起见,从 10 开始试。检查 PyTorch 是否真的用 GPU:在 Python 中运行
import torch; print(torch.cuda.is_available()),返回False说明没装对版本。Ubuntu 上必须用pip install torch==2.1.0+cpu(CPU 版),GPU 版要额外装 CUDA Toolkit。终极方案:强制 CPU 推理:在
model_config.json中设"n_gpu_layers": 0,虽然慢 3 倍(约 6 tokens/s),但 100% 稳定。对于日更博主,8 秒 vs 24 秒,差别不大。
5.2 “WordPress 发布后图片显示 404” —— 路径、权限、CDN 的三重陷阱
这个问题我踩过三次坑,每次原因都不同:
第一次:服务器 Nginx 配置未开放
assets/目录。解决方案:在站点配置中加location /assets/ { alias /home/hermes/hermes/posts/assets/; }。第二次:WordPress 媒体库上传后,图片 URL 是
https://blog.com/wp-content/uploads/2024/05/xxx.png,但 Markdown 里写的是/wp-content/uploads/...,相对路径解析错误。解决方案:在 WordPress Adapter 中,将wp media import返回的 URL 提取uploads/后路径,再拼接到。第三次:CDN 缓存了旧的 404 响应。解决方案:发布后自动调用 CDN 刷新 API,或给图片 URL 加时间戳参数
?t=1715234567。
实操心得:永远在发布后执行
curl -I https://your-blog.com/assets/tokio-arch.png,看返回状态码。别信浏览器缓存。
5.3 “Notion 发布后格式全乱” —— HTML 解析的隐藏雷区
Notion Adapter 基于 HTML 解析,而 Notion 导出的 HTML 充满<div class="notion-text">这类无语义标签。我的应对策略:
不依赖 class 名:用 CSS 选择器
div[data-block-id]定位区块,这是 Notion 唯一稳定的属性。代码块特殊处理:Notion 的代码块导出为
<pre><code class="language-rust">...</code></pre>,但其class值可能是language-rust或lang-rust。Adapter 中用正则r'language-(\w+)|lang-(\w+)'提取语言,兼容两种格式。图片尺寸丢失:Notion 导出 HTML 中图片无宽高属性,导致发布后拉伸。解决方案:在 Adapter 中,用 Pillow 读取本地图片获取尺寸,再注入 HTML 的
style="width:800px;height:auto;"。
5.4 “敏感词扫描误报” —— 如何平衡安全与误伤
某次,sensitive_words.txt里写了test,结果所有含testing、contest的句子都被标红。修正方案:
用单词边界锚定:正则改为
\btest\b,确保只匹配独立单词test。分级敏感词:
critical级(如公司名)触发阻断;warning级(如test)只告警不阻断。上下文豁免:在提示词中加规则“若敏感词出现在代码块或 URL 中,忽略扫描”。因为
https://test-api.example.com是合法链接。
5.5 “批量发布时部分失败,如何续传” —— 原子性与幂等性的实战设计
main.py支持--resume-from ID参数。原理是:每次发布成功,都在logs/publish_history.json中记录{ "id": "12345", "file": "posts/a.md", "platform": "wordpress", "status": "success", "timestamp": "2024-05-10T14:23:01Z" }。当批量失败时,用jq '.[] | select(.status=="failed") | .file' logs/publish_history.json提取失败文件列表,再用--resume-from重试。关键点:每个文件的发布是原子的,失败不影响其他文件;重试时,Orchestrator 会检查 WordPress 是否已存在同名草稿(用标题哈希做唯一索引),避免重复创建。
6. 进阶扩展与未来方向:从“能用”到“好用”的进化路径
Hermes Agent 当前已稳定支撑我 90% 的技术内容发布,但还有几个明确的进化方向,都是基于真实痛点:
多模态内容支持:现在只处理文本+图片,下一步要接入 Whisper 模型,自动为技术视频生成字幕和摘要,再发布为博客。难点在于视频帧提取和时间轴对齐,已在测试 FFmpeg + PySceneDetect 方案。
A/B 测试摘要生成:同一文章,用不同提示词生成 3 个摘要,自动发布到不同平台,用点击率数据反哺提示词优化。这需要在 Validator 中增加“平台效果追踪”模块,记录各平台的 UV/PV。
团队协作工作流:增加
reviewer角色,Orchestrator 生成任务包后,先发给指定 reviewer 邮箱,需其回复APPROVE才进入发布队列。这解决了“技术内容需多人审核”的刚需。离线模式增强:当前模型需联网下载,下一步打包成 Docker 镜像,内置所有模型权重和依赖,
docker run -v $(pwd)/posts:/app/posts hermes-agent --platform hexo即可离线发布,适合内网环境。
这些不是 PPT 愿景,而是我接下来三个月的待办清单。Hermes Agent 的本质,不是一个“完成了”的项目,而是一个持续生长的技术内容基础设施。它不追求炫技,只解决一个问题:让技术人把时间花在写代码、画架构图、做实验上,而不是和编辑器、API、404 错误较劲。当我今天下午三点写完这篇关于 Hermes Agent 的博客,敲下python main.py --input posts/hermes-agent.md --platform wordpress,八秒后,它就静静地躺在我的博客首页,标题前带着【Hermes】前缀,摘要里准确提到了“Qwen2-1.5B”和“INT4 量化”,图片链接全部有效——那一刻,我知道,这套系统已经真正活了过来。