ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

用Hermes Agent建立个人LLM Wiki知识库:TaoToken统一Key接入与config.toml配置实战

用Hermes Agent建立个人LLM Wiki知识库:TaoToken统一Key接入与config.toml配置实战 1. 为什么我要给 Hermes Agent 配一个统一 KeyHermes Agent 是本地 Python 写的自进化 Agent它最吸引我的地方是能自己写 skill、自己维护知识库。我把它用来跑个人 LLM Wikiraw/放原始素材wiki/放加工后的概念页和实体页SCHEMA.md定规范index.md做索引log.md记操作流水。这套结构本身不复杂真正卡住我的是接入环节——Agent 要读 Wiki、要提炼概念、要生成 wikilinks每一步都得调模型而模型通道如果每个 provider 配一套 Key、一套 base_urlconfig.toml 会迅速变成一团乱麻。我试过最笨的办法在config.toml里给每个模型单独写一段[providers.xxx]结果换一个模型就要改代码、改环境变量、重启 Agent调试一次知识库问答要折腾十几分钟。后来我把所有模型调用收敛到 TaoToken 的统一 Key 和统一 API 通道上config.toml 只保留一份base_url和一份api_key模型名通过参数切换。这样 Hermes Agent 在摄入文章、建立关联、定时整理时不需要关心底层是哪个模型只认一个入口。这篇面向的是已经在本地跑 Python Agent、准备把 LLM Wiki 真正用起来的开发者。我会给出可直接复制的config.toml骨架、环境变量写法、Python 调用示例以及一次知识库问答请求的完整验证动作确认 Agent 能正常读写 Wiki 条目。如果你还没搭好 Wiki 目录也可以先按这套配置把通道跑通再回头补目录结构。2. TaoToken 前置统一 Key 与 API 通道准备TaoToken 在这里扮演的角色是「统一模型入口」。你不需要在 Hermes Agent 里维护一堆 provider 配置只需要一个 API Key 和一个 base_url就能在同一个通道里切换不同模型。对 LLM Wiki 这种场景特别合适摄入原始素材时可能用便宜快的模型做摘要建立概念关联时用推理强的模型定时整理时用稳定的模型跑批处理而它们共用同一份凭证。第一步是拿到 Key。访问官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后进入控制台在 API Keys 页面创建一个新 Key。建议给这个 Key 起一个能识别的名字比如hermes-wiki-local方便以后区分是哪个 Agent 在用。创建后立刻复制保存页面刷新后通常不再完整显示。第二步是确认 API 通道地址。TaoToken 的 API 入口是 https://taotoken.net/api 注意这个地址不带任何查询参数直接作为base_url使用。很多 OpenAI 兼容的 SDK 会自动在 base_url 后面拼/v1/chat/completions所以你在 config.toml 里写base_url https://taotoken.net/api即可不要自己再加/v1否则容易出现 404。第三步是确认模型名。在控制台的模型列表或文档页可以看到当前可用的模型标识比如对话模型、代码模型等。Hermes Agent 的 Wiki 维护任务大多是文本理解和生成选一个通用对话模型就够如果你要让它读大段原始素材做提炼选上下文窗口大的模型更稳。把模型名记下来后面写进 config.toml 的model字段。注意Key 只存在本地环境变量或本地配置文件里不要提交到 Git也不要在 Wiki 的log.md里打印完整 Key。我在log.md里只记录「本次调用使用了哪个模型、耗时多少」不记录凭证。3. config.toml 骨架与环境变量配置Hermes Agent 的配置我习惯放在项目根目录的config.toml凭证走环境变量这样配置文件和密钥分离换机器时只改环境变量。下面是我实际在用的骨架你可以直接复制后改路径和模型名。# ~/hermes-wiki/config.toml [agent] name hermes-wiki wiki_root /Users/yourname/wiki skill_dir /Users/yourname/hermes-wiki/skills log_level INFO [llm] # 统一走 TaoToken 通道只保留一份 base_url 和 api_key base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY model your-chat-model-name timeout 60 max_retries 3 [llm.params] temperature 0.3 max_tokens 4096 [wiki] raw_dir raw wiki_dir wiki schema_file SCHEMA.md index_file index.md log_file log.md # 摄入时先落 raw再判断是否提炼到 wiki ingest_to_raw_first true [cron] enabled true # 每天 08:30 自动整理检查断裂 wikilinks、补 frontmatter、更新 index daily_compile 30 8 * * *环境变量在 shell 里设置macOS/Linux 写进~/.zshrc或~/.bashrcWindows 用系统环境变量或.env文件配合python-dotenvexport TAOTOKEN_API_KEYsk-你的Key如果你用.env管理在项目里放一个.env然后确保.gitignore里有.envTAOTOKEN_API_KEYsk-你的KeyPython 侧读取配置时我建议封装一个小的 loader把 TOML 和环境变量合并避免在业务代码里到处写os.environ# hermes-wiki/config_loader.py import os import tomllib from pathlib import Path def load_config(path: str config.toml) - dict: with open(path, rb) as f: cfg tomllib.load(f) llm cfg[llm] key_env llm[api_key_env] api_key os.environ.get(key_env) if not api_key: raise RuntimeError(f环境变量 {key_env} 未设置) llm[api_key] api_key return cfg if __name__ __main__: c load_config() print(base_url:, c[llm][base_url]) print(model:, c[llm][model]) print(wiki_root:, c[agent][wiki_root])跑一下这个 loader确认能打印出 base_url 和 model且没有把 Key 明文打出来。这一步过了说明配置层没问题接下来才是真正的调用。4. 用统一通道调用模型读写 Wiki 条目配置通了之后核心动作是让 Hermes Agent 通过统一通道调用模型完成一次「读 Wiki 条目 → 生成回答 → 写回 log」的闭环。我用 OpenAI 兼容的 SDK 来写因为 TaoToken 的通道兼容这套调用方式代码量最少。先装依赖pip install openai tomllib然后写一个最小的 Wiki 问答模块。它的逻辑是读取index.md和指定概念页拼成上下文发给模型拿到回答后追加到log.md。# hermes-wiki/wiki_qa.py import os from pathlib import Path from openai import OpenAI from config_loader import load_config cfg load_config() llm cfg[llm] wiki_root Path(cfg[agent][wiki_root]) client OpenAI( base_urlllm[base_url], api_keyllm[api_key], ) def read_wiki_page(rel_path: str) - str: p wiki_root / rel_path if not p.exists(): return return p.read_text(encodingutf-8) def ask_wiki(question: str, page: str wiki/concepts/费曼学习法.md) - str: index_text read_wiki_page(index.md) page_text read_wiki_page(page) prompt f你是个人 LLM Wiki 的维护助手。 以下是 Wiki 索引 {index_text[:2000]} 以下是相关概念页 {page_text[:4000]} 用户问题{question} 请基于以上内容回答如果 Wiki 中没有相关信息明确说明。 resp client.chat.completions.create( modelllm[model], messages[{role: user, content: prompt}], temperaturellm[params][temperature], max_tokensllm[params][max_tokens], ) answer resp.choices[0].message.content append_log(question, answer) return answer def append_log(question: str, answer: str): log_path wiki_root / cfg[wiki][log_file] with log_path.open(a, encodingutf-8) as f: f.write(f\n## Q: {question}\n) f.write(f{answer[:500]}\n) if __name__ __main__: q 我的 Wiki 里关于费曼学习法是怎么定义的 print(ask_wiki(q))这段代码里有两个关键点。第一base_url直接用https://taotoken.net/apiSDK 会自动补全路径不要手动加/v1。第二append_log只写问题和回答摘要不写 Key也不写完整请求体避免日志膨胀和凭证泄露。如果你想让 Agent 在摄入新文章时自动判断该进raw/还是提炼到wiki/可以在 prompt 里加一段判断逻辑让模型返回 JSON再由 Python 解析后决定写哪个目录。这样 Wiki 的 Layer 1 和 Layer 2 就能自动分流不需要你手动搬文件。5. 验证请求确认 Agent 能正常读写 Wiki配置和代码都就位后必须做一次端到端验证确认三件事通道能通、模型能答、Wiki 能写。我用的验证动作是一个最小问答请求配合文件检查。先跑问答脚本cd ~/hermes-wiki python wiki_qa.py预期输出是一段关于费曼学习法的回答。如果这一步报错先看错误类型401 通常是 Key 没读到或失效404 通常是 base_url 写错超时通常是网络或 timeout 设太短。然后检查log.md是否被追加了内容tail -n 20 ~/wiki/log.md你应该能看到类似这样的记录## Q: 我的 Wiki 里关于费曼学习法是怎么定义的 费曼学习法的核心是……回答摘要接着验证「写 Wiki 条目」这条路径。让 Agent 摄入一段新素材并生成概念页# hermes-wiki/ingest_demo.py from pathlib import Path from wiki_qa import client, llm, wiki_root raw_text 费曼学习法强调用自己的话复述概念直到能向小白讲清楚。 它的四个步骤是选定概念、模拟教学、发现缺口、简化重述。 prompt f请把以下素材提炼成一个 Wiki 概念页使用 Markdown 包含 frontmattertitle, type, sources正文用 [[wikilinks]] 关联相关概念。 素材 {raw_text} 只输出页面内容。 resp client.chat.completions.create( modelllm[model], messages[{role: user, content: prompt}], temperature0.2, ) page_content resp.choices[0].message.content out wiki_root / wiki/concepts/费曼学习法.md out.write_text(page_content, encodingutf-8) print(written:, out)跑完后检查文件head -n 20 ~/wiki/wiki/concepts/费曼学习法.md如果能看到 frontmatter 和正文说明 Agent 已经能通过统一通道完成「读素材 → 生成页面 → 写入 Wiki」的完整链路。再跑一次wiki_qa.py问同一个概念这次回答应该能引用到刚写入的页面内容形成闭环。提示验证阶段建议把max_tokens调小一点比如 1024避免一次生成太长内容不好排查。确认链路通了再调回正常值。6. 本篇常见错排查接入环节的报错大多集中在凭证、地址、路径三类。下面是我实际踩过的坑和对应处理方式。401 Unauthorized最常见的原因是环境变量没生效。检查echo $TAOTOKEN_API_KEY是否有输出如果为空说明 shell 没加载或写错了文件。另一个原因是 Key 复制时带了空格或换行重新复制一次。还有一种情况是用了旧 Key去控制台确认 Key 状态是否正常。404 Not Found几乎都是 base_url 写错。正确写法是https://taotoken.net/api不要写成https://taotoken.net/api/v1也不要漏掉/api。如果你用的 SDK 版本较老确认它是否会自动补全路径必要时在代码里打印实际请求的 URL。模型名不存在model字段必须和控制台里显示的标识完全一致大小写敏感。如果你从文档里复制注意不要带多余空格。换模型时只改config.toml里的model不要动 base_url 和 Key。Wiki 路径找不到wiki_root建议用绝对路径不要用~因为 Python 的Path不会自动展开~。如果你非要用~在 loader 里加Path(...).expanduser()。另外确认raw/、wiki/、SCHEMA.md、index.md、log.md都已存在缺文件时 Agent 写入会报错。写入 log 但页面没更新检查ingest_demo.py里的输出路径是否和wiki_root拼接正确。有时候模型返回的内容带了 Markdown 代码块包裹直接写入会把 也写进文件建议在写入前做一次清洗去掉首尾的代码块标记。定时任务不执行Hermes Agent 的 cron 依赖进程常驻或系统级调度。如果你只是本地跑脚本确认 Agent 进程在后台运行如果用系统 cron确认 Python 路径和环境变量在 cron 环境里也能读到必要时在 crontab 里显式 source 环境变量文件。排障时我习惯先跑一个最小请求只发一句「你好」确认通道本身没问题再逐步加上 Wiki 上下文。这样能把「通道问题」和「业务逻辑问题」分开定位快很多。7. 下一步把通道固化进你的 Agent 工作流通道跑通之后我建议做两件事让它真正稳定下来。第一把config_loader.py和wiki_qa.py里的调用封装成一个llm_client模块所有 skill 都通过它调模型这样以后换模型、调参数只改一处。第二把定时整理任务接上让 Agent 每天自动扫描wiki/下的断裂 wikilinks、补 frontmatter、更新index.md你只需要看log.md的摘要。如果你还想继续深入可以去看接入文档里面有更完整的参数说明和错误码解释https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。需要管理多个 Key 或查看用量去控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。如果你打算让 Agent 长期跑编码类任务、频繁调用模型可以了解 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。想先在网页里验证模型回答效果用模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。Key 的创建和管理在 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。我自己的做法是先把config.toml和 loader 固定下来再写 skill最后才接定时任务。顺序反了的话skill 里散落一堆硬编码的 base_url后面改起来很痛苦。通道这件事一次配好后面所有 Wiki 维护动作都省心。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进