
1. 跨会话失忆的 Coding Agent卡在哪一环用 DeepSeek Harness 连着做几天 Coding 问答的人大概都遇到过同一个尴尬昨天刚跟 Agent 讲清楚「这个仓库的鉴权走网关下发的一次性 Token不要写死在 config 里」今天新开一个 session它又老老实实给你在配置里塞了个硬编码字符串。更别提多轮改造任务里第三轮它已经忘了第一轮你强调过的目录结构约定。这不是模型能力问题是记忆链路没接上——上下文窗口会滑走会话会结束而项目约束需要一直在。WeKnora 补的正是这一环。它把 Profile、Preference、Fact、Task、Interest 这几类信息做成可确认、可召回的跨会话长期记忆再通过 API、CLI 和 MCP Server 暴露给外部 Harness。DeepSeek Harness 那边有官方插件wxg-prc-cpg/dsh-weknora挂上之后 Coding Agent 能直接检索知识库、读取完整文档或走 WeKnora 的 RAG / ReAct 流程完成问答。而在模型侧长期记忆召回会明显抬高 Token 消耗——每一轮都要把召回的 memory 片段重新塞进上下文跑对照实验时额度跳动会直接打断节奏。用 TaoToken 统一管 Key 和配额会省心很多注册入口在这https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_memory 登录后在控制台创建 Key模型侧的 Base URL 统一填https://taotoken.net/api。本文要交付两样可复现的东西一套能跑通的「WeKnora 长期记忆召回配置」以及一份「DeepSeek Harness 多轮问答对照」记录方法。全部按 Coding Agent 使用者的视角展开不含任何需要跳步的地方。2. 模型侧先打通TaoToken 的 Key、Base URL 与三件套很多人在这一步翻车不是因为难而是把不同工具的配置项串了。先把边界划清楚Claude Code 走ANTHROPIC_*环境变量族Codex 走config.toml两者不能互相套用。把ANTHROPIC_BASE_URL写进 Codex 的配置文件里代码不会报错但也不会生效你只会看到一个莫名其妙的 401。2.1 先拿 Key打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_key 注册后进控制台在 API Keys 页面创建一个新 Key复制出来。这个 Key 后面在三个地方要用Claude Code、Codex、以及 WeKnora 里配置的模型调用通道。建议单独建一个用途为weknora-lab的 Key方便跑完实验后单独撤销。2.2 Claude Codesettings.json 写法Claude Code 推荐用配置文件而不是每次 export 环境变量这样换项目时不会互相污染。编辑~/.claude/settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_MODEL: claude-sonnet-4-5, ANTHROPIC_SMALL_FAST_MODEL: claude-haiku-4-5 } }如果你更习惯 shell 层面注入等价写法是export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_AUTH_TOKENYOUR_API_KEY export ANTHROPIC_MODELclaude-sonnet-4-5注意ANTHROPIC_BASE_URL末尾不要带/v1SDK 会自己拼路径手动加一层会得到 404。2.3 Codexconfig.toml 写法Codex 用的是完全另一套 schema文件位置在~/.codex/config.tomlmodel gpt-5-codex model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api responses对应地Key 通过环境变量传export TAOTOKEN_API_KEYYOUR_API_KEY这里的关键点是env_key指定的是环境变量名不是 Key 本身。把 Key 明文写进config.toml不会被读取会直接报缺 key。2.4 CC Switch 三件套如果你在多个供应商之间来回切本地 Ollama、自建网关、TaoToken手动改配置文件很容易漏。CC Switch 这类切换器的核心就是三件套Base URL统一指向https://taotoken.net/apiAPI Key用YOUR_API_KEY占位实际值从环境变量或密钥管理读取Model Name按 Harness 类型分开Claude Code 系走claude-*命名Codex 系走gpt-*-codex命名把这三项做成配置文件模板切换时整体替换不要只改其中一项。只改 Base URL 不改 Model Name是最常见的「配置看起来生效了但答非所问」的根因。3. 起 WeKnoraDocker Compose 与环境变量分层模型通道通了接着把 WeKnora 拉起来。官方推荐的方式是 Docker Compose前置依赖是 Docker、Docker Compose 和 Git 三样。3.1 拉起服务git clone weknora-repo-url weknora cd weknora cp .env.example .env docker compose up -d docker compose logs -f weknora-api等weknora-api日志出现监听端口后浏览器访问http://localhost进入 Web UI 完成初始化。如果你的机器上 80 端口被占用改docker-compose.yml里的端口映射即可但记得同步调整后面插件配置里的地址。3.2 环境变量分层别把模型 Key 和记忆开关混在一起.env建议按用途分成三段避免后面排查时分不清是模型通道问题还是记忆功能问题# ---- 1. 模型调用通道 ---- LLM_BASE_URLhttps://taotoken.net/api LLM_API_KEYYOUR_API_KEY LLM_MODELclaude-sonnet-4-5 # ---- 2. Embedding / Rerank ---- EMBEDDING_MODELbge-m3 RERANK_ENABLEDtrue # ---- 3. 长期记忆 ---- MEMORY_ENABLEDtrue MEMORY_REQUIRE_CONFIRMtrue MEMORY_TYPESprofile,preference,fact,task,interestMEMORY_REQUIRE_CONFIRMtrue这一项建议保持开启。WeKnora 的长期记忆设计里Agent 从对话中自动提取出来的记忆不会直接落库而是进入待确认队列等用户点头后才写入。这对 Coding 场景尤其重要——Agent 很容易把一次性的临时要求「这次先跳过单测」误当成长期偏好「这个项目不用写单测」存下来之后每次生成代码都少给你测试文件。变量名以你拉到的项目版本 README 为准不同 release 会有差异。判断是否生效的方法很简单进 Web UI 后看记忆管理页如果只有「已确认」一个列表而没有「待确认」说明 confirm 开关没打开。3.3 数据源接入顺序WeKnora 支持多格式文档解析、向量检索与 BM25 混合搜索、Rerank以及飞书、Notion、GitLab 等数据源接入。跑 Coding 对照实验时不需要一次性全接。推荐分两步第一步只丢一份项目内的CONTRIBUTING.md和架构说明文档确认召回链路通了第二步再接 GitLab让 Agent 能直接读仓库里的 issue 和 MR 讨论。一上来就接全量数据源出问题时你无法判断是文档解析环节还是检索环节排查成本会翻倍。4. 挂上 DeepSeek Harnessdsh-weknora 插件配置这是整条链路里最关键的一步。WeKnora 官方给 DeepSeek Harness 提供了插件wxg-prc-cpg/dsh-weknora接入后 Coding Agent 就获得了三个动作搜索知识库、读取完整文档、调用 RAG / ReAct 流程问答。4.1 安装与注册在 Harness 的运行环境里装插件npm install wxg-prc-cpg/dsh-weknora --save-exact然后在 Harness 的插件清单里注册。配置文件通常是 JSON 格式{ plugins: [ { name: dsh-weknora, package: wxg-prc-cpg/dsh-weknora, config: { endpoint: http://localhost, apiKey: YOUR_WEKNORA_API_KEY, enableSearch: true, enableReadDocument: true, enableRagFlow: true, memoryRecall: true, recallTopK: 5 } } ] }YOUR_WEKNORA_API_KEY是 WeKnora 自己的 API Key在 Web UI 的设置页生成YOUR_API_KEY是 TaoToken 的 Key。两个 Key 分属不同系统别搞混混了会得到 401 但日志里看不出是哪个环节拒的。4.2 记忆召回的两个开关这里有个容易踩的坑。很多人以为插件的memoryRecall一开就完事了其实还有一层——WeKnora 侧的记忆确认状态。如果某条记忆还停在「待确认」插件调召回接口时它不会出现在结果里。所以完整的召回链路是对话中 Agent 抽取候选记忆 → 进入待确认队列用户在 Web UI 或通过接口确认 → 写入长期记忆库后续会话发起时插件按recallTopK拉取相关记忆记忆片段被拼进系统提示随请求一起送到模型侧模型侧按 Token 计费这部分消耗随轮次线性增长第 4、5 步就是为什么建议用 TaoToken 统一管配额。跑对照实验时A 组关记忆、B 组开记忆两组的 Token 曲线差异会非常明显用同一套 Key 管理能让实验数据更干净。4.3 如果 Harness 不支持插件机制有些自研 Harness 或者旧版本没有插件系统这种情况下降级用 MCP Server 方案把 WeKnora 的 MCP Server 端点配到 Harness 的 MCP 列表里让模型通过标准的 MCP 工具调用去访问知识库。功能上会少掉一部分自动召回但搜索和读取文档这两个核心动作仍然可用。5. 多轮 Coding 问答对照实验设计配置跑通之后需要验证「长期记忆到底有没有被召回」。别靠感觉做一组对照实验。5.1 实验设计造一个需要跨会话约束的任务场景。比如会话 1要求 Agent 为一个 Python 服务加缓存层并明确约束「缓存 Key 必须走统一的 key builder禁止手写 f-string」会话 2隔天新开要求 Agent 为另一个模块加 Redis 缓存如果记忆生效会话 2 里 Agent 应该直接使用 key builder 而不是手写字符串如果记忆没生效它大概率会重新发明一遍。对照组设置三组组别记忆召回知识库检索观察点A关闭关闭基线每次都要重新交代约束B关闭开启看文档知识能否补上部分约束C开启开启完整链路看跨会话约束是否延续5.2 记录方式每轮问答记录四个字段用脚本落盘import json from datetime import datetime from pathlib import Path def log_turn(group, turn, question, answer, recalled_memories, prompt_tokens, completion_tokens): record { ts: datetime.now().isoformat(), group: group, turn: turn, q: question, a_excerpt: answer[:500], recall_count: len(recalled_memories), recall_types: [m.get(type) for m in recalled_memories], prompt_tokens: prompt_tokens, completion_tokens: completion_tokens, } path Path(flogs/{group}.jsonl) path.parent.mkdir(parentsTrue, exist_okTrue) with path.open(a, encodingutf-8) as f: f.write(json.dumps(record, ensure_asciiFalse) \n)recall_count是判断记忆是否真的进上下文的最直接证据。如果 C 组第 3 轮开始recall_count稳定在 2 到 5 之间说明召回链路在工作如果一直是 0往上查两件事记忆是否已确认、插件的memoryRecall是否真的生效。5.3 看 Token 曲线的形状A 组和 C 组的 prompt tokens 曲线形状完全不同。A 组因为每轮都要重新描述背景prompt 会随轮次持续爬升C 组在记忆生效后背景描述被记忆片段替代单轮增量会更平稳。但 C 组的绝对值通常高于 B 组因为记忆片段本身也占 Token。这就是为什么召回条数recallTopK不要设太大。设成 20每轮塞 20 条记忆进上下文既挤占代码上下文空间又让成本失控。5 条左右通常是性价比拐点具体要按你自己项目里记忆片段的平均长度实测。6. 常见报错与排查路径跑这条链路会遇到几类典型问题按出现频率排列。第一类401但不知道是哪一层的 401。先看错误体里的字段。返回信息提到ANTHROPIC相关字段的是 Claude Code 那条通道提到provider或model_provider的是 Codex 的config.toml问题如果错误来自 WeKnora 的接口那就是 WeKnora 自己的 API Key 不对。三个 Key 分属三层排查时先定位层级再改。第二类模型返回结果正常但记忆一条不召回。检查顺序MEMORY_ENABLED是否为 true、目标记忆是否已确认、插件memoryRecall是否为 true、recallTopK是否大于 0。这四项里任意一项关着召回都会静默失败——不会报错只是行为退化成无记忆。第三类Agent 记住了不该记的东西。典型现象是某次临时要求被固化成长期偏好。解决办法是保持MEMORY_REQUIRE_CONFIRMtrue并且定期去记忆管理页做一次清理把 Task 类型的过期条目删掉。Task 类记忆最容易堆积做完的任务应该及时销掉。第四类Codex 配置没生效。八成是把ANTHROPIC_BASE_URL写进了config.toml。Codex 只认model_providers.name.base_url这个字段结构其他形式的 URL 配置会被忽略。第五类Docker Compose 起来了但 Web UI 打不开。先docker compose ps看容器状态再docker compose logs weknora-api看是否有迁移失败。首次启动时数据库初始化需要一点时间日志里出现监听信息之前访问会连接被拒属正常现象。7. 把知识层和模型层拆开管WeKnora 这类项目真正有意思的地方是它把企业知识层从具体 Harness 里拆了出来。一家公司内部同时跑 Claude Code、DeepSeek Harness 和各种自研 Agent模型不同、Harness 不同但底下可以共享同一套知识库和长期记忆。这个拆法对个人开发者同样成立。你可以把项目规范、踩坑记录、架构决策都沉淀进 WeKnora让不同的 Coding 工具都能查到同时把模型调用统一收口到 TaoTokenKey 轮换、配额监控、成本归因都在一个地方做。两层的职责边界清晰之后换模型不会丢知识换 Harness 不用重配 Key。想直接体验模型对话链路可以从这里进https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_chat 。如果打算长期跑 Coding Agent月付型方案在连续多轮召回场景下更划算可以看 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_plan 。创建 Key 的入口在 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_apikey Claude Code 侧的完整配置说明在 https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentweknora_doc 。按本文的顺序走一遍先在控制台拿 Key把 Base URL 设成https://taotoken.net/api用 settings.json 或 config.toml 把对应 Harness 配好再用 Docker Compose 起 WeKnora打开记忆确认开关最后挂wxg-prc-cpg/dsh-weknora跑一组 A/B/C 对照看recall_count和 Token 曲线两个指标。这套流程跑通之后跨会话的 Coding 约束就能真正延续下来而不是每开一个新窗口就从头解释一遍。