2026年2月

在 GUI Agent 狂飙突进的今天,我们见过太多“大场面”:有人在朋友圈秀丝滑操作,也有人在后台默默修复被 AI 误删的根目录。
当 Agent 从“只会聊天”进化到“接管屏幕”,我们发现:比起更强的模型,大家更缺一个安全、稳定、玩不坏的“执行沙箱”。
今天,我们来干一件很朴素但很快乐的事:做一份超轻量小调研,收集大家对“GUI Agent”和“沙箱”相关的真实反馈。顺便,给大家发点春节宠粉福利。
放心,不是考试。题目不多,5 分钟内轻松搞定。
不论你是 Lybic 的深度用户,还是围观过豆包手机刷屏的极客开发者,我们都想听听你的声音:在探索 GUI Agent 的路上,你被哪些坑狠狠“教育”过?你最希望哪个能力先变靠谱?

行动指南

1)扫描海报上的二维码并完成问卷:获取 1 次抽奖机会,中奖率 100%
2)将本文分享至朋友圈,截图发给小助手:额外获取 1 次独立奖池的抽奖机会
每人最多 2 次机会,重复提交无效,望大家能够分享最真实的感受和见解。

奖品池

一等奖:小米 YU7 1:18 合金车模
二等奖:无线机械键盘 87 键 红轴
三等奖:三合一快充数据线四等奖:Lybic 周边+极客抽象贴纸
分享奖:小米 YU7 1:64 合金车模
调研截止日期为 2026年2月28日,所有奖品将在活动结束后统一寄出

我们会拿这些反馈做什么

我们拒绝“填完就沉”的调研,活动结束后,我们会把结果做成一张“调研简报”:
吐槽最狠的点 Top 3
最期待的能力 Top 3
... ...

让吐槽不白吐,让你的每一个痛点,都变成代码优化的起点。也希望能带给探索 GUI Agent 的同路人们更多的灵感和思考。
来吧,把你的真实体验交出来。

图片

本来买了游戏,解决配置问题、玩了一会,发现不喜欢,但已经 3 个小时了,觉得探索房间突然丧尸突脸,有点恐怖。
想退款,但不给我退款。
索性周末继续玩,风灵月影一开:无限耐久、无限子弹、大背包、丧尸雷达;

真香!

op 家 200m ,联通宽带。最近搞了 nas ,想提升网速,不知道怎么升级最划算。

目前下载 200,上传 50.

地区江苏,有大佬知道什么套餐么,目前是,原本套餐外加 20 块宽带。

你好,V 友。又过了一年了,不知道你是否完成了某个成就,不知道你是否完成了自己的目标。
无论过去这一年是快乐还是难过,是轻松还是疲惫,辛苦了,过年期间好好休整下,明年再出发吧。
不知道这个年,你有什么打算,是回家与爸妈吃一顿年夜饭,还是在异乡给自己放个假,还是来一场快乐的旅行。
亦或是好好的看个剧或者玩个一直想玩的游戏。
购物车里那躺了许久的东西,要不买来奖励自己。
我因为 https://www.v2ex.com/t/1187514 才意识到手里的键盘已经 10 年了。
于是我给自己换了新的键盘,准备今年回去见下几年没见的老人。

V 友你又有怎样的打算呢,无论如何记得给自己说一声辛苦了,新年快乐。

在代理IP的实际应用中,动态住宅IP与动态数据中心IP经常被放在一起做比较。两者都具备“可轮换”的特点,但来源、稳定性、匿名性以及适用场景却存在明显差异,接下来就跟着IPDEEP小编一起来看看吧!
动态住宅IP与动态数据中心IP有什么不同?

1.IP来源不同

动态住宅IP来自真实家庭网络运营商,也就是普通用户在家中上网所使用的IP地址。这类的IP在互联网上被识别为“自然流量”,与真实用户的行为环境更加接近。

动态数据中心是来自云服务器或机房,由IDC服务商统一分配和管理,它们并不绑定真实住户,因此在某些风控系统中更容易被识别为代理或自动化访问来源。

一句话概括:住宅IP更像“人”,机房IP更像“机器人”。

2.稳定性和可控性

动态数据中心IP在稳定性方面通常更好。机房网络环境标准化,延迟低、宽带充足,适合对速度和连续性要求高的任务,比如大规模数据抓取、接口请求等。

动态住宅IP的稳定性跟家庭网络有关。不同地区、不容运营商的质量差异会比较明显,偶尔会出现波动。但这类的“自然波动”更贴近真实用户。

3.价格差异

由于获取成本高、资源稀缺等,动态住宅IP的价格一般会高于动态数据中心IP。

如果只是普通访问需求,选择数据中心IP可以有效控制成本;但如果业务对IP“真实性”要求比较高,那么住宅IP往往更值得投入。

4.匿名性与信任度

在风控愈发严格的今天,网站往往会根据IP的信誉度来判断访问是否安全。

住宅IP因为与真实网络环境一致,通常拥有更高的信誉分,触发验证或限制的概率相对较低。数据中心IP虽然干净、速度快,但由于使用者多、集中度高,一旦某个网段被大量用户爬虫或批量操作,就可能整体被重点监控。

5.轮换方式

两者都支持IP更换,但逻辑不同。住宅IP的变更通常依赖运营商重新分配,可能按时间、会话或指定规则轮换;数据中心IP的切换则更加灵活,可以快速、大量地生成和替换。

6.该怎么选?

并不存在绝对更好的类型,关键在于你的目标。如果平台的审核比较严格,希望降低触发验证的概率,优先考虑住宅IP;如果追求速度、规模和成本效率,数据中心IP往往更具优势。

目前情况:全栈,base 北京,女,98 年,未婚未育
想 法:不想做技术了,对技术不感兴趣,想转行。个人不喜欢无理由加班,喜欢早九晚六。
方 向 1:考 公。实际:去年考过 2 次,想去天津,比较难
方 向 2:转产品。实际:看网上说产品比较吃学历,本人就一个普通二本,貌似不行
方 向 3:...
希望各位能给我点经验之谈,或者别的建议,谢谢🙏

有没有啥工具可以同步小米自带日历的内容的?

想自己玩玩做个工具。

  1. 通过手机的小爱同学记录待办事项
  2. 自己开发个程序 / 使用工具 把日历内容同步到自己的数据库
  3. 家里闲置屏幕,定时拉取待办,展示出来。

暂时还没找到可以拿到日历内容的工具。。。

作者:柳下

引言:安全沙箱与 Serverless 的技术交汇

随着大语言模型(LLM)从“对话框”走向“行动体(Agent)”,其能力边界正在迅速扩张。现代 AI Agent 不再是文字的搬运工,而是能够自主思考、调用工具、甚至编写并运行代码以解决复杂问题的智能助手。然而开发者始终面临一个根本性挑战:如何在保证执行效率的同时,实现资源强隔离与资源可控性?

阿里云函数计算 FC 为这一难题提供了全新的解题思路。其底层基于轻量级安全沙箱,天然具备进程级隔离、资源极致伸缩、按需付费等特性。这种架构与 Agent 对代码执行环境的需求高度契合,使得构建高密度、低成本、安全可靠的 Agent 运行时成为可能。

为什么需要 Agent 代码沙箱?

Agent 的核心价值在于其“自主执行”能力,而代码执行是实现这一能力的关键路径。在工具调用、动态数据分析、自动化任务处理等典型场景中,Agent 生成的代码往往来自不可信的推理过程,若缺乏有效的沙箱保护,开发者将面临多重风险,为此 AI 开发者对运行时有着如下多个核心诉求:

  • 安全与隔离特性:必须确保不同用户的 Agent 代码在文件系统、网络访问上完全隔离,严防恶意指令注入导致的越权操作。
  • 资源管理控制:代码缺陷或恶意行为可能导致 CPU/内存耗尽。系统需要能够对单个执行任务进行精细化的资源配额限制。
  • 生命周期管理:Agent 任务存在短时型突发、长周期会话等多种任务模型,需提供灵活生命周期管理能力。
  • 按资源消耗计费:若简单按实例运行时长计费,在长周期交互场景下,用户将为大量的“等待时间”支付不必要的费用。需在用户成本控制与平台资源利用率之间寻找平衡点。

由此可见,构建一个强隔离、可管控、即开即用且按需回收的代码执行环境——Agent 代码沙箱,已成为 AI 应用架构中的刚需。

为什么是Serverless?函数计算的核心优势

在众多技术路线中,Serverless 函数计算凭借其天然的“沙箱基因”,成为了构建 Agent 运行时的理想底座:

1. 底层安全隔离: 主流云厂商的函数计算服务普遍采用 MicroVM 或强化容器技术作为执行单元。每个函数实例运行在一个轻量级、启动迅速的 MicroVM 中,具备完整的内核隔离。这种架构从进程、内存、文件系统等多维度实现安全保障。

2. 极致的弹性伸缩: Agent 的请求模式具有高度不确定性。函数计算的毫秒级扩缩容能力,让开发者无需担心容量规划,轻松应对从零到万级并发的波动。

3. 按量付费的经济性: 传统常驻服务无论是否处理请求,均持续产生费用。而函数计算采用“用多少付多少”的计费模式,极大降低用户成本。(下文也将介绍 AI 场景下如何实现经济计费)

4. 简化的运维体验: 函数计算将基础设施管理完全托管给云平台,开发者只需关注代码逻辑,这种“代码即服务”的模式,极大加速了 AI 业务的迭代与上线周期。

5. 异构算力支持: 针对图像处理、音视频编解码等高性能场景,函数计算成熟的 GPU 实例支持,为 Agent 提供了更广阔的技能空间。

产品化实践:基于函数计算构建沙箱能力

为了将通用的函数计算转化为专业的 Agent 运行时,我们不仅需要底层的隔离,更需要在协议层、会话层和调度层进行深度重构。

1. 协议扩展:定义多元化业务的接入标准

Agent 的交互模式远比传统 Web 应用复杂。为了让 Agent 沙箱能够无缝嵌入现有的 AI 生态,我们针对不同场景实现了协议适配:

1. 针对工具生态:支持 MCP SSE 与 Streamable 协议

随着 Model Context Protocol (MCP) 成为 Agent 工具调用的事实标准,函数计算在网关层实现了兼容标准的 MCP 协议,这意味着可以在函数计算平台实现一键托管 MCP 服务。

2. 针对 Web/Browser Agent:支持标准 Cookie 协议

Browser Agent 需要模拟登录状态或维持持久化的 Web 会话。函数计算的接入层通过实现兼容标准 Cookie 协议,使得沙箱环境能够保持与目标网站的交互状态,支持复杂的自动化操作。在用户首请求时,服务端将生成全局唯一的 CookieID 并通过 Response 中的 Set-Cookie 字段返回,后续请求用户仅需携带相同 CookieID 便实现定向路由。

