
1. 从 Claude Chat 会议纪要落库说起先拿 Key再定 Base URL要让 Claude Chat 里的会议纪要流稳定落成 Markdown 并自动入库第一步是到 TaoToken 官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentminutes_intro 获取一个可用的 Key然后把请求的 Base URL 统一设为https://taotoken.net/api。这两步做完后面的脚本、Claude Code、Codex、CC Switch 才有统一的落点不会出现“同一份转写文本在三个工具里跑出三种结果”的尴尬。外部背景一句话带过Anthropic 近期把 Claude Chat 与 Claude Cowork 合并为统一体验并推出 Claude Docs、Claude Slides办公文档与会议场景被进一步收拢到同一个聊天入口。对后端开发者来说这意味着会议纪要的上游形态会更集中下游却更需要一个稳定的模型调用出口——把“聊天产物”转成可版本化、可检索、可入库的 Markdown才是工程侧真正要解决的问题。本文的视角是一个负责会议纪要自动落库的后端开发者转写文本进来经过模型结构化输出 Markdown再写入 Git 或数据库。我们要解决的不是“怎么写提示词”而是三件更硬的事调用出口是否统一、可切换、可回滚输出是否结构稳定能被下游解析出错时能不能快速定位是 Key、Base URL、模型名还是流式截断的问题。下面的内容按“准备 → 脚本 → 工具配置 → 前后对照 → 输出样例 → 落库 → 检查清单”推进所有命令和 SQL 都由你在本地执行模型只负责生成 Markdown 文本不直接连生产库。2. 接入前准备在 TaoToken 创建 Key 与 Base URL 规划2.1 创建 Key 的入口先到官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentprepare_key 完成账号准备再进入控制台的 API Keys 页面创建密钥https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentprepare_key创建后你会得到类似sk-...的字符串。本文统一用占位符YOUR_API_KEY表示请不要把真实 Key 提交到仓库。把 Key 放进环境变量是后续所有脚本和工具配置的共同前提# Linux / macOS export TAOTOKEN_API_KEYYOUR_API_KEY # Windows PowerShell setx TAOTOKEN_API_KEY YOUR_API_KEY2.2 Base URL 的两种写法TaoToken 的 Base URL 主入口是https://taotoken.net/api不同客户端的拼接习惯不一样这一点是排障时最容易踩的坑Anthropic 风格客户端例如使用anthropicSDK、Claude Code通常直接使用https://taotoken.net/api由 SDK 自己补/v1/messagesOpenAI 兼容客户端例如 Codex、部分第三方 SDK经常需要在 Base URL 后带/v1也就是https://taotoken.net/api/v1或者由客户端自动补/v1。判断方法很简单先用curl打一次确认路径没有被拼成/api/v1/v1/...。如果出现 404大概率就是路径重复或缺少/v1。2.3 模型名以控制台为准脚本里会用到模型 ID。模型列表和对话入口在这里https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentprepare_model建议把模型 ID 也做成环境变量不要硬编码在代码里。这样切换模型时只改一处不需要重新部署整条纪要流水线。3. 会议纪要生成脚本从转写文本到 Markdown3.1 设计目标这个脚本要满足会议纪要自动落库的实际需求输入是转写文本可能是 ASR 结果也可能是人工整理的段落输出是结构稳定的 Markdown包含固定章节便于下游正则或 AST 解析长会议要能分块处理避免一次请求过长导致截断失败要能重试重试后结果仍然可幂等落库不直接把模型输出写进数据库而是先落文件再由本地任务入库。3.2 可运行脚本示例下面是一份 Python 脚本使用 Anthropic 风格客户端指向 TaoToken# minutes_pipeline.py import os import re import time import json import hashlib import pathlib from anthropic import Anthropic, APIStatusError, APIConnectionError BASE_URL https://taotoken.net/api API_KEY os.environ[TAOTOKEN_API_KEY] # YOUR_API_KEY MODEL os.environ.get(MINUTES_MODEL, YOUR_MODEL_ID) OUT_DIR pathlib.Path(./minutes_out) OUT_DIR.mkdir(parentsTrue, exist_okTrue) client Anthropic(base_urlBASE_URL, api_keyAPI_KEY) SYSTEM_PROMPT 你是一个会议纪要结构化引擎。 只输出 Markdown不要输出解释、不要输出代码块围栏。 必须包含以下二级标题且顺序固定 ## 会议信息 ## 议题与讨论 ## 结论 ## 待办事项 ## 风险与阻塞 ## 待确认问题 待办事项必须使用表格列为负责人 | 事项 | 截止时间 | 优先级。 原文没有提到的信息写“待确认”禁止编造人名、日期和数字。 def split_transcript(text: str, size: int 6000, overlap: int 200): chunks [] start 0 while start len(text): end min(start size, len(text)) chunks.append(text[start:end]) if end len(text): break start end - overlap return chunks def call_model(chunk: str, idx: int, total: int) - str: user_prompt ( f这是会议转写的第 {idx 1}/{total} 块。 请提取该块内的议题、结论、待办、风险和待确认项。 只输出 Markdown 片段不要重复标题层级。\n\n f----- 转写开始 -----\n{chunk}\n----- 转写结束 ----- ) last_err None for attempt in range(5): try: resp client.messages.create( modelMODEL, max_tokens2048, temperature0.2, systemSYSTEM_PROMPT, messages[{role: user, content: user_prompt}], ) return .join( block.text for block in resp.content if getattr(block, type, ) text ) except (APIStatusError, APIConnectionError) as e: last_err e sleep_s min(2 ** attempt, 16) print(f[warn] chunk {idx} attempt {attempt 1} failed: {e}; retry in {sleep_s}s) time.sleep(sleep_s) raise RuntimeError(fchunk {idx} failed after retries: {last_err}) def merge_minutes(parts: list[str], title: str) - str: body \n\n.join(p.strip() for p in parts if p.strip()) return f--- title: {title} source: claude-chat generated_by: taotoken --- # {title} {body} def normalize_markdown(md: str) - str: md re.sub(r\n{3,}, \n\n, md) md re.sub(r^.*$, , md, flagsre.M) return md.strip() \n def build_minutes(transcript: str, title: str) - pathlib.Path: chunks split_transcript(transcript) parts [call_model(c, i, len(chunks)) for i, c in enumerate(chunks)] md normalize_markdown(merge_minutes(parts, title)) digest hashlib.sha256(transcript.encode(utf-8)).hexdigest()[:12] out OUT_DIR / f{digest}.md out.write_text(md, encodingutf-8) meta {digest: digest, title: title, chunks: len(chunks), path: str(out)} (OUT_DIR / f{digest}.json).write_text( json.dumps(meta, ensure_asciiFalse, indent2), encodingutf-8 ) return out if __name__ __main__: import sys txt pathlib.Path(sys.argv[1]).read_text(encodingutf-8) name sys.argv[2] if len(sys.argv) 2 else 未命名会议 print(build_minutes(txt, name))几个工程细节值得强调temperature设成 0.2纪要不需要创意稳定比多样重要max_tokens按块大小给块越小越不容易被截断用转写文本的哈希做文件名天然幂等同一份会议重复跑不会产生多份文件重试只对可恢复错误做退避超过次数直接抛错避免脏数据入库。3.3 用 curl 做最小连通性验证在跑整条脚本前先用一条最小请求确认 Key、Base URL、模型名三件事都对curl -sS https://taotoken.net/api/v1/messages \ -H x-api-key: YOUR_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: YOUR_MODEL_ID, max_tokens: 128, messages: [{role: user, content: 只回复两个字连通}] }如果这里返回 401检查 Key 是否有多余空格返回 404检查路径是否被写成了/api/v1/v1/messages返回 429先降低并发脚本里的退避逻辑会派上用场。4. Claude Code、Codex、CC Switch 的供应商切换配置会议纪要流水线只是其中一环。实际开发中你还会在 Claude Code 里调提示词、在 Codex 里改脚本、用 CC Switch 在多个供应商之间切换。这三者的配置方式完全不同混用会直接报错。4.1 Claude Codesettings.json 与环境变量Claude Code 使用 Anthropic 风格配置核心是ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN。编辑用户级或项目级settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_MODEL: YOUR_MODEL_ID, ANTHROPIC_SMALL_FAST_MODEL: YOUR_FAST_MODEL_ID } }保存后重启 Claude Code让它重新读取配置。验证方式是问一句需要实际调用模型的问题然后看请求是否成功返回如果仍然报鉴权错误优先检查是否被 shell 里的旧环境变量覆盖。4.2 Codexconfig.toml不要套用 ANTHROPIC_*Codex 使用 OpenAI 兼容风格的config.toml不能把ANTHROPIC_*环境变量套过来。正确做法是定义一个 providermodel YOUR_MODEL_ID model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api/v1 env_key TAOTOKEN_API_KEY然后在 shell 里导出TAOTOKEN_API_KEYYOUR_API_KEY。注意点env_key填的是环境变量名不是 Key 本身如果客户端会自动补/v1base_url就写https://taotoken.net/api反之写.../api/v1改完配置后新开一个终端会话避免旧环境变量残留。4.3 CC Switch三件套切换法CC Switch 用来在多个供应商配置之间切换。把它当成“三件套”来管理切换过程才可控第一件供应商配置为 TaoToken 单独建一个 profileBase URL 写https://taotoken.net/apiKey 引用环境变量而不是明文写入。第二件备份与回滚切换前把当前生效的配置文件复制一份带时间戳cp ~/.claude/settings.json ~/.claude/settings.json.bak.$(date %Y%m%d%H%M%S)第三件切换后自检不要只看 CC Switch 界面显示“已切换”要实际发一次请求确认返回内容和模型名都对得上。自检失败就立刻回滚到备份文件再逐项排查。这里再强调一次边界Claude Code 用ANTHROPIC_*Codex 用config.tomlenv_key二者不能交叉套用。很多“配置明明改了却没生效”的问题根源就是把 Anthropic 风格变量写进了 Codex 的终端会话里。5. 调用前后对照从直连到 TaoToken 的差异与排障把调用出口切到 TaoToken 后变化集中在以下几个维度。下面这张对照表可以直接用于团队内部排障文档。维度切换前切换后Base URL各工具各自维护容易写错版本统一为https://taotoken.net/api鉴权多处散落 Key轮换困难Key 集中在控制台创建环境变量注入模型名硬编码在脚本里提取为YOUR_MODEL_ID按控制台为准错误定位401/404/429 混在一起先分路径再分鉴权再分限流回滚改回去要靠记忆CC Switch 三件套 备份文件日志只记录成功与否记录 digest、chunk 数、重试次数常见错误与处理顺序401 / 鉴权失败检查YOUR_API_KEY是否已替换、是否带空格、是否被旧环境变量覆盖。Claude Code 看ANTHROPIC_AUTH_TOKENCodex 看env_key指向的变量。404 / 路径错误检查 Base URL 与客户端自动补全规则避免/api/v1/v1/...或缺少/v1。429 / 限流降低并发给脚本加指数退避批量历史会议建议排队处理不要一次性打满。流式截断纪要场景建议关闭流式用非流式一次拿完整 Markdown避免半截 JSON 或半截表格。Markdown 结构漂移在系统提示里固定二级标题顺序脚本侧再做一次章节校验缺章节就重试该块。长会议超长用分块 合并块之间留 200 字重叠防止议题被切断。6. Markdown 输出样例下游可以怎么解析脚本产出的 Markdown 大致长这样结构固定便于正则或 Markdown AST 解析--- title: 支付网关改造评审会 source: claude-chat generated_by: taotoken --- # 支付网关改造评审会 ## 会议信息 - 时间待确认 - 参与人待确认 - 记录来源Claude Chat 转写 ## 议题与讨论 - 讨论了下单链路的重试策略重点关注重复扣款风险。 - 对比了同步扣款与异步对账两种方案倾向先做异步对账。 ## 结论 - 采用异步对账方案先在小流量灰度。 - 重试策略加入幂等键幂等键由订单号与请求时间生成。 ## 待办事项 | 负责人 | 事项 | 截止时间 | 优先级 | | --- | --- | --- | --- | | 待确认 | 补幂等键设计文档 | 待确认 | 高 | | 待确认 | 灰度开关与回滚预案 | 待确认 | 高 | | 待确认 | 对账任务监控埋点 | 待确认 | 中 | ## 风险与阻塞 - 灰度期间对账延迟可能造成用户侧状态不一致需要人工兜底流程。 ## 待确认问题 - 灰度流量比例是否由风控统一配置 - 对账失败后的补偿由哪个团队负责这份样例的价值在于标题层级固定、待办是表格、缺失信息统一写“待确认”。下游解析时不需要猜模型这次用了什么格式。7. 落库与自动化文件先落地再入库模型输出先落文件再由本地任务入库是更安全的做法。Markdown 文件可以进 Git数据库只存索引和结构化字段。一个最小化的入库流程# 1. 生成纪要文件 python minutes_pipeline.py ./transcript.txt 支付网关改造评审会 # 2. 查看生成结果 ls -l ./minutes_out/入库 SQL 由你在本地或 CI 中执行模型不直接连库CREATE TABLE IF NOT EXISTS meeting_minutes ( id BIGSERIAL PRIMARY KEY, digest VARCHAR(32) NOT NULL UNIQUE, title TEXT NOT NULL, markdown_path TEXT NOT NULL, chunk_count INT NOT NULL DEFAULT 1, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); INSERT INTO meeting_minutes (digest, title, markdown_path, chunk_count) VALUES (digest, title, path, chunk_count) ON CONFLICT (digest) DO NOTHING;digest上的唯一约束让重复消费自动去重配合文件哈希整条链路具备幂等性。如果需要把待办事项单独抽表可以在 CI 里解析 Markdown 表格后再插入仍然坚持“模型只产出文本写库由本地任务执行”。8. 上线检查清单与下一步上线前逐项确认Key 是否只存在于环境变量没有进仓库Base URL 是否统一为https://taotoken.net/api且路径没有重复Claude Code 用的是ANTHROPIC_*Codex 用的是config.toml没有交叉CC Switch 是否保留最近一次可回滚备份脚本是否具备重试、幂等文件名和章节校验长会议是否走分块 合并而不是单次超长请求Markdown 结构是否固定缺失信息是否统一为“待确认”。完成这些之后Claude Chat 的会议纪要流就可以更稳地落到 Markdown 与数据库。继续往下走可以从模型对话页开始验证调用https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentcta_chat如果要把这套调用固化到日常开发流可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcta_plan还没有 Key 的话直接创建https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentcta_keyClaude Code 的完整配置说明在这里https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentcta_claude_code建议的推进顺序是先在模型对话页跑通一次最小请求再把纪要脚本接上随后在 Claude Code 里验证settings.json最后把 CC Switch 的回滚备份补齐。每一步都留下日志和 digest排障时你会感谢自己。补充一个实操提醒如果你的转写文本来自多个来源先统一编码和换行符再做分块。编码不一致会让模型在中文标点处出现乱码Markdown 表格也会错位。把这一层清洗放在脚本入口而不是事后修补整条会议纪要流水线会稳定得多。