「Python有LLMLingua,.NET呢?暂时没有直接替代品,但积木已经齐了。」这是Lukas Walter在他博客里的原话。一个让.NET开发者头疼很久的问题——RAG上下文太长、太贵、太慢——突然有了工程化的解法。
痛点:一万个token里,八千个是废话
![]()
做RAG(检索增强生成)的开发者都懂这个场景:用户问一个技术问题,系统从文档库里捞出十几页相关内容,连HTML标签、导航栏、重复页眉一起塞进大模型。
一万个token就这么出去了。每次查询都如此。
这些token里,真正有价值的可能只有技术参数、API签名、配置示例。剩下的是格式噪音:`
`标签、版权声明、上一章下一章的链接。按Claude 3.5 Sonnet的定价,输入一万token要0.3美元。如果日活一万次查询,一天就是三千美元,一年百万美元级别。
更隐蔽的伤害是延迟。token越多,首字返回时间越长。用户体验直接受损。
Python生态早有应对方案。LLMLingua用小型语言模型压缩提示,能把几千token压到几百,保留核心语义。.NET开发者只能干看着,或者自己造轮子。
现在轮子有了,而且搭在微软官方的基础设施上。
解法:让便宜模型干脏活,贵模型只干精活
核心思路是分层处理。不是把原始文档直接扔给GPT-4、Claude或Gemini,而是先过一个「预处理层」。
这个预处理层可以是:
本地Phi模型,通过ONNX Runtime GenAI跑在CPU或边缘设备上;或者更小的云端模型,比如Phi-3-mini、Llama 3.1 8B这类成本只有GPT-4几十分之一的选项。
给它的指令很直接:「只提取技术事实和标识符,删除所有散文。」
输出是浓缩后的结构化信息。然后再把这个精练版本送给主模型做最终推理。
成本结构完全变了。假设原始上下文一万token,压缩后剩一千。预处理模型费用忽略不计,主模型输入费用直接打九折。延迟同理——首token时间从2秒降到0.5秒的量级。
这不是理论。Semantic Kernel和Microsoft.Extensions.AI已经提供了管道化的基础设施。
代码:三行核心逻辑,塞一个中间件里
Microsoft.Extensions.AI的设计关键在`IChatClient`接口。它支持管道式组合,像ASP.NET Core的中间件那样层层包裹。
Walter给出的实现是一个`DelegatingChatClient`派生类:
第一步,清理样板:去掉HTML标签、重复页眉、导航元素。第二步,过滤低价值RAG片段:比如相似度阈值以下的chunk,或者纯广告/免责声明的段落。第三步,可选地调用小模型做语义压缩。
三件事情做完,才把消息交给内层的真实模型客户端。
代码结构很干净。业务逻辑完全不需要知道压缩的存在,它只跟一个普通的`IChatClient`打交道。压缩是横切关注点,像日志、缓存一样挂在管道里。
这种架构的好处是可替换。今天用Phi-3做压缩,明天可以用自研的小模型,或者等微软出了专门的压缩模型,直接换实现就行。业务代码不动。
对比Python的LLMLingua,.NET方案更「工程化」而不是「算法化」。LLMLingua是一整套压缩算法,包括token重要性估计、预算分配、迭代压缩。.NET这边目前是把算法选择权交给开发者——你可以自己写规则清理HTML,也可以调小模型,也可以两者结合。
灵活,但需要更多手工活。
为什么现在能做成:三个条件刚好凑齐
这个模式不是全新发明,但之前.NET生态玩不转,缺几个拼图。
第一,本地小模型的推理框架。ONNX Runtime GenAI是去年才成熟起来的,让Phi这种规模的模型能在消费级硬件上跑起来,延迟可接受。没有它,预处理层就得走网络调用,省下的钱被网络延迟吃掉,得不偿失。
第二,统一的抽象层。Microsoft.Extensions.AI今年正式发布,给各种模型客户端(OpenAI、Azure OpenAI、本地ONNX模型)套了同一个接口。管道模式才能成立。以前每个SDK各玩各的,没法无缝插入中间层。
第三,Semantic Kernel的RAG管道成熟。检索、分块、向量化这些基础设施稳定了,开发者才会把注意力转向「检索之后、生成之前」这个环节的优化。
三个条件同时满足,上下文压缩从「能做的demo」变成「该上的生产特性」。
实际收益:延迟、成本、架构 cleanliness
Walter列了三条收益,对应三个工程指标。
延迟方面,输入token减少通常直接转化为更快的首token时间。大模型的prefill阶段是计算密集型,token数和计算量基本线性。砍掉80%的输入,理论上有接近5倍的prefill加速。实际受网络、批处理策略影响,但改善是确定的。
成本方面,停止为低价值文本支付高端模型价格。如果原始RAG结果里50%是格式噪音,压缩后这50%的费用就省掉了。对于高频场景,这是六位数级别的年度节省。
架构方面,业务逻辑与提示工程解耦。压缩策略可以独立迭代,A/B测试,甚至针对不同用户群体动态调整。比如付费用户给完整上下文,免费用户走压缩管道——这种商业策略在代码层面只是一行配置。
一个细节:压缩本身也有成本。本地Phi模型是算力成本,云端小模型是token成本。需要监控压缩率,确保省下的主模型费用大于压缩开销。Walter没给具体数字,但指出这是「需要测量的」而非「假设成立的」。
落地建议:从规则清理开始,逐步上模型压缩
对于想尝试的.NET开发者,最务实的路径是分阶段。
第一阶段,纯规则清理。HTML标签、重复header、导航链接,用正则或DOM解析器干掉。零额外成本,通常能砍掉30-50%的token。先验证ROI——确实省钱了,再往下走。
第二阶段,加入基于相似度的chunk过滤。RAG检索返回的top-k结果,有些与查询意图关联很弱。用embedding相似度二次筛选,或者让重排序模型打分,剔除尾部内容。
第三阶段,引入小模型做语义压缩。这一步开始有推理成本,需要更严格的监控。建议从离线评估开始:拿一批真实查询,对比压缩前后的主模型输出质量,确认信息损失可接受。
三个阶段可以独立开关。`ContextCompressionChatClient`内部设计成策略模式,方便渐进式演进。
这件事为什么重要
它标志着.NET AI生态从「追赶Python」转向「走自己的路」。Python有LLMLingua这样的专用库,.NET选择把能力做进基础设施层,让压缩成为任何RAG应用的默认选项。
更深一层,它反映了AI工程化的一个趋势:模型分层。不再是「一个大模型包打天下」,而是「小模型处理大量廉价任务,大模型专注高价值推理」。这个分层架构在成本敏感的企业场景里,会越来越成为标配。
对于正在用Semantic Kernel或Microsoft.Extensions.AI构建应用的团队,这个模式值得纳入技术债清单——不是紧急需求,但每延迟一个季度,就多付一个季度的冗余token费用。按Walter的估算,高频场景下这笔账很容易达到六位数。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.