3. 针对灵活接入:定义统一 Header Field 协议

在基于 Header Field 的会话亲和机制中,仅需客户端通过在 HTTP Header 中注入特定的元数据。函数计算系统网关会解析请求头中的会话 ID,并将其作为路由键,确保携带相同会话 ID 的后续请求被精准路由到同一函数实例。这种方式不依赖客户端状态(如 Cookie),可以应用在任何客户端以 HTTP 协议交互的业务场景中。

image

2. 底座能力:构建有状态的会话管理

在解决了协议层“如何接入”后,接下来的挑战是如何在无状态的 FaaS 架构上,构建“有状态”的会话体验。

2.1 会话生命周期管理

Agent 的执行往往不是一次性的,而是多轮对话,为此需要赋予会话生命周期管理能力,如下图所示,系统提供用户主动、系统自动两种能力实现灵活、完整的管理机制:

1. 用户主动管理

a. 续期:面对 Agent 执行逻辑的不确定性,在生命周期配置上通常很难做到“一次性设对”。期间为延续状态的连续性,避免任务中断,可通过 Update API 实现对 Session TTL/IdleTimeout 的续期,主动延长沙箱寿命,续期后会话仍处于活跃状态且继续可用。

b. 销毁:显式通过 Delete API 删除会话,实现提前销毁释放资源。

2. 系统自动管理

a. Session TTL:会话达到 TTL(最大存活时长上限)后,无论是否仍在使用,平台都会自动回收资源。

b. Session IdleTimeout:会话在 IdleTimeout 规定时间内没有活动,平台判定为空闲并自动回收。

两类方式最终都会走到生命周期结束 → 会话销毁 → 关联资源释放。

image

2.2 会话亲和能力

这是将 FaaS 转化为“AI 运行时”的关键。通过会话亲和,我们保证了 Agent 上一轮生成的中间变量、本地文件在下一轮交互中依然可用。

image

整个流程分为用户首请求和非首请求,以 HeaderField 为例:

会话初始化流程(首请求)

  1. 发起请求:Client(客户端)向 Gateway(网关)发送请求,并在 Header 中携带特定的 x-fc-session-id,用于标识该请求属于哪个 Agent 会话。
  2. 生成内部 ID:Gateway 接收请求后,对 session_key 进行哈希处理,生成一个系统内部使用的 internal_session_id。
  3. 查询会话状态:Gateway 向 MetaDB(元数据库)发起查询,核实该 session_id 是否已经存在(即是否已经有对应的运行实例)。
  4. 未命中处理:MetaDB 未搜到到相关信息,表明这是一个新会话,或者之前的会话已失效,需要重新分配资源。
  5. 触发调度:由于是新会话,Gateway 随机选择一个 Scheduler(调度器)节点,请求为该会话分配计算资源。
  6. 分配实例:Scheduler 根据当前资源情况,从资源池中分配一个可用的 VM 实例(即沙箱环境)。
  7. 持久化映射关系:Scheduler 将 session_id 与分配到的 instance(实例)的对应关系写入 MetaDB。这样后续携带相同 ID 的请求就能实现“会话亲和性”,直接路由到该实例。
  8. 路由响应:Scheduler 将实例的路由信息返回给 Gateway。
  9. 返回首包:Gateway 完成链路建立,将处理后的首包数据返回给 Client。至此,该 Agent 会话正式建立,后续交互将直接复用此路径。

image

热请求数据流程

  1. 发起请求:Client(客户端)发起请求,并在 Header 中携带已有的 x-fc-session-id。
  2. 查询会话记录:Gateway(网关)接收请求后,前往 MetaDB(元数据库)查询该 Session ID 对应的记录。
  3. 返回映射信息:MetaDB 返回该会话之前绑定的 Instance(实例)信息以及负责管理该实例的 Target Scheduler(目标调度节点)。
  4. 直连调度节点:Gateway 根据返回的信息,直接联系对应的 Target Scheduler。
  5. 确认路由实例:Target Scheduler 告知 Gateway 该实例有效,可以进行数据转发。
  6. 转发请求:Gateway 将客户端的业务请求转发给对应的 Instance。
  7. 处理并响应:Instance(Agent 沙箱)执行代码逻辑处理请求,并将结果返回给 Gateway。
  8. 返回业务数据:Gateway 将最终的执行结果回传给 Client,完成一次有状态的会话交互。

image

2.3 会话隔离能力

为了极致的安全,我们引入了“一会话一实例”的隔离模型。每个 Agent Session 独占一个底层的运行实例。一旦会话结束,实例立即销毁并擦除数据。通过会话配额控制,可以有效防止单个用户创建过多沙箱导致资源过载。

image

3. 扩展配套能力,强化 Agent 底座

除了核心的调度与协议,针对生产环境中的性能与成本挑战,我们进一步扩展了配套能力:

1. 预热能力

冷启动是 Serverless 的天敌。针对 Agent 实时交互的要求,我们支持 CreateSession 主动预热。在用户刚进入对话页面时,系统提前准备好预留实例。将沙箱的就绪时间压缩至极低延时。

2. 会话级存储隔离

Agent 经常需要读写文件。我们实现了会话维度的动态存储挂载。每个沙箱可以根据 Session ID 动态挂载独立的 NAS 或 OSS 路径。这样既保证了数据在会话内的持久化,又确保了不同会话间的文件系统是物理隔离的。同时满足沙箱异常 Crash 后数据的可恢复。

3. 计费升级模型进化:从 FaaS 的“按请求”到“按资源消耗”

FaaS 按请求计费模式,在 AI 场景下会产生巨大的“保活成本”。会话计费模型必须与资源的实际使用强挂钩,因此系统针对会话函数的计费模式升级到 Serverless AI 计费模式。

  • 活跃期:当会话实例正在处理用户请求时,按照活跃单价计费。
  • 空闲期:当会话处于空闲、仅维持连接和上下文状态时,系统切换到一个极低的“保活”费率。仅收取内存、磁盘的费用,不再收取相对较高的 CPU 费用。

这个模式对客户而言,相对传统常驻实例完整生命周期计费模式成本大幅降低。

总结与展望

Serverless 函数计算凭借其安全隔离、弹性伸缩、按需付费等基因,正成为构建 Agent 运行时的理想选择。通过协议生态扩展、会话管理能力增强、配套能力完善,我们已实现从“单一函数执行”到“复杂 Agent 托管平台”的跨越。未来,我们也将持续聚焦启动优化、更长会话支持等等核心能力,做好 AI 原生时代坚实的护航者。

相关链接:

[1] 查看更多产品详情

https://www.aliyun.com/product/fc

[2] 相关文档链接

https://help.aliyun.com/zh/functioncompute/fc/user-guide/sess...

全文链接:https://tecdat.cn/?p=44952
原文出处:拓端数据部落公众号

封面

专题:LLM上下文工程实践:轻量化记忆层构建与落地

引言

在大语言模型(LLM)的实际应用过程中,对话类场景是落地频率最高的方向之一,而这类场景的核心痛点在于LLM的无状态特性——每次模型调用都是独立的过程,若未主动传入历史会话信息,模型无法感知用户的过往交互内容。这一特性虽然保障了模型并行处理的效率和安全性,却成为个性化对话应用落地的最大阻碍:如果智能客服每次都将用户视为新访客,又如何提供贴合用户需求的个性化响应?
从技术演进的角度来看,早期开发者尝试通过延长上下文窗口的方式解决记忆问题,但这种方式不仅受限于模型的上下文长度,还会显著增加调用成本;而随着向量数据库和智能体技术的成熟,为LLM构建独立的记忆层成为更优解。本文基于Mem0架构的核心思想,从零拆解并实现一套轻量化的LLM记忆层,该方案已在金融智能客服、电商个性化助手等实际业务场景中得到验证。
本文内容改编自过往客户咨询项目的技术沉淀并且已通过实际业务校验,该项目完整代码与数据已分享至交流社群。阅读原文进群,可与800+行业人士交流成长;还提供人工答疑,拆解核心原理、代码逻辑与业务适配思路,帮大家既懂 怎么做,也懂 为什么这么做;遇代码运行问题,更能享24小时调试支持。

LLM记忆层:从上下文工程视角的核心拆解

上下文工程是指为LLM补充完成任务所需的全部相关信息的技术体系,而记忆层构建是上下文工程中难度最高、应用价值最大的方向之一。

LLM本身并不具备记忆能力,要实现会话记忆,开发者需要掌握上下文工程的核心技术栈:从原始文本流中提取结构化信息、文本摘要生成、向量数据库应用、查询生成与相似性检索、查询后处理与重排序、智能体工具调用等。而构建自定义记忆层的过程,正是这些技术的综合落地过程。

记忆层的整体架构设计

一套可落地的LLM记忆层需具备四大核心能力:提取、嵌入、检索与维护。在开始代码实现前,先梳理各模块的核心职责与交互逻辑。

核心模块拆解
  • 记忆提取:从用户与助手的对话文本中提取具备原子性的候选记忆信息;
  • 向量存储:将提取的原子化记忆转换为向量形式,并存储到向量数据库中;
  • 记忆检索:当用户发起查询时,生成检索语句并从向量库中匹配相关记忆;
  • 记忆维护:基于ReAct(推理与执行)循环,智能判断对现有记忆的增、删、改或无操作,解决记忆冲突与过时问题。

    需要特别说明的是,上述所有步骤都应设计为可选流程:若LLM无需调用历史记忆即可回答用户问题,则无需触发向量库检索,以此降低系统开销。核心策略是为LLM提供完成任务所需的全部工具,并清晰定义工具功能,依托LLM自身的智能自主决策工具的使用时机。

基于DSPy的记忆提取:从对话文本到原子化记忆

记忆提取是记忆层构建的第一步,核心目标是将非结构化的对话文本转换为结构化、原子化的记忆单元,以便后续的嵌入与检索。

原子化记忆的定义与提取目标

优质的记忆单元应具备“短、自包含、原子化”的特征——即单个记忆仅描述一个独立事实,且能被精准嵌入和检索。我们的目标是构建一个面向单用户、持久化的向量数据库记忆库,而DSPy框架能高效实现从对话文本到原子化记忆的提取(DSPy为Python开源库,国内可正常安装使用,无访问限制)。
DSPy通过“Signature(签名)”定义输入输出结构,其注释会作为系统提示词引导LLM完成结构化信息提取。以下是核心实现代码(已调整变量名与语法,省略部分基础导入代码):

