资讯动态

技术线04_端侧4B如何做到可控长会话问答

发布时间:2026/10/1 15:38:22 来源:尧图企业网站定制
端侧 4B 也能做到可控长会话问答Agent 记忆、难点与一套工程实践面向读者正在做 RAG、Agent、桌面端 AI 或私有化部署的工程师。示例系统一个完全离线、端侧部署的质量体系助手。生成模型冻结在 Qwen3.5-4B Q4_K_M嵌入模型使用 bge-m3。结论先说上下文记忆不等于把聊天记录塞进模型。可用的 Agent 记忆是“最近完整轮次 滚动摘要 任务事实 结构化意图 可追溯证据”的组合。4B 模型的关键不是变大而是把解释权交给模型把意图仲裁、证据选择、引用校验和业务判定交给确定性层。一、传统 Agent 怎么做上下文记忆很多系统把记忆做成一个简单的对话数组每次提问都把最近 N 条消息拼进 prompt。这在演示里够用但轮次一多会遇到三个典型问题早期事实被滑出窗口摘要压缩后丢失对象和约束检索 query 里混入历史噪声导致当前问题答非所问。成熟的记忆体系通常分成五层。1. 短期记忆保留最近完整轮次最近几轮对话保持原文不急着压缩。原因是短追问、指代、比较和口语表达高度依赖原文细节。比如用户先问“技术归零是什么”再问“它和管理归零有什么区别”“那五条要求分别是什么”这些“它”“那”“五条要求”必须从近期上下文解析。但窗口不能无限扩大。上下文越长KV cache、首 token 延迟、显存或内存压力都会增加而且历史主题会污染当前问题。2. 滚动摘要把滑出窗口的内容收敛成可回溯结论当早期轮次滑出短窗口后可以生成滚动摘要。摘要要保留的是任务对象、用户确认过的事实、已经给出的结论、待补信息和当前约束而不是复述每一句话。有两个工程细节很关键原始消息不能被重写。摘要应该单独存储带来源区间和内容哈希否则后面无法审计“模型为什么记成了这样”。摘要更新应该是增量的。每次都重压全量历史长会话会变得又慢又不稳定。3. 固定事实不要指望摘要永远保真项目代号、用户选择的对象、当前文件类型、材料版本、任务状态这类信息不适合只依赖摘要。它们应该进入独立的结构化事实表并在组装 prompt 时获得更高优先级。例如用户说“请记住项目代号是 PROJ-2026-001”这类显式事实可以由确定性逻辑写入session_facts。后续提问时如果命中的是固定事实就不需要再让 4B 模型自由回忆。4. 外部记忆与 RAG知识不进参数进可追溯资产领域知识、标准条款、模板大纲、规则包、历史案例应该放在外部存储里。向量检索负责语义召回关键词、条款树、实体目录、规则路由负责精确约束。这一层的重点是来源控制公共知识只读不吸收用户敏感材料。当前任务材料只绑定当前任务不进入公共向量库。检索无命中时应该拒答或澄清而不是让模型补全。输出中的引用必须通过白名单或库内校验。5. 任务记忆Agent 真正需要的是状态机对业务型 Agent 来说仅记住“聊过什么”不够还要记住“正在做什么”。这通常包括记忆类型内容典型问题意图链当前主意图、次意图、对象、主题、置信度“还有吗”继承哪个对象证据计划本次要查哪些范围、工具、条款、模板和材料不要把整个历史拼进检索工具结果解析结果、规则检查结果、评分结果、文件版本结论是否支持后续追问会话状态当前材料、当前任务、待澄清项、已完成步骤主题切换后旧对象是否过期一个健康的链路通常是会话调度 - 路由契约 - 上下文构建 - 意图解析与守卫 - 证据计划 - 检索 / 工具执行 - 门禁预检 - LLM 组织表达 - 门禁后检 - 结构化输出或降级LLM 只出现在“组织表达”和极少数受控解析环节而不是自由决定记忆、检索、判定和结论。二、上下文记忆用什么指标衡量“回答比较理想”不是一个工程指标。落地时至少要看六组指标。1. 检索质量指标说明RecallK前 K 个片段是否召回正确证据MRR / nDCG正确证据排得有多靠前命中率至少一条有效证据进入 prompt 的比例无命中拒答率无证据时是否稳定拒答而不是编答案垂直知识库尤其要看“无命中拒答率”。把不知道说成知道比少答一条更危险。2. 上下文继承质量指标说明上下文继承准确率短追问是否继承正确对象和主题对象 / 实体准确率“它”“这类”“刚才那个”是否解析正确主题污染率新主题是否误用旧上下文长程事实召回率第 1 轮事实在第 N 轮仍能被正确使用这个指标比单轮问答准确率更能暴露记忆设计问题。3. 语义路由与意图质量指标说明意图准确率问定义、要求、写法、比较、模板还是任务操作域外误放行率越界问题是否被错误回答误澄清率明确问题是否被反复追问跨功能引导准确率查文件、找模板、算分、改状态是否引导到正确入口4. 回答质量与安全性指标说明任务通过率自动断言或人工评分通过比例引用精度 / 引用召回引用是否支持结论关键结论是否都有依据编造条款率输出中不存在库外标准号或条款号P0 / P1 缺陷数编造、越权判定、核心遗漏、上下文污染等落库展示一致性存储内容、Trace 和前端展示是否一致5. 性能与资源指标说明首 token 延迟用户开始看到反馈的时间总耗时 P50 / P95单题端到端耗时检索耗时embedding 和 TopK 查询成本每秒 token 数生成吞吐常驻内存 / 峰值内存模型、上下文、索引和应用总占用降级成功率模型失败时能否回退规则或摘录模式6. 可运营性还要看题库是否能轮换、失败能否复现、Trace 是否脱敏、知识包是否有哈希和版本、回归是否能锁住旧缺陷。没有这些一次高分只是运气。能做到什么水平不同任务没有统一的“理想分数”。可以按记忆体系成熟度大致分层层级典型能力适合边界简单聊天窗口最近 5 到 10 轮较稳轻度闲聊不适合业务系统滚动摘要 固定事实20 轮以上仍能承接显式对象和事实长对话助手但证据密集任务仍弱RAG 引用校验封闭语料内可做到高命中、高引用、低编造标准问答、制度问答、产品手册意图链 证据计划 规则门禁固定评测集内可以做到很高的机器验收通过率高可信垂直 Agent在封闭评测集和明确业务边界里做到 95% 以上甚至 100% 工程验收通过是可能的但这不等于开放域全能也不能跳过人工盲评。真正可信的系统必须同时报告通过率、失败分类、拒答边界、数据集版本和剩余风险。三、端侧 4B 模型会遇到哪些困难把生成模型从云端大模型换成端侧 4B困难不是线性增加而是系统设计方式要变。1. 内存不是只看模型文件大小Q4_K_M 量化的 4B 权重文件大约 2.3 到 2.5GB但产品运行时还要加上 KV cache、上下文、embedding 模型、SQLite、解析器、前端和系统开销。工程目标是让 8GB 内存的机器最低可用16GB 内存获得更稳体验。如果为了长记忆把 50 轮对话都塞进去很快就吃掉低配机的可用空间。所以上下文预算必须显式分配而不是“能塞多少塞多少”。2. 小模型更容易被历史噪声带偏4B 模型对复杂指令和长距离依赖的稳定性弱于大模型。把大量历史原文、检索片段、系统规则和工具结果堆在同一个 prompt 里常见结果是当前问题继承错误对象把上一轮任务误当成本轮意图忽略输出 schema把检索到的相似标准当成命中的标准用流畅语言遮盖证据缺口。所以检索 query 不能直接拼接全部历史。更好的做法是先解析当前意图和对象再生成有界的证据计划。3. 语义检索对小输入和编号输入不友好领域系统里有两类高频难点短追问很多“还有吗”“这些判据出自哪里”“必须改的还有吗”。精确编号很多标准号、条款号、审查项编号、文件编号。纯向量检索容易被相似文本带偏。比如库外标准问题相似度可能很高但标准号根本不在库内。如果只用相似度阈值就可能出现“高置信地答错”。一个早期基线评测里4 个域外或库外问题全部未拒答其中一个错误关联到GJB 450A-2004相似度约 0.8015。4. 输出契约和工具调用不稳定云端大模型可以较稳地输出 JSON、调用工具、维护多步计划。4B 模型不能默认具备这个能力。JSON 字段容易漂移枚举容易编造工具参数容易混入自然语言。解决办法是把模型输出当成“候选提案”而不是“最终决定”。必须加封闭 JSON schema枚举白名单最大重试次数和时间预算schema 失败后的规则回退确定性仲裁器校验目标、范围和引用。5. 摘要本身也消耗预算长会话摘要通常需要一次额外模型调用。在端侧这会挤占延迟、内存和上下文预算。摘要失败时还要有确定性降级否则一个辅助功能会把主链路拖死。可执行的预算策略是摘要只在滚动出窗口时触发摘要上限 1500 字符prompt 历史块上限 10000 字符生成服务不可用时退化为确定性摘要。6. 延迟预算更紧一份本地性能基线显示embedding 加 TopK 检索的 P50 约 11.17msP95 约 22.36ms本地生成总耗时 P50 约 7.42sP95 约 11.67s。检索很快生成才是延迟大头。如果意图解析也让模型做就必须给硬预算。否则真实用户一句短追问可能要等两次生成才得到答案。工程上可以把 LLM 意图解析限制在 2 秒内超过即回退规则路径。7. 业务判定不能交给模型在质量体系场景里符合性、扣分、风险等级、正式审查结论都不能由概率模型给出。哪怕 4B 模型解释得再顺也不能让它算分。这意味着架构上必须区分判定规则引擎、打分表、状态机组织语言LLM证据选择检索与确定性证据计划引用校验白名单和库内校验边界裁决Policy Guard、Quality Gate。四、一个端侧 4B 系统怎么做优化这个示例系统覆盖标准问答、文件检查、模板中心、研制过程评审、评审模拟和资格审查。下面这些优化围绕同一个目标在 4B、断网、低配可用的约束下让长会话问答可控、可查、可降级。1. 先建基线再改架构先冻结一组评测用例覆盖上下文、模板大纲、材料审阅、拒答、检索、工具链、多会话、内核行为和性能。基线暴露了三类真实问题上下文只读 8 轮、检索只增强最近 2 轮第 1 轮事实在 12 轮后不可见。4 个域外或库外问题全部未拒答。技术归零等范围检索缺位模板大纲输出会被审查类提示词覆盖。这一步很关键。先让失败可复现再决定改哪个模块。2. 用 Context Core 显式分配记忆预算系统引入独立 Context Core而不是继续在业务 handler 里拼 prompt。规则是项配置读取最近轮次12最近完整轮次4检索增强主题最近 3 轮滚动摘要上限1500 字符prompt 历史块上限10000 字符首次补齐长历史摘要来源最多 16 轮核心配置可以直接固化为代码常量pubconstREAD_PAIRS:usize12;pubconstRECENT_PAIRS:usize4;pubconstRETRIEVAL_CONTEXT_PAIRS:usize3;pubconstSUMMARY_MAX_CHARS:usize1_500;pubconstPROMPT_MAX_CHARS:usize10_000;pubconstSUMMARY_SOURCE_MAX_PAIRS:usize16;进入 prompt 前先把“固定事实、滚动摘要、最近轮次”分成三个优先级letsplitturns.len().saturating_sub(RECENT_PAIRS);let(older,recent_turns)turns.split_at(split);render_prompt_block(summary,recent_turns,pinned_facts,PROMPT_MAX_CHARS,)固定事实的渲染规则尤其重要。它必须显式告诉模型这些事实优先于摘要。if!visible_facts.is_empty(){block.push_str(【会话固定事实】\n);forfactinvisible_facts{block.push_str(- );block.push_str(fact.fact_value.trim());block.push(\n);}block.push_str(以上事实由用户在本会话中明确确认回答相关问题时必须优先使用\ 不得被更早摘要覆盖。\n\n,);}第 5 轮以前的轮次进入滚动摘要。摘要单独存储带来源消息区间、来源哈希和是否调用模型的标记。原始消息不重写删除会话时同步清理摘要。同时增加固定事实层。用户明确要求记住的项目代号、备注等信息优先于滚动摘要。这样即使摘要压缩丢细节关键事实也不会丢。在真实模型回归中第 1 轮写入的项目代号在 13 轮后仍能被正确回答已测路径无上下文溢出。3. 意图链、证据计划和上下文记忆分离系统不再让 Context Core 直接把历史拼成检索 query而是拆成三个职责Intent Core解析当前意图、对象、主题、引用和继承关系。Evidence Planner根据结构化意图生成证据计划。Context Bridge只补充被引用的结论和长历史摘要。每轮最多读取最近 12 轮意图状态更早内容只来自 Context Core 摘要。Intent Core 或 Evidence Planner 损坏时按未知或域外问题处理不开放模型自由发挥。这解决的不只是“记得住”更是“记得准”。历史只允许补齐缺失对象和任务不能争夺当前问题的解释权。检索 query 的构造也保持有界当前问题优先只补充最近 3 轮话题和上一轮结论。pubfnbuild_retrieval_query(question:str,turns:[ConversationTurn],)-String{letmutpartsvec![question.trim().to_string()];letrecent_questions:VecStringturns.iter().rev().take(RETRIEVAL_CONTEXT_PAIRS).map(|turn|excerpt(turn.question,150)).collect();if!recent_questions.is_empty(){parts.push(format!(相关话题{},recent_questions.join()));}ifletSome(last)turns.last(){letconclusionexcerpt(last.answer,PRIOR_CONCLUSION_EXCERPT);if!conclusion.is_empty(){parts.push(format!(上一轮结论{conclusion}));}}dedupe_query_parts(parts)}证据计划则由结构化意图驱动并且在一开始就声明数量上限pubconstMAX_RETRIEVAL_QUERIES:usize3;pubconstMAX_DIRECT_SOURCES:usize8;pubstructEvidencePlan{pubevidence_ids:VecEvidenceKind,pubretrieval_queries:VecString,pubrequired_direct_sources:VecString,puboutput_contract:String,puballowed_tools:VecString,}生成计划前域外问题直接返回空证据计划需要明确对象但没有对象时返回澄清而不是猜一个检索词。ifstate.domain_status!DomainStatus::InDomain{returnOk(EvidencePlan{evidence_ids:Vec::new(),retrieval_queries:Vec::new(),required_direct_sources:Vec::new(),output_contract:no_evidence.into(),allowed_tools:Vec::new(),});}ifrule.requires_targetsstate.target_ids.is_empty(){returnOk(EvidencePlan{evidence_ids:Vec::new(),retrieval_queries:Vec::new(),required_direct_sources:Vec::new(),output_contract:clarification.into(),allowed_tools:Vec::new(),});}4. 4B 模型只做受控提案最终由仲裁器决定LLM Intent Parser 只作为受控提案器接入入口很窄只在低置信、上下文继承、复合意图等场景进入模型解析输出封闭 JSON schema最多两次 schema 修复总预算 2 秒白名单、引用、目标集非法时拒绝提案gen sidecar 不可用时回退规则意图。解析器的单次调用和总预算都写进常量不允许调用方临时放宽pubconstLLM_INTENT_MAX_TOKENS:u32128;pubconstLLM_INTENT_TIMEOUT_MS:u641_800;pubconstLLM_INTENT_TOTAL_TIMEOUT_MS:u642_000;schema 错误最多允许一次修复第一次调用已经耗掉超过 200ms 时连这次修复也直接放弃避免重试把短追问拖成一次长等待。letstartedInstant::now();letfirstself.invoke(user_prompt,budget,1,started);matchfirst.result{Ok(output)LlmIntentOutcome::succeeded(output,attempts),Err(code)if!code.retryable(){LlmIntentOutcome::failed(code,attempts,false)}Err(_){ifstarted.elapsed().as_millis()asu64200{LlmIntentOutcome::failed(LlmIntentFailureCode::RetryBudgetExceeded,attempts,false,)}else{self.retry_after_invalid(user_prompt,budget,started)}}}模型返回后先做 JSON schema 校验再校验封闭枚举和 ID 集合letvalue:Valueserde_json::from_str(trimmed).map_err(|_|LlmIntentFailureCode::InvalidSchema)?;letmutoutput:LlmIntentOutputserde_json::from_value(value).map_err(|_|LlmIntentFailureCode::InvalidSchema)?;whitelist.validate(mutoutput)?;Ok(output)也就是说模型给出的不是“最终意图”而是一个必须通过结构校验的候选提案。一份 60 例语义评测的主链路结果指标Rule 单路LLM 单路Arbiter 主链路意图准确率60.00%76.67%100.00%上下文继承准确率54.17%83.33%100.00%对象准确率70.27%89.19%100.00%域外误放行-00误澄清率-1.67%0LLM P95 延迟-1600ms1600ms这里最值得注意的不是 Arbiter 到了 100%而是 Rule 和 LLM 单路都没有达到 90% 阈值。也就是说小模型不能直接接主链路规则快速路径、模型候选和确定性仲裁一起才组成可用系统。另一组复测中Arbiter 意图准确率 98.33%上下文继承 100%对象准确率 97.30%域外误放行 0LLM P95 1715ms。数值会随版本和题集变化但架构边界保持不变。5. 无检索不回答输出后继续校验标准问答链路保持几条硬门禁检索 Top1 相似度低于阈值时不进 LLM。无命中返回固定拒答或澄清。输出中的标准号必须来自检索上下文或明确标注为示例。引用不在白名单时丢弃该句或降级为检索摘录。生成失败时回退到摘录模式不编造完整答案。后检的核心逻辑不是“相信模型”而是先根据本轮证据构造允许集合再删除包含未知引用的句子letmutallowed_docsallowed_from_docs(hits.iter().map(|hit|hit.doc.clone()));allowed_docs.extend(hits.iter().flat_map(|hit|profile.extract_standard_codes(hit.snippet)).map(|token|normalized_code(token)),);letbad_standardsunknown_tokens(profile.extract_standard_codes(answer),allowed_docs,);let(cleaned,removed_standards,_)strip_unknown_token_sentences(answer,bad_standards);ifremoved_standards0{violations.push(repaired(citation_standard_removed,答案含非本轮引用的标准号,false,));answercleaned;}条款号同理只有出现在本轮检索片段、结构化上下文或领域配置里的条款号才是可信引用。6. 连续追问不提高历史权限只扩大证据召回针对一类真实场景用户连续 3 轮围绕同一主意图追问说明前两轮证据可能没有覆盖真正关注点。处理方式不是让历史意图覆盖当前输入而是保留原 Evidence Plan追加当前输入、上下文增强 query 和原计划 query在同一知识范围内做多 query 兜底召回按 chunk 去重并合并分数不放宽相关性阈值、域外边界、标准号白名单和 Quality Gate。这样“连续不满意”会带来更多证据而不是带来更多模型自由。7. 用真实链路压测而不是只测单模块标准问答做过连续三轮 50 题轮换评测结果均为 50/50。随后执行 100 题连续压力包首轮 98/100暴露“这些判据”这类指代链问题和证据兜底超长问题修复指代词表、当前任务继承和 1200 字硬上限后完整重跑 100/100。100 题包含 10 个独立会话、每会话连续 10 轮总耗时约 20.5 分钟。这个数字不代表单题 P95但它说明当时本机端侧链路的整体吞吐量级。真实问法评测更有代表性30 道真实问题和 70 道同风格仿真题组成 100 题10 组每组连续 10 问。经过失败归因和修复最终完整复测 100/100。失败集中在专用知识 Provider 抢答、模板写作入口词、评审表达和边界问题而不是单靠 prompt 能修好的问题。8. 覆盖多个功能域而不是只优化聊天一组五类功能普通问答评测覆盖标准问答、模板中心、研制过程评审、评审模拟和资格审查三轮共 750 次真实链路执行450 道唯一题三轮机器判定均为 250/25025 个连续会话组每轮全部通过86 个引导题全部命中目标功能750 题落库展示一致只有 138 题进入生成回答其余大量问题由确定性知识或结构化引导完成。质量代理六维审计平均分 98.72最低 75445/450 达到 85 分以上。但这里必须保留边界代理审计不能替代业务人员盲评机器通过率也不等价于业务验收结论。文件检查也做了材料级连续会话验证25 份材料、每份 10 个连续问题250/250 通过。真实用户短句场景还会出现“能用吗”“必须改的还有吗”这类短问、反驳和前后一致性问题需要用确定性守卫承接最近一次检查结论避免回答自相矛盾。五、可借鉴的七条经验1. 记忆是多种状态的组合不是聊天记录短期窗口、滚动摘要、固定事实、意图链、证据计划、任务状态和材料版本要分开建模。任何一个都被当成“万能记忆”长会话一定会崩。2. 上下文优先级要显式当前输入和当前材料最高其次是当前任务事实然后是最近轮次再是滚动摘要最后才是历史检索。历史上下文只补齐缺失信息不重写当前意图。3. 小模型输出必须可拒绝schema、枚举、目标集、引用和耗时都要校验。模型提案失败就回退规则路径。不能因为模型返回了 JSON就默认它是对的。4. 检索召回要由证据计划驱动不要让模型或上下文模块随手拼 query。意图、对象、范围、材料状态和工具白名单先生成 Evidence Plan再由检索执行。历史只用于补对象不用于淹没当前问题。5. 拒答是能力不是失败无命中、库外标准、越界任务、无材料假装检查、无事实生成正式文件都应该拒答或引导。域外误放行率必须单独作为发布门禁。6. 判定和表达分家分数、符合性、风险、正式结论由规则和状态机给出。LLM 负责把已经确定的事实讲清楚。这不是浪费模型能力而是让模型工作在自己可验证的边界内。7. 验收必须覆盖真实链路和真实问法单元测试、检索离线评估、语义评测、连续会话压测、材料级追问、跨功能引导、落库一致性、隐私扫描和版本哈希都要有。尤其是固定锚定题加动态题轮换才能区分“能力稳定”和“背题成功”。结语端侧 4B 的价值不在模仿云端大模型而在重新划清系统边界。这个项目的实践可以压缩成一句话让模型记得少一点、说得稳一点让规则记得准一点、管得住一点。当上下文预算、意图仲裁、证据计划、引用校验和业务判定都被工程化之后4B 离线模型完全可以承担一个高质量垂直助手的语言组织层。剩余短板也很清楚语言美学、长尾表达和业务盲评仍需要持续评估不能被漂亮的机器通过率掩盖。说明文中评测数据来自示例系统内部评测记录。不同题集、版本、硬件和并发条件下的结果不可直接横向比较。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