news 2026/9/18 13:20:39

Fact 类记忆抽取,TaoToken 管住 WeKnora Agent 消耗

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Fact 类记忆抽取,TaoToken 管住 WeKnora Agent 消耗

1. 先管住模型出口:WeKnora 的 Fact 记忆为什么容易烧 Token

最近微信团队开源的 WeKnora 把企业知识库往 Agent 知识层推进,长期记忆里的 Fact 类信息很值得企业知识 Agent 开发者先动手验证。你要复现“从对话里抽取 Fact,等待用户确认,再按需召回”这条链路,第一件事不是改 Prompt,而是把模型调用出口固定到 TaoToken:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=weknora_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_source=taotoken_aicg_blog_end&utm_content=weknora_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_confirmation=true。 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_url="https://taotoken.net/api", api_key=os.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}"}, ], temperature=0.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_source=taotoken_aicg_blog_end&utm_content=weknora_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 Code:settings.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_URLANTHROPIC_MODEL,然后用系统环境变量注入ANTHROPIC_AUTH_TOKEN。例如在本地 shell 里:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY" export ANTHROPIC_MODEL="你的Claude模型ID"

验证时不要只看 Claude Code 是否启动,要看它发出的请求是否命中 TaoToken。你可以先在模型对话页做一次最小调用,确认 Key 可用,再去配 Claude Code。模型对话入口在文末 CTA 里。

4.2 Codex:config.toml 用 model_provider

Codex 的配置逻辑和 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_KEY="YOUR_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 做多工具切换,建议把它当成“三件套”来维护:

  1. Claude Code 档案:只放ANTHROPIC_BASE_URLANTHROPIC_AUTH_TOKENANTHROPIC_MODEL
  2. Codex 档案:只放model_providerbase_urlenv_keymodel
  3. 通用环境变量档案:放TAOTOKEN_API_KEY=YOUR_API_KEY,供 Codex 和其他脚本读取。

不要为了省事,把 Claude 的ANTHROPIC_AUTH_TOKEN直接填到 Codex 的env_key里。Codex 读的是TAOTOKEN_API_KEY这类变量,不是ANTHROPIC_*。如果你在 CC Switch 里切换后出现配置不生效,优先检查它是否覆盖了项目目录下的settings.jsonconfig.toml

需要统一管理 Key 时,从 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=weknora_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_KEY
404 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_provider+env_key
Token 异常升高抽取 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 长期记忆之前,建议按下面清单过一遍:

  1. Fact 抽取只处理最近一轮或最近一个窗口,不要全量历史反复跑。
  2. Prompt 必须限定type=fact,并明确禁止 Preference、Task、Interest、Profile。
  3. 候选结果必须进入待确认队列,needs_confirmation=true不允许绕过。
  4. 去重先用本地向量或规则,模糊区间再调用模型。
  5. 确认写入由后端服务完成,模型和 MCP 不直接写生产库。
  6. 召回设置 top-k、scope 过滤和最大 Token,避免上下文膨胀。
  7. 给 Fact 抽取、主对话、确认摘要分别创建 TaoToken Key,方便归因用量。
  8. Claude Code 用settings.jsonANTHROPIC_*;Codex 用config.tomlmodel_provider;CC Switch 维护三件套档案,不要混用。

如果你还没有 Key,建议按下面路径走,顺序不要颠倒:

  1. 先到模型对话页做一次最小调用,确认模型和 Key 可用:https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=weknora_fact_chat
  2. 如果准备日常开发使用,查看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=weknora_fact_plan
  3. 进入控制台创建独立 Key,给 Fact 抽取服务和编码工具分开:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=weknora_fact_keys
  4. Claude Code 用户参考文档完成 settings.json 配置:https://taotoken.net/doc/ClaudeCodeAnthropic?utm_source=taotoken_aicg_blog_end&utm_content=weknora_fact_claudecode

最后再回到 WeKnora 的 Fact 记忆本身。企业知识 Agent 的长期记忆不是“记得越多越好”,而是“记得越准越好”。Fact 类记忆如果直接自动写入,短期看起来 Agent 更聪明,长期看却会增加召回噪声和 Token 成本。把抽取、确认、去重、召回拆成可控步骤,再用 TaoToken 统一模型出口和用量观测,你就能在复现 WeKnora 这类企业知识底座能力时,既保留 Agent 的记忆体验,又不让记忆系统变成新的黑盒成本中心。官网入口在这里:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=weknora_fact_final ,需要进一步看模型、创建 Key、配置 Claude Code 时,按文末路径逐项完成即可。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 13:15:09

合同问题记录

文章目录 一、变更问题 hcbm_contract_relationship表 如何拿到框架协议变更后最新的合同内容? 如何根据1003231100021-1的合同id拿到这个合同关联的最后一个变更单? 变更后合同页面展示的问题 如何根据变更编号拿到变更后最新合同行信息? 关于relate_contract_number 关于s…

作者头像 李华
网站建设 2026/9/18 13:13:36

Python实现BP神经网络:彻底搞懂误差反向传播与梯度下降

简介&#xff1a;BP神经网络是机器学习中经典的多层前馈模型&#xff0c;其核心在于通过反向传播不断调整权重以降低预测误差。针对想从代码层面理解这一过程的Python开发者与入门学习者&#xff0c;这份PDF资源以“原理实现”的方式&#xff0c;系统讲解了三层网络的结构设计、…

作者头像 李华
网站建设 2026/9/18 13:12:43

像切换 Cursor 显示语言那样,这次用 TaoToken 走通模型接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 13:11:49

【Stable Diffusion】优秀提示词生成艺术作品图像

Stable Diffusion 作为一项深度学习驱动的图像生成技术,通过分析海量图像和文本语料,实现了从文本描述生成图像的能力。该技术以深度学习为核心,通过像素级别的预测,能够根据简单的文字提示生成丰富多样、符合预期的图像。其应用涵盖了从日常物品到复杂艺术风格的生成,让用…

作者头像 李华