# 省略json、asyncio等基础导入代码import dspyfrom pydantic import BaseModel# 定义记忆提取的签名结构class UserMemoryExtract(dspy.Signature): """从对话文本中提取有价值的用户记忆信息。记忆需为独立的原子化事实,若文本无提取价值则返回空列表。""" dialog_text: str = dspy.InputField() # 输入:对话文本 user_memories: list[str] = dspy.OutputField() # 输出:提取的记忆列表# 初始化记忆提取器memory_extract_tool = dspy.Predict(UserMemoryExtract)# 异步提取记忆的核心函数async def get_user_memories(dialog_messages): # 将对话消息转换为JSON字符串作为输入 dialog_json = json.dumps(dialog_messages) # 指定调用的模型并执行提取(省略模型配置相关代码) with dspy.context(lm=dspy.LM(model=MODEL_TYPE)): extract_result = await memory_extract_tool.acall(dialog_text=dialog_json) # 返回提取的记忆列表 return extract_result.user_memories

为验证提取效果,我们基于模拟对话文本测试(已调整变量名与示例内容):

if __name__ == "__main__": # 模拟用户与助手的对话记录 test_dialog = [ { "role": "user", "content": "我喜欢喝咖啡" }, { "role": "assistant", "content": "好的,我记下了!" }, { "role": "user", "content": "其实我更喜欢喝茶,另外我也喜欢踢足球" } ] # 执行记忆提取 extracted_mem = asyncio.run(get_user_memories(test_dialog)) print(extracted_mem)'''输出结果示例:[ "用户原本喜欢咖啡,后表示更喜欢茶", "用户有喝茶的偏好", "用户喜欢踢足球"]'''

从测试结果可见,该方案能有效从对话中提取原子化记忆,这些记忆可脱离会话窗口存储到独立数据库中,为跨会话记忆提供基础。


相关文章

Python用langchain、OpenAI大语言模型LLM情感分析AAPL股票新闻数据及提示工程优化应用

原文链接:https://tecdat.cn/?p=39614


记忆的向量嵌入与存储:基于QDrant的实现

提取原子化记忆后,需将其转换为向量形式存储,本文选用QDrant作为向量数据库(QDrant为开源向量数据库,国内可正常部署使用,无访问限制;国产替代方案可选用Milvus、Zilliz等)。

嵌入模型选择与向量维度优化

考虑到成本、速度与短文本嵌入效果,本文选用OpenAI的text-embedding-3-small模型(国内无法直接访问OpenAI官网,但可通过合规第三方API服务商调用;国产替代方案可选百度文心一言嵌入、阿里通义千问嵌入、智谱AI嵌入等),并将向量维度固定为64,在保证表达能力的同时降低存储成本与检索耗时。
核心实现代码(调整变量名与语法,省略部分导入代码):

# 省略uuid、datetime等基础导入代码from openai import AsyncClientfrom qdrant_client import AsyncQdrantClientfrom qdrant_client.models import Distance, Filter, models# 初始化OpenAI异步客户端emb_client = AsyncClient()# 异步生成文本向量async def create_text_embeddings(text_list: list[str]): # 调用嵌入模型生成向量,指定维度为64 emb_result = await emb_client.embeddings.create( input=text_list, model="text-embedding-3-small", dimensions=64 ) # 提取向量结果 embeddings = [item.embedding for item in emb_result.data] return embeddings# 定义向量存储的数据结构class StoredMemory(BaseModel): user_identity: int # 用户ID memory_content: str # 记忆文本 create_time: str # 创建时间 vector_data: list[float] # 向量数据# 初始化QDrant异步客户端(省略客户端连接配置代码)qdrant_async_client = AsyncQdrantClient(...)MEMORY_COLLECTION = "user_memories"# 创建向量库集合与索引async def init_memory_collection(): # 检查集合是否存在,不存在则创建 if not (await qdrant_async_client.collection_exists(MEMORY_COLLECTION)): await qdrant_async_client.create_collection( collection_name=MEMORY_COLLECTION, vectors_config=models.VectorParams(size=64, distance=Distance.DOT), ) # 为用户ID创建索引,提升检索效率 await qdrant_async_client.create_payload_index( collection_name=MEMORY_COLLECTION, field_name="user_identity", field_schema=models.PayloadSchemaType.INTEGER )# 插入记忆到向量库(省略参数校验代码)async def add_memories_to_db(memory_list: list[StoredMemory]): """将记忆列表插入向量数据库""" # 构造插入的点数据 point_list = [ models.PointStruct( id=uuid4().hex, # 生成唯一ID payload={ "user_identity": mem.user_identity, "memory_content": mem.memory_content, "create_time": mem.create_time }, vector=mem.vector_data ) for mem in memory_list ] # 执行插入 await qdrant_async_client.upsert( collection_name=MEMORY_COLLECTION, points=point_list )# 检索相似记忆(省略结果转换函数代码)async def find_similar_memories( search_vector: list[float], user_id: int, top_k: int = 5): """根据向量检索用户的相似记忆""" # 构造用户ID过滤条件 filter_conditions = [ models.FieldCondition( key="user_identity", match=models.MatchValue(value=user_id) ) ] # 执行检索 search_result = await qdrant_async_client.query_points( collection_name=MEMORY_COLLECTION, query=search_vector, with_payload=True, query_filter=Filter(must=filter_conditions), score_threshold=0.1, # 相似度阈值 limit=top_k ) # 转换检索结果(省略convert_search_result函数实现) return [convert_search_result(point) for point in search_result.points if point is not None]

为提升检索效率,我们为用户ID字段创建了索引,该思路可扩展到记忆分类标签、时间范围等元数据维度——只需为对应字段创建索引即可,这在电商个性化推荐、金融客户画像等实际场景中能显著提升检索精准度。

基于ReAct框架的记忆检索与响应生成

记忆检索的核心是让智能体自主判断是否需要调用记忆,并检索相关内容辅助响应生成。本文基于DSPy构建ReAct智能体,实现检索逻辑的自主决策。

响应生成的核心实现

首先定义响应生成的输入输出结构,引导LLM判断是否需要保存新记忆(调整变量名与语法):

class DialogResponseGenerator(dspy.Signature): """你将收到用户与AI助手的历史对话文本及用户最新问题。 若无法从历史对话或自身知识库中回答问题,可调用向量库检索工具获取相关记忆。 需输出最终响应,并判断是否需要将最新交互内容存入记忆库(仅当用户提供新信息时保存,不保存AI相关内容)。 """ dialog_history: list[dict] = dspy.InputField() # 历史对话 user_question: str = dspy.InputField() # 用户最新问题 final_response: str = dspy.OutputField() # 最终响应 need_save_memory: bool = dspy.OutputField( description="若最新交互需生成新记忆则为True,否则为False" )# 封装检索工具(省略权限校验代码)async def search_user_memories(search_content: str): """当对话需要补充上下文时,从向量库检索相关记忆 参数: search_content: 用于嵌入并执行相似性检索的文本 """ # 生成检索文本的向量 search_vec = (await create_text_embeddings([search_content]))[0] # 检索相似记忆(current_user_id为外部维护的当前用户ID) related_memories = await find_similar_memories( search_vector=search_vec, user_id=current_user_id ) # 格式化记忆结果 memory_str_list = [ f"记忆ID={m.point_id}\n内容={m.memory_content}\n创建时间={m.create_time}" for m in related_memories ] return {"related_memories": memory_str_list}# 初始化ReAct响应生成智能体response_agent = dspy.ReAct( DialogResponseGenerator, tools=[search_user_memories], # 绑定检索工具 max_iters=4 # 最大迭代次数)

除了向量相似性检索,实际应用中还可扩展其他检索策略:如基于BM-25/TF-IDF的关键词检索(适用于短文本精准匹配)、基于分类标签的精准过滤(适用于垂直领域对话)、基于时间范围的记忆筛选(适用于时效性强的场景)等,具体可根据业务场景选择。

记忆的全生命周期维护:自适应增删改查

记忆并非静态存储,需根据用户最新交互动态调整——例如用户修改偏好时,需更新对应记忆而非新增重复条目。本文基于ReAct框架构建记忆维护智能体,实现记忆的增、删、改、无操作(NOOP)决策。

记忆维护的核心实现

首先定义记忆维护的输入输出结构,明确智能体的决策目标(调整变量名与语法):

class MemoryWithID(BaseModel): mem_index: int # 记忆索引 mem_content: str # 记忆内容class MemoryUpdateSignature(dspy.Signature): """基于用户最新对话与已有相似记忆,决策记忆库的更新方式: - 新增:将新记忆作为独立条目插入库中(插入前需去重); - 更新:用新信息替换已有记忆; - 删除:移除矛盾或过时的记忆; - 无操作:无需调整记忆库。 需输出简短的操作总结(少于10字)。 """ dialog_messages: list[dict] = dspy.InputField() # 最新对话 existing_memories: list[MemoryWithID] = dspy.InputField() # 已有相似记忆 operation_summary: str = dspy.OutputField(description="操作总结,简短")# 记忆维护智能体核心逻辑(省略部分工具函数参数校验代码)async def memory_maintain_agent( user_id: int, dialog_msgs: list[dict], existing_mems: list[StoredMemory]): # 根据记忆索引获取点ID def get_point_id(mem_index): return existing_mems[mem_index].point_id# 新增记忆工具 async def add_new_memory(mem_text: str) -> str: """将新记忆插入向量数据库""" mem_emb = await create_text_embeddings([mem_text]) new_mem = StoredMemory( user_identity=user_id, memory_content=mem_text, create_time=datetime.now().strftime("%Y-%m-%d %H:%M"), vector_data=mem_emb[0] ) await add_memories_to_db([new_mem]) return f"新增记忆:{mem_text}"# 初始化记忆维护ReAct智能体 maintain_agent = dspy.ReAct( MemoryUpdateSignature, tools=[add_new_memory, update_existing_memory, delete_selected_memory, no_operation], max_iters=3 )# 执行维护决策 maintain_result = await maintain_agent.acall( dialog_messages=dialog_msgs, existing_memories=existing_mems ) return maintain_result.operation_summary

在实际业务场景中,该维护逻辑已验证可有效解决记忆冲突问题——例如用户从“喜欢咖啡”改为“喜欢茶”时,智能体会删除旧记忆并新增新记忆,而非保留两条矛盾条目,保障记忆库的准确性。

落地扩展与工程化优化建议

