1. 先管住模型出口WeKnora 的 Fact 记忆为什么容易烧 Token最近微信团队开源的 WeKnora 把企业知识库往 Agent 知识层推进长期记忆里的 Fact 类信息很值得企业知识 Agent 开发者先动手验证。你要复现“从对话里抽取 Fact等待用户确认再按需召回”这条链路第一件事不是改 Prompt而是把模型调用出口固定到 TaoTokenhttps://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_fact_intro 。TaoToken 的模型调用地址是 https://taotoken.net/api Key 去控制台创建。这样做不是因为“额度不够”这种泛泛理由而是 Fact 抽取天然是一个高频、可批处理、又需要审计的调用场景每轮对话结束可能触发候选事实抽取候选事实还要去重、合并、等待确认确认之后在后续问题里又会被召回。只要 Agent 还在跑Token 消耗就不是一次性的而是持续发生的。WeKnora 本身把企业知识库常见能力做得很全包括多格式文档解析、混合检索、Rerank、知识图谱、数据源接入以及 ReAct Agent、Skills、沙箱等扩展。但对企业知识 Agent 开发者来说Fact 类记忆是最容易“写错”的一类数据。Preference 写错了最多影响推荐风格Task 写错了最多影响一次执行Fact 写错了可能会被后续几十次对话反复召回最后变成企业知识层里的污染源。所以原文里“Agent 自动提取出的记忆不会直接写入而是等待用户确认”这个设计非常关键。它把模型的不确定性挡在长期记忆之外也给开发者留下了接入自己的鉴权、审计、成本控制的空间。这也是为什么建议你在本地开发阶段就把 TaoToken 放到模型调用链路上。TaoToken 管住的不只是 Key还包括调用入口、模型选择和用量观测。Fact 抽取可以用便宜模型做初筛确认环节可以用更强模型做复核召回阶段则尽量走本地缓存或向量检索不要每次都把全量历史记忆塞进上下文。下面这套写法目标就是让你在 WeKnora 的 Fact 记忆链路上既能复现确认流程又能把 Token 消耗控制在可解释范围内。2. 拆开 WeKnora 的 Fact 抽取链路触发、候选、确认、召回WeKnora 的长期记忆里会区分 Profile、Preference、Fact、Task、Interest 等类型。Fact 不是“用户喜欢什么”也不是“用户让你做什么”而是“用户明确表达过的、可被证伪的客观信息”。例如“我们团队使用 GitLab 做代码托管”“这个项目的发布窗口是每周四”“该客户要求发票走电子专票”。这些信息未来会被多次复用所以它们必须经过确认。把链路拆开大致是下面六段阶段WeKnora 侧动作企业知识 Agent 开发者要补的能力TaoToken 侧可观测点触发对话轮次结束、用户手动保存、特定意图命中决定哪些 Session 触发抽取避免每句话都调用模型调用次数、模型分布、单次 Token候选抽取从对话中提取 Fact 候选用 JSON Schema 约束输出过滤偏好和任务抽取模型用量、失败率去重合并与已有记忆比对判断新增或更新本地做向量相似度或规则匹配减少模型调用去重阶段是否重复调用等待确认候选记忆进入待确认队列在 UI/IM/工单里呈现“原文摘录 抽取结果”确认前后调用量对比写入召回用户确认后写入长期记忆后续按需召回设置作用域、过期时间、召回上限召回是否携带过多历史审计回溯记录来源、确认人、版本本地日志与 TaoToken 调用记录对齐可按 Key、模型、时间排查这里最容易出问题的是“触发”和“去重合并”。如果每轮对话都调用模型抽 Fact用量会很快上去如果去重也完全交给大模型等于一次抽取变成两次模型调用。更合理的做法是抽取只处理最近一轮对话并且只输出 Fact 候选去重先用本地向量或简单规则初筛只有相似度处于模糊区间时才让模型判断“新增、更新还是忽略”。WeKnora 的确认流程给了你一个很好的插入点。候选记忆不要直接写入长期库而是落到一张待确认表。待确认表可以放在本地 SQLite 里由你的服务读取再展示给用户确认。注意不要让 Agent 或 MCP 直接去连生产数据库执行写操作。企业知识层里的写入动作应该由你的后端服务完成SQL 也由读者在本地或测试环境手工执行。生产库的权限边界不能交给模型。一个更具体的流程对照如下对话结束 - 判断是否触发 Fact 抽取 - 调用 TaoToken 上的轻量模型输出 JSON 候选 - 本地规则过滤去掉 Preference、Task、Interest、Profile - 本地向量去重与已确认 Fact 比对 - 写入待确认队列 - 给用户展示原文摘录 / 抽取 Fact / 作用域 / 过期时间 - 用户点击确认或拒绝 - 确认后写入长期记忆拒绝后记录负样本 - 后续对话召回时只取 top-k 已确认 Fact这套流程和 WeKnora 原生“先等待用户确认再自动召回”的思路一致但额外加了两层本地去重和成本观测。TaoToken 在这里的角色不是替代 WeKnora而是把模型调用集中到一个可管理的出口。你可以去 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_fact_pipeline 创建 Key然后在环境变量里统一注入避免每个 Agent、每个脚本各写一套 Key。3. 可复现的 Fact 抽取 Prompt只抽事实不碰偏好和任务要复现 Fact 抽取Prompt 必须比“请提取记忆”这种自然语言指令严格得多。推荐直接要求模型输出 JSON 数组并且把字段固定下来。下面这段 Prompt 片段可以放在 WeKnora 的自定义记忆抽取节点里也可以放在你自己的 Agent 服务里。你是企业知识 Agent 的长期记忆抽取器。你的任务是从最近一轮对话中只抽取 Fact 类长期记忆。 Fact 的定义 - 可在未来复用 - 可被证伪 - 不是用户喜好、不是一次性任务、不是兴趣标签、不是个人档案 - 必须能在原文中找到明确依据。 禁止抽取 - Preference喜欢/讨厌/偏好某风格 - Task让 Agent 执行的一次性动作 - Interest关注某个话题 - Profile姓名、职位等身份档案除非用户明确要求作为事实保存。 输出格式JSON 数组。没有候选时输出 []。 每个对象包含 { type: fact, subject: 主体, predicate: 关系或属性, object: 客体或值, fact_text: 合并后的事实句, confidence: 0.0, source_quote: 原文中的短句不超过 80 字, scope: user | team | org, expires_at: null, needs_confirmation: true } 规则 1. confidence 低于 0.65 不要输出。 2. source_quote 必须来自最近一轮对话不得改写。 3. scope 无法判断时填 user。 4. expires_at 只接受 ISO 日期或 null。 5. 所有输出都必须 needs_confirmationtrue。 6. 不要输出解释不要输出 Markdown只输出 JSON。这段 Prompt 的重点不是“更聪明”而是“更窄”。Fact 抽取最怕模型自由发挥把“用户说喜欢简洁回答”写成 Fact或者把“帮我查一下明天天气”写成 Task 后误存成长期事实。通过 JSON Schema 和禁止类型可以大幅降低污染。接下来用 TaoToken 的兼容接口调用。Base URL 使用 https://taotoken.net/api Key 用 YOUR_API_KEY 占位。下面是一个 Python 侧的例子演示如何做抽取和后处理。具体 SDK 可以按你项目里已有依赖替换核心是 base_url 和 api_key 的来源。import json import os from openai import OpenAI client OpenAI( base_urlhttps://taotoken.net/api, api_keyos.environ.get(TAOTOKEN_API_KEY, YOUR_API_KEY), ) FACT_PROMPT 你是企业知识 Agent 的长期记忆抽取器。 只抽取 Fact 类长期记忆输出 JSON 数组。 字段type, subject, predicate, object, fact_text, confidence, source_quote, scope, expires_at, needs_confirmation。 没有候选输出 []。不要输出解释。 def extract_fact_candidates(last_dialogue: str): resp client.chat.completions.create( model你的抽取模型ID, messages[ {role: system, content: FACT_PROMPT}, {role: user, content: f最近一轮对话\n{last_dialogue}}, ], temperature0.1, ) content resp.choices[0].message.content.strip() candidates json.loads(content) facts [] for item in candidates: if item.get(type) ! fact: continue if float(item.get(confidence, 0)) 0.65: continue if not item.get(source_quote): continue item[needs_confirmation] True facts.append(item) return facts如果你在 WeKnora 里做二次开发建议把extract_fact_candidates的返回值写入待确认表而不是直接写长期记忆。确认动作由用户完成写入动作由后端服务完成。模型只负责候选不负责最终事实。这个边界一旦守住后面排障会轻松很多。TaoToken 在这里的价值是让你能按 Key 观察抽取调用。你可以给“Fact 抽取”单独创建一个 Key给“对话主模型”创建另一个 Key给“确认后摘要”再创建一个 Key。这样当用量异常时你能快速判断是抽取太频繁还是主对话太长。需要创建多个 Key 时从 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_fact_keys 进入控制台即可。4. Claude Code、Codex、CC Switch 接入 TaoToken配置分三件套不要混用企业知识 Agent 开发者往往不只用一个工具。你可能用 Claude Code 改后端用 Codex 写配置用 CC Switch 在多个供应商之间切换。这里必须强调Claude Code 用 Anthropic 风格的环境变量Codex 用 OpenAI 风格的 config.toml不要把ANTHROPIC_*套到 Codex 上。混用最常见的后果是请求地址不对、模型名不识别、401 和 404 交替出现。4.1 Claude Codesettings.json 与 ANTHROPIC_*Claude Code 推荐在项目或用户级settings.json里配置。Base URL 用 https://taotoken.net/api Key 用 YOUR_API_KEY 占位。{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_MODEL: 你的Claude模型ID } }如果你不想把 Key 写进文件可以只保留ANTHROPIC_BASE_URL和ANTHROPIC_MODEL然后用系统环境变量注入ANTHROPIC_AUTH_TOKEN。例如在本地 shell 里export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_AUTH_TOKENYOUR_API_KEY export ANTHROPIC_MODEL你的Claude模型ID验证时不要只看 Claude Code 是否启动要看它发出的请求是否命中 TaoToken。你可以先在模型对话页做一次最小调用确认 Key 可用再去配 Claude Code。模型对话入口在文末 CTA 里。4.2 Codexconfig.toml 用 model_providerCodex 的配置逻辑和 Claude Code 不同。它通常通过config.toml声明 provider再用环境变量读取 Key。下面是一个示例Base URL 仍然是 https://taotoken.net/api 但不要写ANTHROPIC_*。model 你的Codex模型ID model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat然后在 shell 里设置export TAOTOKEN_API_KEYYOUR_API_KEY如果你使用的是支持 Responses API 的 Codex 版本wire_api可以按你本地版本要求改成responses。但无论怎么改Key 的环境变量名要和env_key一致base_url不要多加/v1或重复路径。TaoToken 的统一入口是 https://taotoken.net/api 路径拼接交给客户端。4.3 CC Switch 三件套Claude、Codex、环境变量档案如果你用 CC Switch 做多工具切换建议把它当成“三件套”来维护Claude Code 档案只放ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_MODEL。Codex 档案只放model_provider、base_url、env_key、model。通用环境变量档案放TAOTOKEN_API_KEYYOUR_API_KEY供 Codex 和其他脚本读取。不要为了省事把 Claude 的ANTHROPIC_AUTH_TOKEN直接填到 Codex 的env_key里。Codex 读的是TAOTOKEN_API_KEY这类变量不是ANTHROPIC_*。如果你在 CC Switch 里切换后出现配置不生效优先检查它是否覆盖了项目目录下的settings.json或config.toml。需要统一管理 Key 时从 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_fact_ccswitch 进入控制台创建。建议给 Claude Code、Codex、Fact 抽取服务分别建 Key不要所有工具共用一个 Key。共用 Key 虽然省事但一旦某个 Agent 进入循环调用你很难定位是谁在消耗。5. 记忆确认流程对照WeKnora 原生确认与代理侧审计怎么配合WeKnora 的长期记忆设计里自动抽取的候选不会直接落库而是等待用户确认。这个机制解决的是“模型抽取结果是否可信”的问题。但企业开发者还要解决另一个问题确认之后如何知道这条 Fact 是被哪个模型、哪次对话、哪个 Key 抽取出来的。把 WeKnora 原生确认和 TaoToken 代理侧审计对齐才能形成闭环。下面是一个流程对照表你可以直接拿去做实现清单环节WeKnora 原生行为你需要在本地补的记录TaoToken 侧对应信息抽取候选从对话中提取记忆候选记录 session_id、message_id、抽取时间调用时间、模型、Token 数类型过滤区分 Profile、Preference、Fact 等只让 Fact 进入待确认队列抽取 Key 的调用量用户确认等待用户确认后写入记录确认人、确认时间、原文摘录确认动作本身不一定调模型写入长期记忆按需召回记录 scope、expires_at、版本号写入后召回调用单独计量后续召回自动召回已确认记忆设置 top-k 和最大 Token召回调用是否过大拒绝样本不写入记录拒绝原因反哺 Prompt抽取失败率、重复率一个很实用的做法是给待确认表加字段-- 本地 SQLite 示例仅用于开发环境手工执行 CREATE TABLE fact_candidates ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT NOT NULL, message_id TEXT NOT NULL, fact_text TEXT NOT NULL, subject TEXT, predicate TEXT, object TEXT, confidence REAL, source_quote TEXT, scope TEXT DEFAULT user, expires_at TEXT, status TEXT DEFAULT pending, created_at TEXT DEFAULT CURRENT_TIMESTAMP, confirmed_at TEXT, confirmed_by TEXT, reject_reason TEXT );注意这只是本地开发示例。不要让 Agent 或 MCP 直接拿这段 SQL 去连生产库执行。生产环境的表结构、权限和迁移流程应该由你的后端工程管理。模型只输出候选 JSON写入由服务层控制。确认流程可以设计成“两段式”第一段抽取后立即在待确认表写入pending记录并把source_quote展示给用户。用户看到的不是模型改写后的事实句而是原文摘录加结构化字段。这样用户能判断模型有没有断章取义。第二段用户点击确认后服务层把status改为confirmed再写入长期记忆库。如果用户点击拒绝把status改为rejected并记录reject_reason。这些拒绝样本可以定期用来优化 Prompt比如发现模型总把“今天先这样”抽成 Fact就在 Prompt 里增加反例。召回时也要控制上下文。不要因为长期记忆里有 500 条 Fact就每次都全部塞给模型。先按用户、团队、组织作用域过滤再做向量检索最后只取 top-k。TaoToken 的用量页可以帮助你观察召回调用是否突然变大。如果你发现对话主模型 Token 暴涨但抽取 Key 用量正常问题通常出在召回上下文组装而不是 Fact 抽取本身。6. 排障顺序Fact 抽取重复、确认不生效、Token 异常Fact 记忆链路出问题时不要一上来就改 Prompt。先按“调用是否通、输出是否合法、写入是否发生、召回是否过量”四层排查。下面这张表可以直接用。现象优先检查常见原因处理方式401 UnauthorizedKey 是否有效、环境变量是否注入用了旧 Key或 CC Switch 覆盖了配置重新创建 Key确认TAOTOKEN_API_KEY404 Not FoundBase URL 是否写成 https://taotoken.net/api多加了/v1或路径重复保持 Base URL 不加 UTM、不重复拼接429 Too Many Requests抽取触发是否过频每轮对话都调用或循环调用加节流、批量、本地去重Fact 重复写入去重逻辑是否执行相似度阈值太低模型判断不稳定先用本地向量初筛再让模型复核确认后不生效写入服务是否执行只改了待确认表状态没写长期库服务层事务处理记录写入日志召回内容过长top-k 是否过大把全部 Fact 塞进上下文限制条数、按 scope 过滤、摘要化Claude Code 配置不生效settings.json 是否被覆盖CC Switch 或环境变量优先级问题检查项目级、用户级、环境变量顺序Codex 报模型不存在config.toml 的 provider 是否正确把ANTHROPIC_*写进了 Codex改用model_providerenv_keyToken 异常升高抽取 Key 与主对话 Key 是否混用多工具共用 Key无法归因拆分 Key按服务观察用量关于 Base URL再强调一次TaoToken 的模型调用地址是 https://taotoken.net/api 这个地址在配置里不要加 UTM 参数也不要写成别的路径。UTM 只用于官网入口和文档页统计。你在 Claude Code、Codex、脚本里填的 Base URL 都应该是干净地址。如果 Fact 抽取重复率很高可以做一个本地相似度阈值实验。比如先用向量模型计算候选 Fact 与已确认 Fact 的余弦相似度# 伪代码本地去重不调用远程模型 def should_ask_llm(candidate, existing_facts, embed, cosine): for fact in existing_facts: score cosine(embed(candidate[fact_text]), embed(fact[fact_text])) if score 0.92: return duplicate, fact if score 0.78: return ask_llm, fact return new, None相似度大于 0.92 的直接视为重复不再调用模型0.78 到 0.92 之间才让模型判断“更新还是忽略”低于 0.78 的直接作为新候选。这样能把大量重复判断挡在模型之外TaoToken 上的抽取调用量会明显更稳定。如果确认流程不生效检查服务层是否真的写了长期记忆库。很多实现只把待确认记录状态改成confirmed但召回逻辑读的是另一张表。可以加日志候选 ID、确认人、写入表、写入时间、召回命中次数。这样一旦用户说“我明明确认过”你可以快速定位是没写入还是写入了但召回没命中。7. 上线前检查清单与高转化接入路径在上线 WeKnora 风格的 Fact 长期记忆之前建议按下面清单过一遍Fact 抽取只处理最近一轮或最近一个窗口不要全量历史反复跑。Prompt 必须限定typefact并明确禁止 Preference、Task、Interest、Profile。候选结果必须进入待确认队列needs_confirmationtrue不允许绕过。去重先用本地向量或规则模糊区间再调用模型。确认写入由后端服务完成模型和 MCP 不直接写生产库。召回设置 top-k、scope 过滤和最大 Token避免上下文膨胀。给 Fact 抽取、主对话、确认摘要分别创建 TaoToken Key方便归因用量。Claude Code 用settings.json和ANTHROPIC_*Codex 用config.toml和model_providerCC Switch 维护三件套档案不要混用。如果你还没有 Key建议按下面路径走顺序不要颠倒先到模型对话页做一次最小调用确认模型和 Key 可用https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_fact_chat如果准备日常开发使用查看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_fact_plan进入控制台创建独立 Key给 Fact 抽取服务和编码工具分开https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_fact_keysClaude Code 用户参考文档完成 settings.json 配置https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_fact_claudecode最后再回到 WeKnora 的 Fact 记忆本身。企业知识 Agent 的长期记忆不是“记得越多越好”而是“记得越准越好”。Fact 类记忆如果直接自动写入短期看起来 Agent 更聪明长期看却会增加召回噪声和 Token 成本。把抽取、确认、去重、召回拆成可控步骤再用 TaoToken 统一模型出口和用量观测你就能在复现 WeKnora 这类企业知识底座能力时既保留 Agent 的记忆体验又不让记忆系统变成新的黑盒成本中心。官网入口在这里https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_fact_final 需要进一步看模型、创建 Key、配置 Claude Code 时按文末路径逐项完成即可。