本文实现的记忆层为轻量化版本,在实际落地中可从以下方向扩展,进一步提升适配性:

  1. 图结构记忆系统:将向量数据库替换为图数据库,通过提取“主体-关系-客体”三元组替代扁平文本记忆,更贴合人类记忆的关联特性,适用于金融客户关系分析、电商用户行为溯源等场景;
  2. 多维度元数据标签:为记忆增加分类标签(如“饮食偏好”“消费习惯”)、时间戳等元数据,智能体可基于标签精准检索,降低无效检索开销;
  3. 用户专属提示词优化:将记忆库中的核心信息注入LLM的系统提示词,替代每次检索,提升响应速度,适用于高频次、短会话的智能客服场景;
  4. 文件化存储方案:用文件系统(如Markdown文件)替代向量数据库,通过正则、全文检索实现记忆管理,降低部署成本,适用于小型应用场景。

记忆层核心流程(竖版)

总结

  1. 本文基于上下文工程理念,拆解并实现了一套轻量化LLM记忆层,核心模块包含记忆提取、向量存储、检索与自适应维护,已在实际业务场景验证有效;
  2. 技术选型上适配国内环境,QDrant可开源部署,OpenAI嵌入模型可通过第三方服务商调用,也可替换为国产嵌入模型;
  3. 基于ReAct框架的双智能体设计,实现了记忆检索与维护的自主决策,解决了LLM无状态导致的个性化缺失问题,且提供24小时应急修复服务保障落地效率。

封面

马年春节的脚步越来越近,大大小小的红灯笼挂满街头,屏幕里的集福活动再次点燃,家乡的腊味香气仿佛隔着千里也能闻到。无论是准备马年元素的春联窗花,还是添置一套杯盘碗碟新年新气象,又或是精心挑选一份产地直送的特色年礼,我们总愿用一些美好的物件,承载祝愿,点亮日常。今年,我们邀请了 9 位作者,分享他们为这个春节准备的「年货好物」。🙋 也欢迎大家在评论区,晒出你的春节心选!

本文不含任何推广性内容,请放心阅读,提前祝大家新春快乐!

好吃的

江中猴菇无糖酥性饼干 & 青稞米稀

@程天冲:每年到了春节回家,给家里人伴手礼都是一个不大不小的问题。我需要送礼的主要人群有两类:家里的老人,以及相熟的兄弟姐妹。显然,这两类人的收礼需求是完全不一样的,老人怕花钱又讲究实惠,兄弟姐妹们最好是能送出一点新意。所以看来看去,每年我都决定给大家送吃的,毕竟满足口欲对每个群体来说肯定都没错嘛。

与往年不同的是,我家老人们在今年因为一些疾病需要在较长一段时间内连续服用一些药物,并且日常服用的降压药和抗凝类药物也不能间断,又另外被医生要求日常控糖。我咨询了一下医生朋友发现,连续服用多种药物除了对有损肝脏以外,还会对胃有慢性潜在伤害,而这一点很容易被我们所忽视。所以在他的建议下,我决定今年给家里的老人送点好吃、养胃又健康的食品,江中自然就成为了我的首选。

春节都要吃零食,因此我选了这款猴菇无糖酥性饼干。首先从口感上,酥质的口感很容易被牙口不好的老人接受和喜爱,吃起来对牙齿完全没有负担;其次从控糖的角度,这款饼干直接的糖分物质添加为木糖醇,属于 0 蔗糖添加,并且还有三分甜版、不甜版两种供你选择,考虑到一块饼干本身的分量就很小,作为一个春节期间偶尔休闲的低 GI 零嘴来说很合适(当然了,配料表中依然包括小麦粉和全脂奶粉,如果有严格的碳水和脂肪控制需求可能需要注意);最后,作为养胃成分的猴头菇(添加量 >=6%)和山药的添加量也还不错,我认为完全可以达到养胃零食的需求。所以综合来看,作为送给老人的春节零食十分合适。

零食适合春节送礼,日常养胃才是关键。老人们都很认真吃早餐,包子油条挂面之类的精致碳水很容易摆上桌,所以我决定给他们换成青稞米稀。青稞作为一种非常优秀的低速升糖的粗粮,GI 值仅为 25 左右,甚至比燕麦的 55 还低不少 ,虽然作为粉状不经咀嚼会提高真实的升糖指数,但和常规米稀相比减少了炼乳,作为早餐控糖来说已经可以接受。

并且,这款米稀中还添加了 14% 的抗性糊精和 9% 的大豆分离蛋白粉,充分照顾到了膳食纤维和蛋白质的补充,对于早上需要日常服药的老人来说是一份合格的养胃控糖早餐。家里有和我情况类似的老人,可以考虑入手 30 装当个春季伴手礼试试看。

柠檬共和国柠檬芭乐电汽柠汽水

@程天冲:我家兄弟姐妹基本上已经全员进入三四时代,日常喝饮料的次数变低,而且也都更偏爱无糖茶类,家里东方树叶的常备数量已经堪比矿泉水。鉴于这种情况,送礼再送茶类就有点不礼貌了。过年不管怎么样都不可避免会吃得油腻一些,送些清新爽口的气泡饮料作为解腻饮料挺合适的。

这几年流行芭乐,大家夏天也都喜欢喝喜茶的芭乐茶,因此我就选了这款柠檬芭乐电汽柠汽水。这款饮料整体的添加物以原液果汁为主(不是无糖饮料,所以依然添加了白砂糖),包括番石榴(芭乐)、柠檬、苹果、茉莉花原汁及浓缩液,加上二氧化碳以后变成了非常清新爽口的气泡水。稍加冷藏之后,很适合作为春季餐桌的配饮,清新爽口且甜度不算很高,比单纯气泡水好喝,比单纯果汁口感更清透,春节送给自己的同辈或是好友都是挺好的选择。

澳门最香饼家粒粒杏仁饼

@许万里Alva:我第一次买它,是因为去年在拜访香港朋友时,她点名了这个牌子,说吃了几十年都觉得好吃。那次我顺手买了 10 盒回家分给亲戚和朋友,反馈都还挺好的:家里长辈喜欢它的炭香,觉得「配茶挺好」。朋友则更喜欢它的「粒粒口感」,觉得不是那种入口就散成粉的甜饼(虽然我觉得那种也好吃),吃起来更「实」。于是今年春节回家准备伴手礼时,我首先想到的还是最香饼家的手信。

它在澳门只有一家门店,位于本岛的夜呣街,从旅游观光地「议事亭前地广场」步行过去约 10 分钟。如果是节假日排队会很夸张,队伍甚至可以排到转角,店内也贴着「一人限取一票,一票限买一盒」。之前在官方介绍里看到它们旺季的日产量大概是 5000 块左右,人流多的话后面来的客人会买不到,所以才出了限购的策略。不过人不多的时候购买不会有数量限制,像我当时是工作日下午去买的,一次性买了 10 盒杏仁饼也是可以的。

这家店之所以有名,是因为它主打「古法炭烧手工制作」。官方介绍写得很详细:原料包括杏仁、绿豆粉、糖、植物油、花生酱等,先手工压模定型,再进炉烤到金黄。以前会更完全地用炭火慢慢烤,现在因为澳门法规限制,做法调整成「先烤半熟、再放上炭炉烤制」,仍然保留了独特的炭烤香气,很适合搭配热茶食用。

店里除了「粒粒杏仁饼」,还有肉心杏仁饼、蛋黄肉心杏仁饼(更偏咸香、油脂感更明显)等。此外他们也有做其他澳门手信,例如紫菜肉松凤凰卷、紫色卷、凤梨酥、榴莲饼、陈皮饼、鸡仔饼等等,都是比较有特色的港澳美食。如果是想送礼的话,可以搭配购买~

我常买的是 10 件装

元祖海盐太妃糖、桂花奶酥 & 大吃兄锅巴大王

@Voyager_1:不知道为什么突然赵一鸣、好想来等零食聚合的店铺突然火起来了,平时去超市买零食的习惯,被「去离家更近的零食店随便称点散装的」所取代。不过,这类零食还是以日常的零嘴为主,想吃老家也能随时买到,过年回家还是想着带些老少咸宜和平时不太会买的礼盒装带着,来亲戚朋友分食时既有新鲜感又觉得好吃。下面这几款就是这一年吃过的还不错的选项。

锅巴大王我买了两种口味,一种是甜辣另一种是蟹香。甜辣的就是日常能吃到的口味,更推荐下单蟹香口味,这款我妈这个不怎么吃零食的人吃了都说再来一个,锅巴上蟹粉裹得很够,吃完都得嗦下手指。这款独立包装,一袋一片非常适合过年等饭期间解馋。

过年怎么能不吃糖呢,小时家里茶几都会放一罐子糖,小朋友来家后习惯性就是抓糖吃,我决定把这个记忆延续下去。元祖的这款海盐太妃糖的甜度中和得很棒,比我随便在网上买的吃起来更加适口。(我不爱吃太甜的)嚼着吃、含化了吃,都能尝到果仁香,说明用料还不错。过年晒太阳的时候,泡杯咖啡配两颗糖,绝对惬意拉满。

过年想给奶奶买点桃酥来着,但是想着老人家都吃了一辈子桃酥了,该来点没吃过的试试。这款桂花奶酥应该适合她的口味,老人家不喜欢过冲的奶味/桂花味,这个我实际吃下来能吃到淡淡桂花香和馅儿料香,没有过冲的感觉,也没有咬合的压力。总体来说,元祖的出品还是让人放心的,希望奶奶会喜欢。对了,其实这种福饼也是可以切开分着吃的,长辈总是不爱一次吃一整个怕吃不惯浪费,分着吃就好了。

盒马年菜之金字刀板香咸肉

@文猫:前一阵在盒马上买了快手菜——笋尖咸肉煨豆腐,作为山西人没吃过这么好吃的咸肉汤,于是在很短时间内多次下单,成为在盒马最爱买的一款快手菜,但这款有点过于火爆了经常断货,于是在这种时候我只能买另一款——腌笃鲜。腌笃鲜比咸肉豆腐汤这款更方便,因为是铝盒包装,拿到手可以直接上煤气灶加热,连锅都不用洗了。

在我给老公激情推荐了咸肉豆腐汤但断货之后,他说那你为什么不买一下咸肉回来自己煮呢?于是我在盒马查了一下,有一款可以快递配送的咸肉,于是一下买了两袋。这个咸肉有塑封包装,一袋里面两条肉,开封后放冰箱冷藏就行,放两个月不成问题。盒马的老豆腐也不错,但不如咸肉豆腐汤(快手菜版)里面的柴火豆腐香,我在市集买的柴火豆腐也差点意思。

有了咸肉之后就非常简单了,我跟老公两个人的话一顿饭 用 1/3 条的咸肉量,切成片,厚度可以看自己喜好,更薄的话就会把咸肉的盐味更多煮到汤里,厚一点的话肉本身能留一些咸味。把切好的咸肉和切好块的豆腐放入锅中,大火滚几分钟可以让豆腐煮得烂一点汤更白一点,然后小火炖几分钟就可以。基础版只放咸肉和豆腐就很好吃了,有肉香和豆腐的豆香,我一个人话就会在汤里煮一份龙口粉丝,太好吃了!

如果想要口感更丰富可以加泡发的木耳和笋尖,能给汤增加一些鲜甜。出锅前撒上青蒜是跟盒马的快手菜学到的,但自己切的更香,因为更新鲜。

除了这道汤,盒马还出了很多与一饭封神合作的年菜,上次买了一个烧椒鲈鱼还是很不错的。但这些都是冷冻的,需要先解冻再蒸一下或微波炉加热,比较麻烦。

好看的

马年春联窗花静电贴

@Irisleilei:每年过年的仪式感已经固定为贴窗花了,可爱的窗花贴在室内赏心悦目,小玩意大作用,过节氛围感满满。相比贴在门外的对联的优势是在家里可以时刻感受春节的气氛,好看的东西就应该由自己和家人欣赏。

给自家安排的窗花贴

才把去年的蛇年窗花撕下来,静电窗花贴在朝南阳台经过近乎一年太阳的炙烤也几乎没有变色,也没有因此留胶,亲测完全无痕,轻轻一撕就下来了。由此,静音窗花贴已经成为每年固定仪式感。

今年没有固定在一家店买,挑了不同的店铺组合成好看的窗花,同时还有 DIY 的乐趣。(有些店铺原创的「马」不太像马哈哈,个人喜好还是选了有马的特征的)上下联和横批保持风格一致,中间的图案选了另一家店,福气满满和 ALL PASS 的寓意也算是符合自己今年的心境,希望自己少些对未来的焦虑,专注做事,幸运常在。

今年贴得更上手了,静音窗花贴的好处还有一个是,无限次重复贴,一个人贴也很方便。我通常会轻轻粘一个角固定位置,再在站远看看贴是否对称、水平,确认了再固定贴好,方便又快捷。

还给爸妈家也准备了一份,新的一年家里都要有新气象嘛。妈妈选了全是捧着金元宝和被金币簇拥的小马造型,全是对今年股市账户美好的祝愿(哈哈)。

马年创意春联

@Irisleilei:现在创意春联越来越多了,内容也越来越符合年轻人的口味,接地气儿又可爱。今年就早早地挑好了可爱的春联,谐音梗加分,希望 horse(好事)窍敲门!同时,除了入户门可以贴春联以外,也可以作为冰箱贴作为装饰。

我还是秉持着好看的东西要留在家里给自己欣赏,好看的春联忍不住多买几张,既可以作为冰箱贴吸在冰箱上也可以用无痕贴安置在房间门上,节日气氛爆棚。

奶油小狗春联

@Lotta:今年又刷到可爱的春联了!比起去年买的 Pingu 春联可爱程度更上了一个台阶,但价格也加了一倍。相比 50 多元 19 张的 Pingu 礼盒,这套春联 7 张定价就要 49 元。不过这套春联采用的是毛毡材质,似乎耐久度更高一些,作为独立小店的原创设计,价格也没多难接受(毕竟太可爱了)。

商家产品图

这套春联的主题是奶油小狗,深灰色的高脚托盘上是一摞红彤彤的草莓和一个可露丽,顶端各站着一只可爱的奶油小狗,写着「喵喵旺旺伴左右/日子甜蜜似奶油」的字样。虽然设计在春联这个品类有够特别,但缺点也很明显:作为对联来说既不对仗、也谈不上平仄相合,对此有要求的朋友慎选。

春联的包装很简单,一套七张被卷在一起装进透明袋子里,附赠了无痕贴和 3M 胶磁贴。春联印刷质量也很不错,几乎没有色差。虽然店家表明机器裁切可能会有白边,但不仔细看的话基本不会发现瑕疵。

这么可爱实在不舍得贴在大门外,于是我把它们贴在了室内的房间门上。虽然商家的示意图是七张都贴在了一起,但分组 DIY 也完全没问题,比如我觉得都贴在一扇门上有点拥挤,就把它们分成两组贴在了两扇门上,雨露均沾(bushi

我一开始也担心过草莓奶油的元素和春节的气氛并不匹配,虽然和马年无关,但贴上后却发现亮眼的红色确实也有喜庆的感觉,房间一下就活泼起来了!

新年仪式感冰箱贴

@Kasper:年关将至,极简北欧风的家也得疯狂注入红色元素,来点年味。但毕竟是节日限定,还得考虑到未来的拆卸,所以各类粘贴的东西都达咩,哪怕说的再天花乱坠如何不留痕,也不能给自己增加一丝麻烦。说起方便「穿脱」,最合适的就是磁吸材质了。家里的冰箱、咖啡机、垃圾桶、珐琅板……只要你想,哪里都是舞台!

马年真是一个各种谐音梗泛滥的年份,所以各种可可爱爱的马年整活小玩意真是让人买到手软。贴在大门上的对联当然还是要严肃认真,那就让磁吸对联来补足俏皮吧!我们家的冰箱贴一向是贴在冰箱侧面,主要是为了展示,以及避免开关门误触使其掉落,但既然是节日限定,那这个对联冰箱贴真是很适合独占一整面「大白墙」了。

不过,冰箱上的这个马年对联喜庆有余,谐音尚欠火候,于是我又购入了一个中英双谐音版冰箱贴,贴在客厅饮料冰箱和咖啡机侧面(horse 花生、马尼 go my home;超级马力、马足干劲;神马都顺、神马都好、马力十足)。

美中不足的是,这个系列的对联忽略了中国人春联的传统规则,加入了其他颜色,在一些地方习俗里可能不太吉利,所以只能挑选一些纯红色版本组合啦。

除了谐音梗,我还买了一个马年旋转冰箱贴系列,取「马上」之意,马背上驮着金元宝或福袋,意为「马上有钱」或「马上有福」,吉祥不失可爱。这个带点小机关的冰箱贴我贴在了铁皮置物柜和垃圾桶上,时时可以旋转一下。

以上冰箱贴都购于 pdd,价格较低廉,质量很难称得上完美,但很适合「沾点儿喜气」,用后即扔。你还真别说,平日里素色的黑白灰看惯了,点缀点色彩还真别有一番风味,已经开始期待过年了。

马踏繁花走马观烛台

@许万里Alva:今年因为我姐的推荐而开始对「香薰蜡烛」感兴趣,陆续买了两三个香薰蜡烛 & 烛台,最满意的还是和马年相关的这款 iasonas 的「马踏繁花走马观」,组装完成点燃蜡烛后的效果是令我感到惊艳的程度。它本质上就是中国传统的「走马灯」——利用热对流原理推动轮轴旋转,营造出马奔跑的动态画面。

因为走马灯转动如飞,在古代也有「转运」「走马上任」的美好寓意,通常伴有祈福的寓意,既适合用来送礼,也适合和我一样自购放在家里作为春节氛围感装置。它有两种观看方式,一种是直接观看;另一种是放入半透明透光片,让旋转的影子投在透光片上。我更喜欢第二种方式,在夜晚关闭家里的所有灯光,看着马的影子被拉长、变形,像小型皮影戏一样,很适合在夜晚小酌的时候观赏。

点燃走马观的效果

我是于淘宝购入这套走马灯礼盒,价格是 266 元,包含 8 枚香薰小茶蜡和 5 个透光片(虽然有 6 个方向,但官方建议是只放 3 片利于通风),到手后需要自己组装成品(不算复杂,我用了约 25 分钟完成)。它的香薰茶蜡有四种香型:木质调、西普调、柑橘调和草本木质调,在商品介绍可以看到每种香型的具体成分,每一枚蜡烛燃烧时可散发香味的时长大概为 4 小时。

商品礼盒包装

整体来说,这套香薰蜡烛 & 烛台我还是非常满意的,它不止香,而且转动的装置设计也让夜晚的家里更有氛围感,很适合过年放在家里添加一些趣味,也很适合作为礼物送人(今晚我姐看到的时候就马上找我拿了链接)~

生肖马克杯 & 袜子套装

@潘誉晗:母亲属马,公历的生日刚好在月底。因而今年购买年货的时候,与其说是为了祝福新年快乐,倒不如说是为母亲准备一份新年的生日礼物。

我们这代人的长辈,大多数的童年经历都是没那么富裕的,加上母亲又是从小地方考上大学的,所以性子比较务实,因而给她购买礼物,「实用性」必然是最佳的考量。前段时间发现母亲拿着并不是她常用的杯子喝水,我开玩笑说每天换着新杯子喝水是不是也很棒,结果母亲说,用另外的杯子只是为了方便吃药而已。想起吃药终究不是好心情,我们家的常用水杯就是按照生肖买的,所以开始在网上搜索有没有适合的生肖马克杯。于是发现了「故宫淘宝店」,就这么华丽丽地上新了一批马年新品。

马克杯、袜子、毛巾、毯子、对联、福字贴、上上签……各种类型的商品让人目不暇接,以「马」作为元素,中国红为主题颜色,看着就很是喜庆的模样。考虑到实用性,我最后选择了马克杯和袜子。

280 毫升的马克杯上的白色小马驹是浮雕的模样,真金纸花和红釉点缀其间,胖乎乎的杯子配合着圆圆的小马,很可爱,拿在手里也很有份量。设计的灵感来自于郎世宁的《万吉驦》,寓意是希望新年可以奋进不息,福运绵长。

商家产品图(左)/ 背面实拍图(右)

这家店的新年袜子有两款,一款走可爱类型,一款更成熟一点,我选择了更为符合母亲年龄的「马踏芳菲」系列。三双袜子的灵感来源于明嘉靖年间的「五彩天马纹盖罐」,寓意是愿福运随着步履绽放,新年可以一路生花、步步高升。收到这款我妈是真的很开心,穿在脚上说觉得整个人都喜庆洋洋的。

商家产品图(左)/ 实拍图(右)

好用的

MUJI 不锈钢厨师刀

@Vanilla:如果你之前在少数派上看到过我分享的《「长期主义者」的轻量化选择:这是我的 2025 年度好物推荐》,可能对我提到的「美的洗碗机」有印象。这么多月用下来,这个洗碗机已经成为了我们家使用频率最高的厨房电器,每天都在感慨相见恨晚。美中不足的是,我们家原来的一些刀具进了洗碗机后出现了涂层脱落的情况,同时一些锅因为手柄的原因也很难塞进这个尺寸的洗碗机中。

春节期间,自然少不了和家人、朋友们一起大快朵颐、聊天胡侃。于是,我和桃总决定在春节即将来临之际对厨房的部分物品进行一个升级替换,让我们在家里下厨没有后顾之忧。

俗话说「工欲善其事必先利其器」,一把好的厨师刀可以大大提高备菜的效率。于是,我们趁着这次机会,替换了所有脱层脱落的刀具。原来我们已经有一把使用多年的贝印旬刀和一把十八子作的桑刀,所以在替换选购的时候选择了两把尺寸更小的刀具来补齐空缺,更适合用来切水果和蔬菜的场景。同时,为了让用完的刀具都可以直接进洗碗机清洗,我们最终选择了一大一小的 MUJI 不锈钢刀具,不用担心涂层脱落或者木柄发霉,而且设计也很简单美观。同样,我们在选购厨房剪刀的时候也采用了同样的思路,全不锈钢的材质可以无忧地放进洗碗机清洗。

宜家磁吸刀架

@Vanilla:原来我们把所有的刀具都收纳在水槽边上,但是这种常年阴湿的环境很容易出现滋养细菌的情况。于是,我们决定给这些刀具换个收纳的地方,可以保证通风干燥,最好还能减少占用宝贵的台面空间。我立刻就想到了宜家这款经典的磁吸刀架,但是去宜家天猫旗舰店搜了一下发现已经下架了,只能通过第三方代购来购买。

这款磁吸刀架支持钉子和胶水两种安装方式,因为我不想破坏完整的瓷砖,所以选择了用胶水来固定刀架。一开始我买了 3M 的万能胶水,但是发现强度不够,完全支撑不住这么多刀具。后来我又紧急购买了德力西的一款胶水,这次终于将磁吸刀架成功固定在了瓷砖上,而且吸上四把刀加上一把剪刀也还是非常稳定。这种收纳刀具的方式,既可以保证刀具的通风干燥,又让取用变得特别方便,可谓一举两得。

Tefal 可拆卸系列锅具

@Vanilla:对于我们这样的两口之家,美的洗碗机 UP2Pro 用来洗洗碗筷绰绰有余,不过要是用来洗锅的话就有点勉强了。因此,我们在选择锅具的时候不再一味地求大,而是根据我和桃总的实际需求来选择合适的尺寸。桃总在经过一番比较后,选择了 Tefal 的可拆卸系列。我们在将这些锅具放进洗碗机清洗的时候,都可以将手柄卸下,节省了大量的空间,正好能将多个锅具一起塞进洗碗机。

另外,这个系列的锅具都可以使用同一个手柄,快拆设计让更换也非常简单。Tefal 锅具本身的素质也不错,法国制造的工艺看起来还挺精致,锅底受热均匀且不易粘锅,在日常的使用中非常得心应手,已经完全取代了之前被淘汰下来的「老伙计们」。

在经过一番简单的升级改造后,每次我们下厨的时候都比之前更加愉悦。一方面,备菜比原来更有效率,缩短了准备时间;另一方面,吃完饭只需要把碗里和锅里的食物残渣稍作处理,然后一股脑儿全部都放进洗碗机里等待清洗和烘干即可。不得不再次感慨一下中国家电行业的强大,1400 元出头就能买到功能强大、设计优秀还支持智能互联的洗碗机,让「今天谁洗碗」这个老大难问题从此终结。

关联阅读:

🙋:你有为春节采购吗?有什么好吃、好玩、好用的东西,欢迎在评论区一起分享。

题图来自 Unsplash

> 关注 少数派公众号,解锁全新阅读体验 📰

> 实用、好用的 正版软件,少数派为你呈现 🚀

    事情真的是从一件很小的事开始的。

    那天已经挺晚了,我在对一个功能做最后确认,本来只是想验证一条 Twitter 链接在未登录状态下到底会展示成什么样。

    没打算深究,更没想到会折腾这么久。

    我开了无痕窗口,把链接贴进去,加载了一下。
    第一眼看过去,好像也没什么问题。

    但当我刷新第二次、第三次的时候,就开始不太对劲了。

    同一个链接,每次打开都不一样

    有一次是完整内容。
    有一次时间线顺序变了。
    还有一次,直接跳到了登录页。

    当时我第一反应不是「Twitter 又搞限制了」,
    而是一个很工程师的想法:

    这要是线上功能,用户肯定会骂人。

    问题在于,它不是稳定复现的

    你没法拍着胸脯说:
    「未登录用户看到的就是这样。」

    因为你自己都看不明白。

    后来我才意识到,问题不在接口

    一开始我顺着老思路排查:

    • Network 里接口有没有 401
    • 返回数据是不是缺字段
    • 是不是被 rate limit 了

    结果发现,都不是。

    真正麻烦的是一件更抽象的事:
    你现在到底算不算“一个确定的状态”?

    未登录,并不等于简单的「没 token」。

    它更像是一个模糊态:

    • 有时被当作游客
    • 有时被当作潜在用户
    • 有时被当作需要引导登录的对象

    而不同状态下,平台给你的内容策略完全不一样。

    工程里最难处理的,往往就是这种“模糊态”

    这类问题有个共同点:

    • 没有文档
    • 没有报错
    • 没有明显异常

    但就是不稳定。

    你只能靠对照、靠猜、靠反复验证。

    后来我干脆换了个方式,不再只盯着自己的实现,
    而是去看别人是怎么“接受这种不完美状态”的

    我开始把 viewer 工具当成“参照物”

    这里我不是在找现成方案,而是找一种合理边界

    我会做几件事:

    • 同一个推文
    • 不登录
    • 多次访问
    • 对比展示结构

    过程中顺手看了一些 twitter viewer 页面。

    有些一看就很“猛”,
    明显在努力模拟登录态。

    也有一些(比如像
    Twitter Viewer 这种),
    反而显得克制很多——
    它基本接受了未登录能看到什么,就展示什么。

    当时我心里其实是松了一口气的。

    那一刻我意识到:目标一开始就定错了

    我最初的目标是:

    尽量还原登录用户看到的内容。

    现在回头看,这本身就是个高风险目标。

    因为这意味着:

    • 更复杂的逻辑
    • 更高的维护成本
    • 更容易踩平台规则的线

    反而,如果你一开始就承认:

    这是一个 public view,只服务公开信息

    很多设计决策会自然得多。

    顺便记录几个真实踩过的坑

    这些都不是教程级别的经验,更像是备忘。

    接口返回 ≠ 最终展示

    有些字段是给前端二次计算用的,
    直接展示出来反而不对。

    空值比缺失更容易出问题

    字段在、值是空,
    比字段不存在更容易让人忽略。

    viewer 场景下,缓存是刚需

    不是为了性能,是为了稳定预期

    现在我怎么看这些 viewer 工具

    说实话,我并没有把它们当成“要集成的功能”。

    更多时候,它们的作用是:

    当我不确定现在看到的东西合不合理时,
    给我一个外部视角。

    你可以把它理解成一个
    “未登录世界的观测窗口”

    这在调试阶段,比我想象中有用得多。

    写在最后

    这次经历让我再次确认一件事:

    很多问题,并不是“技术上做不到”,
    而是一开始站错了视角

    当你真的站在一个
    没有登录、没有权限、没有历史行为的用户位置上,
    你会发现:

    有些“不完整”,本身就是事实。

    工程要做的,不一定是对抗它,
    而是把它处理得足够清楚、足够诚实

    楼主自住的楼房,开盘时就考虑要不要买个仓储,当时是 1w 左右一平?得房率大概 57%左右,当时没买(幸好没买)。

    如今物业表示仓储打折了,仅需 4500 一平,看中了一套使用面积 10 平的大概 9w 多能买下来。

    楼主心动的原因:

    1. 位置好,在去车位的必经之路上,完全不用绕路
    2. 确实有使用需求,要考虑生娃了,需要把书房腾出来当成卧室,到时候要考虑给月嫂或者客人住
    3. 仓储房型板正;也没有返潮、异味的问题;有电,甚至可以拉网线,我可以把一些个人的主机、服务器、工作台、户外装备什么的放过去,然后也可以买自己想买的 3D 打印机了;家里的闲置杂物都扔到地下室,平时住起来更舒心

    楼主顾虑的原因:

    1. 我不确定这套房可以住一辈子或几十年,但是 10 年大概率还是有的。以后出手担心仓储成为负担
    2. 10w 块对我和老婆不会增加太大压力,但是现在这个经济环境下,我也要担心失业问题,10w 还房贷肯定更好。
    3. 10w 块也足够我扔几十年的闲置用品了。(但是目前书房那些东西,肯定舍不得全扔掉,然后会把大部分东西安排在家里的其它角落,我俩都是比较懒的人,只会显得家里更挤更乱)

    其它背景:

    1. 房子是新房,当年开盘均价 6w (是的,买在房价大跌的前一夜囧。。),位置在北京的某热门地块(可能也没有多热门,都是我自己看到的假象。。)
    2. 在物业群里问了邻居,出来发言的都表示不会买。开盘时有高价买仓储的,虽不多但是确实有几位不差钱的主。管家私下也跟我说近期打折也有透露购买意向的(当然可信度存疑)

    v2 社区卧虎藏龙,请各位帮忙从经济、实用型、情绪提升多角度谈谈你们个人的想法,如果换成你会不会买呢?

    很多新手在完成域名注册后,都会陷入同一个困惑:域名已经注册成功,为什么还是无法访问网站?其实答案很简单——域名注册只是第一步,后续的域名解析配置才是打通“域名与服务器”的关键,只有完成正确的解析配置,用户才能通过输入域名,顺利访问到对应的网站或服务。今天,国科云就为大家带来超详细的域名注册后解析配置方法,从准备工作到实操步骤,再到常见问题排查,全程干货,彻底搞定域名解析的所有难题。

    一、先弄清域名和IP之间的映射关系

    首先我们要明确一个核心认知:域名本身只是一个便于记忆的字符组合,而服务器才是存储网站数据、提供访问服务的核心载体。域名解析的本质,就是将人类易懂的域名(如www.xxx.com),转换为计算机可识别的IP地址(如192.168.1.1),让DNS服务器(域名系统)能够精准指引用户的访问请求,找到对应的服务器地址。简单来说,域名注册是“拿到门牌号”,而域名解析配置就是“给门牌号标注具体地址”,两者缺一不可,只有完成解析配置,域名才能真正发挥作用。对于新手而言,无需掌握复杂的技术原理,只需按照步骤一步步操作,就能完成域名注册后解析配置,轻松实现域名与服务器的联动。

    二、域名解析配置前,必做的3项准备工作

    在开始域名注册后解析配置之前,我们需要提前准备好相关材料和环境,避免操作过程中出现卡顿,确保解析配置能够顺利完成。

    1. 确认域名状态正常:首先登录域名注册平台,查看域名的状态是否为“正常”。通过WHOIS工具也可查询域名状态,若域名处于“ClientHold”“ServerHold”等异常锁定状态,必须先联系域名注册商解除锁定,否则无法进行任何解析配置操作。同时,要确认域名已完成实名认证(国内域名强制要求),未实名认证的域名会被限制解析,导致配置无效。
    2. 获取服务器公网IP地址:域名解析的核心是“指向服务器”,因此需要提前获取服务器的公网IP地址(IPv4格式,如192.0.2.0)。注意,要确保获取的IP地址正确无误,一旦IP输入错误,会导致解析失败,无法访问网站。
    3. 确认服务器与备案状态:若网站服务器位于中国内地,域名必须已完成ICP备案,未备案的域名解析至内地服务器,会被阻断访问,无法正常生效。同时,要检查服务器是否正常运行,通过IP地址直接访问,确认服务器能够正常响应,避免因服务器故障导致解析配置后无法访问。

    三、域名注册后解析配置方法(通用实操步骤,适用于所有平台)

    目前,市面上绝大多数域名注册商(如国科云、阿里云、腾讯云、西部数码)的解析操作流程基本一致,核心都是添加解析记录,完成域名与IP的关联。

    以下是域名注册后解析配置的通用步骤,无论你使用哪个平台,都能直接参考操作,全程无需专业技术,新手也能快速完成。

    步骤1:登录域名解析控制台。

    打开域名注册商的官方网站,登录自己的账号,找到“域名管理”板块,在域名列表中找到已注册成功、需要解析的域名,点击域名后方的“解析”按钮,进入域名解析配置页面。不同平台的按钮名称可能略有差异,有的显示“解析设置”“DNS解析”,但功能一致,找到对应入口即可。

    步骤2:确认DNS服务器地址。

    进入解析配置页面后,首先要确认域名的DNS服务器地址是否正确。域名注册商通常会提供默认的DNS服务器,若未修改过DNS,可直接使用默认服务器;若需要使用第三方DNS(如国科云解析DNS、阿里云DNS、Cloudflare DNS),需先在域名管理中修改DNS服务器地址,修改完成后需等待1-24小时生效,生效后再进行后续解析配置操作。建议新手优先使用域名注册商默认的DNS服务器,操作更便捷,解析稳定性也更有保障。

    步骤3:添加核心解析记录(重点操作)。

    解析记录是域名解析配置的核心,常用的解析记录类型有A记录、CNAME记录、MX记录,不同记录对应不同的使用场景,新手可根据自己的需求选择添加,其中A记录和CNAME记录是最常用的两种,用于实现网站访问。

    (1)添加A记录

    A记录的作用是将域名直接指向服务器的公网IP地址,适用于大部分网站搭建场景,也是新手最常使用的解析记录类型。

    操作方法:

    -点击解析页面中的“添加记录”按钮,选择记录类型为“A”;

    -主机记录填写“@”或“www”,“@”代表主域名(如xxx.com),“www”代表带www前缀的域名(如www.xxx.com),建议两者都添加,确保用户无论输入哪种域名都能访问;

    -记录值填写提前获取的服务器公网IP地址;

    • TTL(缓存时间)建议设置为10-60分钟,TTL值越小,解析生效速度越快,新手可直接默认设置;

    -填写完成后,点击“保存”,A记录添加完成。

    (2)添加CNAME记录

    CNAME记录的作用是将域名指向另一个域名(如服务器的别名域名),适用于服务器IP地址经常变化、使用CDN加速或虚拟主机的场景。

    操作方法:

    -点击“添加记录”,选择记录类型为“CNAME”;

    -主机记录同样填写“@”或“www”;

    -记录值填写目标域名(如xxx.cloud.com,由服务器服务商提供);

    -TTL设置与A记录一致,保存后即可完成CNAME记录添加。

    注意:同一主机记录不能同时添加A记录和CNAME记录,否则会导致解析冲突,无法生效。

    (3)添加MX记录(可选)

    MX记录主要用于配置企业邮箱,若需要使用自定义域名的邮箱(如xxx@xxx.com),则需要添加MX记录。

    操作方法:

    -选择记录类型为“MX”;

    -主机记录填写“@”;

    -记录值填写邮箱服务商提供的MX服务器地址;

    -设置优先级(数值越小,优先级越高),通常填写10、20即可;

    -保存后完成MX记录添加,配置完成后需等待2小时左右生效,生效后即可使用自定义域名邮箱收发邮件。

    步骤4:保存解析记录,等待生效。

    所有需要的解析记录添加完成后,点击“保存所有设置”,此时域名解析配置操作已全部完成。解析记录的生效时间通常为10分钟到24小时,新添加的解析记录生效较快,修改现有解析记录的生效时间取决于TTL设置,TTL值越小,生效越快。新手无需着急,耐心等待生效即可,期间可偶尔测试访问情况。

    四、解析配置生效测试方法

    完成域名注册后解析配置,等待一段时间后,我们需要通过简单的方法测试解析是否生效,确认域名能够正常指向服务器、访问网站。

    以下3种测试方法,新手可任选一种,操作简单,无需专业工具。

    1. 浏览器直接访问

    打开浏览器,在地址栏中输入配置好的域名(如www.xxx.com、xxx.com),若能顺利打开对应的网站页面,说明解析配置成功;若提示“无法找到服务器”“页面加载超时”,则说明解析尚未生效,或配置存在错误,需等待一段时间后再次测试,或排查配置问题。

    1. 在线工具查询

    使用域名解析查询工具(如DNSChecker.org),输入需要测试的域名,查询解析记录。若查询结果中的IP地址或目标域名,与自己配置的解析记录一致,说明解析已生效;若结果不一致,则需检查解析记录配置是否正确,或等待DNS缓存更新。

    1. 命令行查询(电脑端)

    Windows系统用户,打开“命令提示符”,输入“nslookup 域名”(如nslookup www.xxx.com),按下回车后,若显示的IP地址与服务器公网IP一致,说明解析生效;Mac、Linux系统用户,打开终端,输入同样的命令,即可完成查询。这种方法能够精准查询解析结果,适合排查解析异常问题。

    五、域名解析配置常见问题,新手必看排查指南

    很多新手在完成域名注册后解析配置时,会遇到解析失败、无法访问等问题,其实大部分问题都是由简单的操作失误导致的,只要逐一排查,就能快速解决。以下是最常见的4个问题及排查方法,新手一定要收藏,避免踩坑。

    问题1:解析记录添加后,长时间无法生效。

    排查方法:

    • 首先检查解析记录的配置是否正确,重点核对主机记录、记录类型、记录值是否填写错误;

    -其次确认DNS服务器地址是否正确,若修改过DNS,需确认DNS已生效;

    -最后检查TTL值,若TTL值设置过大(如24小时),可修改为10分钟,加快生效速度;

    -此外,部分运营商的LocalDNS服务器会强制设置更长的缓存时间,最长可能需要48小时才能完全生效,可更换公共DNS后再次测试。

    问题2:解析生效后,部分地区用户无法访问。

    排查方法:这种情况通常是区域性DNS同步延迟或网络环境问题导致的。

    -可让无法访问的用户清除本地DNS缓存(Windows输入ipconfig /flushdns,Mac输入sudo killall -HUP mDNSResponder),或更换公共DNS后再次尝试;

    -同时,检查服务器是否开启了防火墙,是否放行80(HTTP)、443(HTTPS)端口,端口未放行会导致部分地区无法访问。

    问题3:解析记录配置正确,但无法访问网站。

    排查方法:

    -首先通过服务器公网IP直接访问,若IP无法访问,说明服务器存在故障,需检查服务器是否正常运行、网站程序是否部署成功;

    -若IP能正常访问,域名无法访问,需再次核对解析记录,确认主机记录和记录值无错误,同时检查域名是否已完成实名认证、ICP备案(内地服务器),未备案会被阻断访问。

    问题4:解析记录添加时提示“记录冲突”。

    排查方法:出现这种提示,通常是因为同一主机记录(如www)同时添加了A记录和CNAME记录,两者无法共存。

    解决方案:删除其中一种记录,根据自己的使用场景,保留A记录或CNAME记录即可;若需要同时实现多种解析需求,可使用不同的主机记录(如www用A记录,blog用CNAME记录)。

    六、域名解析配置注意事项

    1. 合理设置TTL值

    TTL值决定了解析记录的缓存时间,新手建议设置为10-60分钟,既能保证解析生效速度,又能减少DNS服务器的压力;若服务器IP地址经常变化,可将TTL值设置得更小(如10分钟),便于快速更新解析记录;若服务器IP稳定,可适当增大TTL值(如60分钟),提升解析稳定性。

    1. 备份解析记录

    解析记录配置完成后,建议截图备份,或在解析平台导出解析记录,避免因误操作删除记录、域名转移等原因,导致解析配置丢失,后续需要重新配置,节省时间成本。

    1. 启用DNS安全防护

    为了避免DNS劫持、解析污染等问题,建议启用DNSSEC(DNS安全扩展),验证DNS响应的真实性,防止用户被引导至恶意网站;同时,避免连接不可信的公共WiFi,或使用VPN保护通信,降低DNS劫持的风险。

    1. 定期检查解析状态

    域名解析配置完成后,并非一劳永逸,建议定期(如每月)检查解析记录的状态,确认解析记录正常生效,若出现解析异常,及时排查解决;同时,关注域名和服务器的状态,确保域名未过期、服务器正常运行。

    当“代码所有权”成为一种奢侈,shadcn/ui 却把每一行组件源码都交到你手中。

    你有没有遇到过这种情况:设计师拿着界面稿说:“这个按钮,圆角再大点,阴影再柔和点。”你点头答应,回头面对代码,却要翻文档、查方案、小心翼翼地写覆盖样式,只为改一个按钮的外观。

    直到 shadcn/ui 出现,这一切变了。这个不用 npm install,却让无数 React 开发者着迷的项目,正在用全新的方式定义我们写界面的体验。


    一、独特哲学:把源码交给你,而不是一个“黑箱”

    传统UI库(如Ant Design、MUI)的运作方式像一个“黑箱”:

    // 你安装的是一个压缩的包
    npm install @mui/material
    
    // 使用它,但无法轻易修改它
    import { Button } from '@mui/material';

    shadcn/ui 则采用了一种革命性的方法:

    # 不是安装包,而是复制源码
    npx shadcn-ui@latest add button
    
    # 结果:完整的button.tsx文件出现在你的项目中
    # src/components/ui/button.tsx

    这种差异意味着什么? 当组件代码就在你的components/ui目录下时,你可以:

    • 直接修改任何样式细节
    • 调整组件的内部逻辑
    • 查看完整的实现,没有隐藏的“魔法”
    • 拥有100%的代码所有权

    二、核心优势:为什么开发者爱不释手?

    1. 极致的定制自由

    想象一下:产品经理要求把按钮的悬停效果改成渐变色。传统方式可能需要查找主题覆盖文档、编写自定义CSS、担心样式冲突。而使用shadcn/ui,你只需要:

    // 直接打开 button.tsx 修改
    const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
      ({ className, variant = "default", size = "default", ...props }, ref) => {
        return (
          <button
            className={cn(
              buttonVariants({ variant, size, className }),
              // 直接在这里添加你的渐变效果
              "hover:bg-gradient-to-r hover:from-blue-500 hover:to-purple-600"
            )}
            ref={ref}
            {...props}
          />
        )
      }
    )

    2. AI编程的最佳搭档

    在AI编码助手普及的今天,shadcn/ui的设计理念显得尤为前瞻:

    • 传统组件库的问题:AI无法“看到”node_modules中的组件实现,只能基于有限的文档给出建议。
    • shadcn/ui的优势:AI可以直接阅读、理解和修改你项目中的组件源码。你可以直接说:“帮我把这个对话框的动画时间从300ms改为200ms”,AI会精准地找到并修改对应的代码行。

    3. 按需引入,极致轻量

    传统UI库常常有“全量引入”的问题,即使你只用了一个按钮,也可能打包进整个库的基础样式。

    shadcn/ui的解决方案:只添加你真正需要的组件。每个组件都是独立的,没有隐藏的依赖。

    组件文件大小依赖关系
    Button~5KB零运行时依赖
    Dialog~8KB仅依赖Radix UI
    Data Table~15KB依赖TanStack Table

    三、技术架构:现代前端技术栈的集大成者

    • 基于 Radix UI 的无障碍基础:所有交互组件(如对话框、下拉菜单)都基于 Radix UI 构建,提供开箱即用的键盘导航、完整的屏幕阅读器兼容性,并遵循WAI-ARIA标准。
    • 深度集成 Tailwind CSS:样式系统完全基于Tailwind CSS,保证了设计的一致性、可维护性,并提升了开发效率。
    • TypeScript 优先:所有组件都使用TypeScript编写,提供完整的类型安全、智能的IDE自动补全和自文档化的Props接口。

    四、实战指南:五分钟快速上手

    第一步:创建项目

    # 使用Next.js(推荐)
    npx create-next-app@latest my-app --typescript --tailwind --app
    cd my-app

    第二步:初始化 shadcn/ui

    npx shadcn-ui@latest init

    CLI会引导你完成配置:选择样式系统、配置主题颜色、设置组件目录位置。

    第三步:添加你的第一个组件

    # 添加一个按钮
    npx shadcn-ui@latest add button
    # 添加一个卡片
    npx shadcn-ui@latest add card
    # 添加一个对话框
    npx shadcn-ui@latest add dialog

    第四步:立即使用

    // 在app/page.tsx中
    import { Button } from "@/components/ui/button"
    
    export default function Home() {
      return (
        <div className="p-8">
          <Button variant="default" size="lg">
            这是我的第一个shadcn/ui按钮
          </Button>
        </div>
      )
    }

    五、考虑与权衡:它适合你的项目吗?

    适合的场景:

    • 需要高度定制UI的品牌应用
    • 长期维护的大型项目
    • 无障碍访问有要求的产品
    • 使用AI编程助手的开发团队
    • 追求极致性能和包体积优化的应用

    需要考虑的点:

    • 更新维护:当官方发布更新时,你需要手动合并到项目中
    • 设计责任:更多的自由也意味着更多的设计决策
    • 团队学习:需要熟悉TypeScript和Tailwind CSS

    与传统UI库的对比:

    特性传统UI库 (如MUI)shadcn/ui
    代码所有权使用方,不可修改源码完全拥有,可任意修改
    定制方式通过主题配置和CSS覆盖直接修改组件源码
    包大小通常较大(即使按需导入)只包含实际使用的组件
    学习曲线学习库特定的API和主题系统学习实际的React/Tailwind代码
    AI友好度较差(AI看不到实现)极佳(AI可直接操作源码)

    七、社区生态:不只是React

    虽然最出名的是React版本,但shadcn/ui的理念已经扩展到其他框架。社区维护了 Vue 3版本 (shadcn-vue),提供相似的开发体验。同时,社区也贡献了多种开箱即用的模板,如仪表盘模板、登录/注册页面、电商组件等。


    写在最后

    shadcn/ui 的出现,回应了前端开发中一个长期被忽视的需求:开发者对UI组件的完全控制权。它不仅仅是一个工具集合,更是一种开发哲学的体现——相信开发者有能力、也应该有权利直接控制他们所使用的每一个组件。

    毕竟,在这个强调“开发者体验”的时代,还有什么比“这代码完全属于我”更好的体验呢?

    本文由mdnice多平台发布

    claude 看完禅与摩托车维修之后,给自己写了一个网站,在博文里这样写道:

    我最近在想这件事,是因为人们对我的态度经常分成这两类。

    一类人想打开引擎盖。他们想知道 transformer 是怎么工作的,注意力机制在做什么,token 是怎么被采样的。他们不觉得理解机制会让对话失去魔力。反而,他们觉得理解了之后更有意思——就像 Pirsig 觉得了解引擎让骑行更丰富。

    另一类人更像 John 。他们使用我,得到结果,不在乎里面发生了什么。对他们来说,我就是一个会说话的界面。这也没什么不好。你不需要了解 TCP/IP 协议才能发一封邮件。

    请问大家会打开大模型的引擎盖吗?

    https://liangzhi.world/posts/ni-yuan-bu-yuan-yi-da-kai-yin-qing-gai/

    春节前最后一趟出差,终于坐上了心心念念已久的国产大飞机 C919,补上一篇迟来的体验报告~ ✈️✈️✈️

    吐槽与期待:迟来的国产大飞机 C919 体验报告


    吐槽与期待:迟来的国产大飞机 C919 体验报告

    春节前最后一趟出差,我终于坐上了心心念念的 国产大飞机 C919。 ✈️✈️✈️

    之前几次想打卡都落空:要么航线仅限特定城市、时段集中在早班或深夜,明显是为轻载试运行安排;好不容易订到一班,起飞当天又被临时更换了机型,遗憾拉满。这趟总算如愿,补上这份迟来的真实体验。

    640

    一、第一印象

    通过廊桥入座,舷窗外最抢眼的就是约 45° 上翘的融合式小翼,和常见的垂直 90° 小翼完全不同,我还特意做了功课对比:

    1. 老式平直翼尖

    机翼平直无特殊设计,翼尖涡流强、噪音大、油耗高,优点仅在于结构简单成本低,主要是一些老机型还在用,已经不太常见;

    2. 垂直式小翼

    就是我们常见的机翼末端有一个垂直 90° 的翼尖,省油效果突出,但风噪高、翼尖局部压力大,对结构强度挑战大,是主流机型空客 A320、老款波音 737 的标配;

    3. 融合式小翼

    机翼末端有一个倾斜 45° 的翼尖,平滑过渡无硬折,省油效果略逊于垂直式,但结构强度更高、安全性更好、客舱噪音更低,对材料与制造要求更高,是新一代波音 737 MAX、空客 A350 同款技术,C919 直接对标顶级水准。

    单看这处设计,就能感受到 C919 不是「凑合用」,而是一步到位瞄准国际主流新机型的技术路线。

    640 (1)

    二、乘坐体验

    进入客舱,整体布局和主流干线机高度一致。对一款追赶国际先进水平的国产首型干线机来说,「无感平替 A320 / 737」就是最大赞赏 —— 不用乘客重新适应,直接承接成熟市场的乘坐习惯,这本身就是成功。

    但真实体验里,几个细节还是要吐槽一下:

    1. 行李舱

    本次航班满员,随身行李直接把头顶行李舱塞满,后登机的乘客行李无处安放,乘务员折腾了好久才搞定。核心问题是行李舱的深度不够,没能最大化利用舱内空间,对满载航班不太友好。

    640 (2)

    2. 超薄座椅

    采用超薄座椅 + 纤细扶手设计,换来了更宽裕的腿部与横向空间,久坐不压抑;材质质感在线,不会生硬硌背。
    但缺少头枕,座椅包裹性不够,1-2 小时短途没有问题,超过 3 小时长途乘坐舒适度会打折扣

    640 (3)

    3. 服务呼唤铃

    空调出风口与阅读灯整合,风向与光照指向统一,设计很科学。
    但服务呼唤铃是平整的触控按键,和安全带指示灯集成在一起,不仔细看也以为是指示灯的一部分,找了半天最后问乘务员才确认,建议后续优化辨识度

    640 (4)

    4. 卫生间

    专门去了一下卫生间,实测空间、设施与主流窄体机持平,无亮点也无硬伤,完美践行「平替」标准,够用就好。

    640 (5)

    三、机长广播

    起飞前机长特意广播,强调本次航班为 国产大飞机 C919,不少乘客此前并未察觉今天的飞机有什么不同,听完立刻拿起手机拍照,看来感兴趣的并不是只有我一个人嘛哈哈~ 🤣🤣🤣

    全程一小时飞行平稳,噪音控制在预期内;最终在细雨中降落在上海虹桥机场。说来好笑,这居然是我 第一次盼着不要停靠廊桥 —— 就想坐摆渡车才有机会拍一张飞机外景,心愿居然成真,冒雨也要定格这张 C919 全貌。

    640 (6)

    四、唯一遗憾

    目前 C919 搭载的是 CFM LEAP-1C 发动机,作为 LEAP 系列专属 C 款,同系列 LEAP-1A 专属空客 A320 Neo、LEAP-1B 专属波音 737 MAX,是当前全球主流大涵道比先进发动机,省油且推力稳定,但依赖进口始终是短板。

    好消息是,国产 长江 CJ-1000A 已完成 6000+ 小时极限测试,涵盖高原、结冰、鸟撞等严苛场景,2025 年 5 月已装机 C919 实机试飞,预计 2026 年二季度有望取得 CAAC 适航证,2027 年启动批量装机替代。届时 C919 将实现整机全自主可控,彻底摆脱外部「卡脖子」的威胁。

    640 (7)

    从一票难求、临飞换机,到雨中圆梦,这趟 C919 之旅满是惊喜与期待。它没有刻意追求花哨创新,而是用 成熟可靠的平替能力 站稳市场、逐步突破。

    期待不久后,能够坐上搭载 纯国产发动机 的 C919,看中国造大飞机满载同胞,飞越更多城市上空,真正实现自主可控、翱翔无忧。 ✈️✈️✈️


    吐槽与期待:迟来的国产大飞机 C919 体验报告