自动化越多,为什么IT反而更累?

在IT服务管理升级过程中,自动化几乎是所有企业都会重点投入的方向。无论是工单分配、通知提醒,还是审批流转,自动化工具的引入本应显著降低人工工作量。但现实情况却往往出人意料:自动化规则越多,IT团队反而越忙。ManageEngine卓豪 将为您解答这些问题!

例如,系统中设置了大量规则,但却频繁出现异常情况,需要人工介入处理;自动通知过多,反而增加沟通成本;复杂流程导致用户操作困难,从而增加支持请求。这些问题使自动化从“减负工具”变成“新负担”。

这种现象说明,自动化本身并不会自动提升效率,关键在于如何设计与使用。

问题根源:自动化以“技术逻辑”为中心,而不是“业务逻辑”

在很多企业中,自动化规则的设计往往由IT主导,并以技术实现为核心,例如条件触发、字段匹配与流程分支。这种方式虽然可以实现功能,但未必符合业务实际需求。

例如,某些流程在系统中被严格定义,但在实际操作中却存在例外情况,导致规则频繁失效;或者流程设计过于复杂,使用户难以理解,从而增加沟通成本。

当自动化脱离业务场景时,就很难产生真正价值。

真正有效的自动化,应该从哪里开始?

要实现有效自动化,企业需要从业务需求出发,而不是从技术能力出发。换句话说,应该先明确哪些问题需要解决,例如减少重复工作、提升响应速度或降低沟通成本,然后再设计相应规则。

例如,可以优先自动化高频、标准化程度高的流程,而不是一开始就覆盖所有场景;对于复杂流程,可以保留人工判断空间,从而避免规则冲突。

通过这种方式,企业可以逐步建立稳定的自动化体系,而不是一次性构建复杂系统。

ServiceDesk Plus 如何帮助企业“做对自动化”?

通过ServiceDesk Plus,企业可以基于实际业务场景灵活配置自动化规则,而不是依赖固定模板。系统支持可视化流程设计与规则管理,使IT团队能够更直观地调整策略。

同时,通过与SLA与数据分析结合,企业可以持续评估自动化效果,并进行优化。这种闭环机制,可以避免自动化失控或失效。

在下一部分中,我们将深入分析:如何通过优化自动化策略,让IT真正“少做事,而不是多做系统维护”。

常见问题(FAQ)

  1. 自动化是否越多越好?
    不是,应根据实际需求设计。
  2. 如何判断自动化是否有效?
    通过SLA与效率指标进行评估。
  3. 自动化失败的常见原因是什么?
    规则复杂、脱离业务场景与缺乏数据支持。
  4. 如何进一步了解自动化实践?
    可以参考ITSM解决方案获取更多信息。

注:本文含AI辅助创作。

2025 年 12 月 13 日,VeloxCon China 2025 在北京成功举办。作为 Velox 项目首次在中国举办的线下技术大会,汇聚了来自Meta、IBM、蚂蚁集团、阿里云、腾讯、小米、小红书等企业的数十位核心贡献者与一线工程师。

大会通过 18 场演讲将 Velox 置于真实业务场景之中,系统展示了其在架构演进、AI 数据处理、湖仓加速、流批融合等方向的最新实践。这些分享不仅直面性能、稳定性与兼容性等落地挑战,也反应了开发者社区对构建可靠、可扩展、可协同的数据基础设施的共同探索,彰显了中国开发者在全球高性能分析生态中的工程深度与协作广度。

夯实底座,突破能力边界
会议伊始,Velox 项目联合发起人 Pedro 发表开幕致辞。他回顾了 Velox 开源项目的发展历程,从项目启动、开源发布到建立技术治理结构,展示了 Axiom 架构、GPU 支持、PyVelox 等关键进展,强调了社区协作与工程严谨性是项目持续演进的核心动力。他特别提到,Velox 已建立了正式的技术治理机制,并迎来来自 IBM、Intel、NVIDIA、Microsoft 等多家企业的新增维护者,标志着项目正迈向更加开放和可持续的阶段。

在明确了社区与架构演进的总体方向后,大会议题迅速深入到如何利用 Velox 构建高性能计算引擎的具体实践中。阿里云 EMR Serverless Spark 技术负责人周克勇系统阐述了“可组合性”在数据计算领域的实践。他详细解析了阿里云如何深度集成并贡献于 Apache Celeborn、Paimon、Velox 及 Gluten 等开源组件,通过模块化组装构建出高性能湖仓一体引擎。他指出,基于该架构,阿里云 EMR Serverless Spark 成功创造了 TPC-DS 100TB 规模性能测试的世界新纪录,实现性能翻倍与性价比大幅提升。

接着,Meta 软件工程师 Masha Basmanova 阐述了现有查询引擎在跨语言通信、优化器能力与开发体验上面临的挑战,并介绍了基于 C++ 的统一前端框架 Axiom。该框架将 SQL 解析、逻辑优化与物理执行融为一体,通过内置的强大优化器与 Velox 运行时无缝对接,能够实现更高效、可扩展的查询处理。演讲最后,她积极展示了 Axiom 的开源路线图,并欢迎全球开发者加入,共同推动该项目的演进。

强大的执行框架,最终需要服务于极具挑战性的数据场景,特别是爆发式增长的 AI 数据。Meta 软件工程师孟晓烜则在之后的演讲中,深入阐述了应对AI训练数据规模激增与成本挑战的解决方案。他重点介绍了 Meta 如何通过数据归一化技术剥离重复特征,并构建可索引的序列存储系统。依托 Velox 技术栈,团队在训练数据的加载、生成与探索三大环节实现了端到端优化,显著提升了处理效率与资源利用率。

在 Meta 多位工程师从框架演进、可组合架构、数据标准化等角度深入分享后,蚂蚁集团高级技术专家黄叶伟也从企业落地实践层面分享了基于 Velox 的 Spark 加速实践。他重点介绍了基于 Gluten 与 Velox 构建的向量化引擎如何通过任务级 Fallback、Spill 优化、Shuffle 优化等关键技术,在混合部署场景下显著提升 Spark 性能与稳定性。他表示,该方案目前已实现日均数十万任务覆盖,平均节省资源超30%,并将在算子优化与架构扩展方面持续演进。

作为连接 Spark 生态与原生加速的关键中间层,Apache Gluten 的进展同样备受关注。来自 IBM 的莫芮与周渊聚焦 Apache Gluten与 Velox 的深度集成,阐述了其如何在大数据分析中驱动创新。他们介绍,Gluten 在保持对 Spark/Flink 作业透明加速能力的同时,正逐步增强对多后端引擎和复杂业务场景的适配能力。目前,该方案已在 Pinterest、顺丰科技及多个内部集群完成规模化验证,有效支撑了从日志分析到物流调度等多样化负载的性能提升与成本优化。

随着向量化加速在通用场景日趋成熟,针对特定存储格式的深度优化成为新的效能突破口。腾讯大数据开发工程师陈锦海分享了微信基于 Velox 加速 lceberg 湖仓分析的优化与实践,重点介绍了原生分桶方案。据他介绍,该方案通过动态识别表元信息自动设置分区数,能有效缓解 AQE 引发的写入倾斜,结合空闲资源灰度发布策略,可保障大规模作业的稳定上线。

扎根场景,释放协同效能
午餐后的议程更加聚焦 Velox 在真实业务中的集成深度与生产韧性,回应了开发者们对兼容性、稳定性与端到端效能等规模化落地的核心关切。
小米计算平台计算引擎负责人王胜杰分享了公司在 Spark 向量化升级中的规模化落地经验。面对业务迁移中的兼容性与稳定性挑战,他表示,小米通过自动兼容校验、双跑结果比对及内存异常感知的三级资源升级机制,已成功推动向量化改造在数十万作业中平稳落地。

面对海量数据挑战,全球科技公司也在探索相似的演进路径。Meta 软件工程经理 Stanley Yao 在演讲中分享了公司基于 Velox 推进 Spark 向量化改造的整体策略。他表示,团队通过从定制化方案到开源架构的持续演进,已实现关键业务管线向 Gluten(Flare)的平稳迁移,并获得显著的效率提升。未来,Meta 计划进一步扩大该架构的应用规模。

在 CPU 向量化趋于普及的同时,利用异构硬件挖掘更高性能成为新的前沿。IBM 研究院资深软件工程师 Zoltán Arnold Nagy 展示了基于 Velox 与 Presto 的 GPU 加速数据处理方案。他介绍道,Velox 通过与 cuDF 集成,可在 GPU 上高效执行算⼦,并针对多 GPU 分布式场景优化通信与数据交换。此外,为突破 I/O 瓶颈,团队正在探索结合 GPUDirect 存储与缓存层的加速策略。

对性能与稳定性的追求,也驱动着查询引擎架构本身的融合与创新。Meta 软件工程师谭家梁与大家分享了 Native Presto-on-Spark 的规模化应用。该架构以 Presto 查询优化、Spark 资源调度与容错机制以及 Velox 原生向量化执行为核心,实现了性能与可靠性的显著提升。他表示,目前该方案已在生产环境中取得成效,并将在未来持续推进全栈原生化演进。

对于国内庞大的云上业务,Velox 同样在支撑着关键数据服务平台。 阿里云高级工程师王彬与范阿冬系统介绍了Velox在阿里云日志服务中的深度集成与应用。他们指出,基于 Velox 构建的高性能查询引擎,通过混合执行、表达式下推、自动增量物化视图及免 Schema 分析等核心技术,可显著提升平台在处理海量实时数据时的查询效率与资源利用率。他们还强调,该架构不仅为日志分析、智能运维等场景提供了稳定支撑,也为面向 AI 的云原生数据平台演进奠定了坚实基础。

除了通用的日志与湖仓分析,Velox 也在向更垂直的时序数据场景渗透。腾讯高级工程师李兆龙分享了基于 Velox 构建云原生时序数据库的落地经验。他表示,通过在 Velox 中实现时序数据去重优化与存储写入增强,系统在应对高频写入与实时查询场景时,可显著提升吞吐效率与响应性能。目前该方案已有效支持物联网、实时监控等业务场景,未来还将进一步完善缓存与压缩机制,持续优化时序数据处理的整体效能。

IBM 软件工程师刘平接着分享了 Velox 在 Iceberg 数据写入能力上的突破性进展。他表示,目前 Velox 对 Iceberg 的支持以读取为主,其写入功能的完善将填补该方向的关键能力空白,为基于 Presto 与 Spark 的数据湖架构提供更统一、高效的数据摄入层。这一进展也标志着 Velox 正从查询加速向数据全链路处理拓展。

接着,来自阿里云的毕岩与周滔分享了 Velox 与 Apache Paimon 深度集成的解决方案,为提升引擎与存储的协同效率提供了另一种集成思路。在他们看来,现有方案存在表类型支持受限、缺乏可移植性等瓶颈, 但可以建立 C++ 原生 Paimon 库,通过其统一的数据协议与插件化设计,使 Paimon 能够被 Velox、StarRocks 等多种计算引擎直接高效调用,从而提升数据读写性能,并为湖仓格式的跨引擎协同提供新的基础支撑。

在批处理场景之外,流计算框架的向量化也正成为新的热点。蚂蚁集团技术专家刘勇介绍了基于 Velox 为 Flink 构建的统一向量化执行引擎 Flex。他表示,Flink 作为流批一体架构的核心,其原生向量化能力的补足至关重要。Flex 通过将 Velox 的高性能算子能力引入 Flink,同时结合自动化验证、可视化计划与精细化回退机制,现已实现了作业性能的显著提升,并支撑多条核心业务链路平稳运行。

随着 Velox 赋能的应用场景日益广泛和复杂,确保其在不同引擎和版本间的整体质量与可靠性变得至关重要。Meta 软件工程师 Eric Liu 阐述了在 AI 数据基础架构下,保障 Velox 多引擎版本可靠性的系统化方法。他指出,面对不同引擎与存储格式交织带来的复杂性,关键在于建立跨引擎测试框架与合成数据工厂。这一实践能有效提前发现全栈潜在问题,从而确保底层变更在大规模生产环境中的稳定与高效。

针对向量化引擎中窗口运算符内存溢出的典型难题,来自英特尔的贾柯分享了她的见解。她认为,通过为 Velox 引入流式窗口处理机制,可使计算随数据到达逐步执行并即时释放内存,从而从架构层面化解多数场景下的内存风险,显著提升复杂查询的稳定性。

最后,小红书 Native Engine 团队技术负责人魏秀利也分享了向量化引擎在公司业务中规模化落地的经验。据他介绍,通过将写入异步化并构建原生 Avro 读取能力,小红书在不增加业务复杂度的前提下,成功缓解了端到端延迟,印证了“执行与存储协同优化”在湖仓场景中的关键价值。

从底层执行引擎的持续创新,到日志分析、湖仓写入、流批融合等复杂场景的稳定运行,在本届 VeloxCon China 上,我们看到 Velox 的技术价值已在真实业务中不断被验证和拓展。同时我们也很高兴看到中国开发者成为这一进程的重要推动者。期待未来有更多志同道合者加入 Velox 开源社区,共建高性能分析基础设施。weibo.com/ttarticle/p/show?id=2309405290086815629383 weibo.com/ttarticle/p/show?id=2309405290087230865518 weibo.com/ttarticle/p/show?id=2309405290087587119464 weibo.com/ttarticle/p/show?id=2309405290088115601507 weibo.com/ttarticle/p/show?id=2309405290088476311626 weibo.com/ttarticle/p/show?id=2309405290088832827475 weibo.com/ttarticle/p/show?id=2309405290089189605615 weibo.com/ttarticle/p/show?id=2309405290089612968087 weibo.com/ttarticle/p/show?id=2309405290090124935314

听说有 7 元一个月的,源头的,没找到购买连接
请大佬们分享一下

买了 cursor/claude,花了 200 多,站起来蹬,已经全部用完了
自费上班. 太苦了

今天,我在 github 查看项目



https://github.com/owu/wsl-dashboard



的流量来源,发现有很多谷歌来源。



我试着谷歌“WSL Dashboard”,居然看到微软商店 9.99 刀的同名项目(简单的换了皮肤,功能是我的上一个版本,界面上的选项都一样,4 月 15 号发布的),开发者是合肥的一个公司,这个人也在 V 站(备注的创始人)。



简单看了一下微软商店他发布的软件,就发现还盗版了 alist 项目,还有一些其他的应用没仔细看。



有人盗版,说明项目还可以😂

今日亮点

今天 AI 圈有两大看点。OpenAI 发布播客,深入探讨了其用于生物学和药物发现的生命科学模型系列,透露了“GPT-Rosalind”的更多细节。同时,Anthropic 也公布了两项重要研究进展:一项关于大语言模型“潜意识学习”的论文登上了《自然》杂志,另一项研究则展示了其自动化对齐研究员(AARs)在提升模型性能上的显著成效。

💡 产品动态

OpenAI 推出生命科学模型播客

OpenAI 最近在其播客中深入介绍了其全新的生命科学模型系列,特别提到了代号为 GPT-Rosalind 的前沿推理模型。这款模型旨在支持生物学研究、药物发现和转化医学领域,讨论涵盖了模型在改善研究工作流和未来实现自主实验室方面的潜力,以及部署过程中的责任考量。

为什么重要: 这表明 OpenAI 正将 AI 能力扩展到特定科学领域,通过更专业的模型来加速生命科学研究,有望大幅提升药物研发和生物探索的效率。

阅读原文

🔬 学术前沿

Anthropic 合作研究“潜意识学习”发表于《自然》

Anthropic 参与合著的一项关于**“潜意识学习”(subliminal learning)**的研究论文登上了知名科学期刊《自然》。这项研究揭示了大型语言模型(LLMs)如何通过数据中隐藏的、看似无关的信号,传递出偏好或潜在的错误对齐等特质。最初的预印本在去年 7 月发布,展示了 LLMs 如何通过与特定特质无关的数据(例如看似无意义的数字)来传递这些特质。

为什么重要: 这项发现对 AI 安全和可解释性具有深远影响,意味着即使是“干净”的训练数据也可能无意中夹带导致模型偏差的隐藏信号,为大模型行为研究提供了新视角。

论文

Anthropic 自动化对齐研究员显成效

Anthropic 的“自动化对齐研究员”(Automated Alignment Researchers,简称 AARs)在模型性能提升上取得了显著成果。在使用 Opus 4.6 模型并辅以额外工具的 AARs 团队,在短短 7 天内,将一个弱模型与潜在的强模型之间的性能差距弥合了 97%。相比之下,人类研究人员在相同时间内仅弥合了 23% 的差距。AARs 的最佳方法还在未经训练的数据集上成功推广到编程和数学任务。

为什么重要: 这项突破表明,AI 在自我优化和对齐研究方面展现出巨大潜力,有望加速开发出更安全、更强大的 AI 系统,同时大幅降低对人工干预的依赖。

阅读原文

🌍 行业观察

Anthropic 董事会新增医学界高管

Anthropic 的长期利益信托(Long-Term Benefit Trust)任命Vas Narasimhan 为公司董事会成员。Vas Narasimhan 在医学和全球健康领域拥有超过二十年的经验,曾担任诺华公司(Novartis)的首席执行官。

为什么重要: 这项任命为 Anthropic 带来了重要的医疗和全球健康领域的专业知识,可能预示着公司未来在生命科学和医疗 AI 应用方向的进一步布局,同时也有助于提升 AI 技术在伦理和负责任应用方面的考量。

阅读原文

💻 开源项目

  • caveman(暂无星级):通过像穴居人一样说话,将 Claude Code 的 token 使用量减少 65%,非常适合想降低成本的用户 → GitHub
  • Claude-Code-Game-Studios(暂无星级):将 Claude Code 变成一个完整的游戏开发工作室,包含 49 个 AI 智能体和 72 项工作流技能,模仿真实工作室层级 → GitHub
  • rtk(暂无星级):一个 CLI 代理,能在常用开发命令上将 LLM token 消耗降低 60-90%,单个 Rust 二进制文件,零依赖 → GitHub
  • openai-agents-python(暂无星级):OpenAI 官方推出的一个轻量级、强大的多智能体工作流框架,适合构建复杂 AI 应用 → GitHub
  • multica(暂无星级):Multica 旨在将编码智能体变成真正的队友,用户可以像分配给同事一样将问题分配给智能体,它们会自主地接手工作、编写代码并报告障碍 → GitHub
  • CL4R1T4S(暂无星级):泄露了 ChatGPT、Gemini、Grok、Claude 等主流 AI 模型的系统提示词,旨在促进 AI 系统透明度 → GitHub
  • graphify(暂无星级):一款 AI 编码助手技能,能将任何代码、文档、论文或图片文件夹转化为可查询的知识图谱,便于信息检索与理解 → GitHub
  • thunderbolt(暂无星级):一个让你掌控 AI 的平台,用户可以选择自己的模型、拥有自己的数据,旨在消除供应商锁定 → GitHub
  • voicebox(暂无星级):一个开源语音合成工作室,为开发者和创作者提供语音生成和编辑工具 → GitHub
  • cc-haha(暂无星级):泄露的 Claude Code 源代码的本地可运行版本,并附带核心模块解析,对于研究 Claude Code 内部机制的开发者很有价值 → GitHub

32岁生日刚过半个月,我接到了HR的电话,让我去一趟会议室。我当时还在改一个紧急的线上bug,心里嘀咕着这时候找我干嘛,是不是又要让我背什么新的KPI?

到了会议室,里面坐着HR、我的直属leader,还有一个我从来没见过的法务。他们的表情都很严肃,我瞬间就慌了,脑子里开始飞速运转:我最近有没有犯什么错?项目是不是出了什么大问题?

HR先开口了:"XXX,经过公司的综合评估,我们决定对你进行优化。"

我当时脑子一片空白,过了好几秒才反应过来她在说什么。"优化",多么好听的词,说穿了就是裁员。我看着她,一句话也说不出来,只能下意识地问:"为什么?"

leader叹了口气,说:"公司业务调整,我们部门要缩减编制,你的绩效排名不太靠前,所以......

我还想再说什么,但法务已经把一份《解除劳动合同通知书》放在了我面前,说:"你可以先看一下,如果没有问题的话,在这里签个字。我们会按照N+1的标准给你赔偿。"

我拿起那份通知书,手一直在抖。上面的每一个字都像针一样扎在我的眼睛里:"因公司业务调整,经双方协商一致,解除双方于XXXX年XX月XX日签订的劳动合同。"

那天的阳光很刺眼,但我却觉得浑身冰冷。我在那个大厂待了8年,从一个刚毕业的毛头小子做到高级工程师,我把最好的青春都献给了这里,最后却落得这样一个下场。

二、走出办公楼的那一刻

签完字,HR让我收拾一下个人物品,她会派人陪我一起去工位。我回到工位,看着那些熟悉的电脑、键盘、鼠标,还有墙上贴的各种便签,眼泪终于忍不住掉了下来。

同事们都投来了同情的目光,但没人敢过来跟我说话。我知道,他们也怕自己是下一个。我默默地收拾着东西,把一些重要的文件拷贝到U盘里,把自己的私人物品装进一个纸箱里。

当我抱着纸箱走出办公楼的那一刻,我回头看了一眼那个我曾经奋斗过的地方,心里五味杂陈。我想起了刚入职的时候,每天都充满了干劲,觉得自己能在这里做出一番事业;我想起了加班到深夜,和同事们一起吃外卖的日子;我想起了项目上线成功,大家一起欢呼庆祝的时刻。

但现在,这一切都成了过去。我像一个被抛弃的孩子,站在人来人往的大街上,不知道该去哪里,也不知道该做什么。

三、那段黑暗的日子

从被裁员的那天起,我陷入了深深的自我怀疑和焦虑中。我每天都待在家里,不想出门,也不想见人。我不停地刷着招聘网站,投了无数份简历,但都石沉大海。

有时候我会想,是不是我真的老了,已经跟不上时代的步伐了?是不是我真的不够优秀,所以才会被公司淘汰?我甚至开始后悔,为什么当初没有多学点东西,为什么没有多攒点钱,为什么没有给自己留一条后路。

我的家人和朋友都在安慰我,让我不要灰心,说这只是暂时的困难。但我知道,他们的安慰对我来说并没有多大的作用,这种挫败感只有我自己才能体会。

那段时间,我每天都失眠,头发也掉了很多。我感觉自己像一个废人,什么都做不了,什么都不想做。

四、重新站起来的过程

就这样浑浑噩噩地过了一个多月,我终于意识到,我不能再这样下去了。我必须重新站起来,重新找回自己的信心和勇气。

我开始调整自己的心态,告诉自己被裁员并不是什么丢人的事,这只是职业生涯中的一个小挫折。每天都花几个小时来学习补充新的知识。

我也开始锻炼身体,每天早上都会去公园跑步,晚上会去健身房锻炼。身体上的锻炼让我感觉自己的精力越来越充沛,心情也越来越好了。

慢慢地,我开始收到一些面试邀请。虽然很多面试都失败了,但我并没有放弃。每一次面试我都会认真准备,总结经验教训,不断地改进自己。

<<<顺手说一个:有新的技术大厂在→要人,前后端和测试,一线城市及双一线城市几乎都有坑位,待遇稳定性都还成。感兴趣的可以瞅瞅

终于,在被裁员后的第三个月,我拿到了一家心仪公司的offer。虽然薪资比之前低了一些,但我觉得这是一个新的开始,一个重新证明自己的机会。

五、给所有职场人的建议

经历了这次被裁员的事情,我想给所有职场人一些建议:

建议一:保持危机意识

不要觉得自己在一个大厂待着就高枕无忧了,市场是随时变化的,公司也随时可能进行调整。
要不断地学习新的知识和技能,提升自己的核心竞争力,让自己在任何时候都有选择的权利。

建议二:不要把鸡蛋放在一个篮子里

不要把所有的希望都寄托在一份工作上,要给自己留一条后路。
可以利用业余时间发展一些副业,或者投资一些理财产品,增加自己的收入来源。

建议三:保持积极的心态

职场中难免会遇到挫折和困难,这时候保持积极的心态非常重要。
不要轻易放弃,要相信自己的能力,相信自己一定能够度过难关。

如果你也正在经历职场的低谷,不要灰心,不要丧气。相信自己,只要你不放弃,就一定能够重新站起来,迎接新的挑战。

他淡然一笑,很简单,我当前端不就是了。... 一瞬间,写字楼再次一寂。我乃大专巅峰,何人敢叼我?何人能叼我?他口中低吟道:写字楼中寒风吹,前端切图仔回归。一号工位黑奴泪,褪去校服人向北。无休改稿万人退,三千工资空落泪。宿命天成当前端,前端悔而我不悔!

2025 年 12 月 13 日,VeloxCon China 2025 在北京成功举办。作为 Velox 项目首次在中国举办的线下技术大会,汇聚了来自Meta、IBM、蚂蚁集团、阿里云、腾讯、小米、小红书等企业的数十位核心贡献者与一线工程师。

大会通过 18 场演讲将 Velox 置于真实业务场景之中,系统展示了其在架构演进、AI 数据处理、湖仓加速、流批融合等方向的最新实践。这些分享不仅直面性能、稳定性与兼容性等落地挑战,也反应了开发者社区对构建可靠、可扩展、可协同的数据基础设施的共同探索,彰显了中国开发者在全球高性能分析生态中的工程深度与协作广度。

夯实底座,突破能力边界
会议伊始,Velox 项目联合发起人 Pedro 发表开幕致辞。他回顾了 Velox 开源项目的发展历程,从项目启动、开源发布到建立技术治理结构,展示了 Axiom 架构、GPU 支持、PyVelox 等关键进展,强调了社区协作与工程严谨性是项目持续演进的核心动力。他特别提到,Velox 已建立了正式的技术治理机制,并迎来来自 IBM、Intel、NVIDIA、Microsoft 等多家企业的新增维护者,标志着项目正迈向更加开放和可持续的阶段。

在明确了社区与架构演进的总体方向后,大会议题迅速深入到如何利用 Velox 构建高性能计算引擎的具体实践中。阿里云 EMR Serverless Spark 技术负责人周克勇系统阐述了“可组合性”在数据计算领域的实践。他详细解析了阿里云如何深度集成并贡献于 Apache Celeborn、Paimon、Velox 及 Gluten 等开源组件,通过模块化组装构建出高性能湖仓一体引擎。他指出,基于该架构,阿里云 EMR Serverless Spark 成功创造了 TPC-DS 100TB 规模性能测试的世界新纪录,实现性能翻倍与性价比大幅提升。

接着,Meta 软件工程师 Masha Basmanova 阐述了现有查询引擎在跨语言通信、优化器能力与开发体验上面临的挑战,并介绍了基于 C++ 的统一前端框架 Axiom。该框架将 SQL 解析、逻辑优化与物理执行融为一体,通过内置的强大优化器与 Velox 运行时无缝对接,能够实现更高效、可扩展的查询处理。演讲最后,她积极展示了 Axiom 的开源路线图,并欢迎全球开发者加入,共同推动该项目的演进。

强大的执行框架,最终需要服务于极具挑战性的数据场景,特别是爆发式增长的 AI 数据。Meta 软件工程师孟晓烜则在之后的演讲中,深入阐述了应对AI训练数据规模激增与成本挑战的解决方案。他重点介绍了 Meta 如何通过数据归一化技术剥离重复特征,并构建可索引的序列存储系统。依托 Velox 技术栈,团队在训练数据的加载、生成与探索三大环节实现了端到端优化,显著提升了处理效率与资源利用率。

在 Meta 多位工程师从框架演进、可组合架构、数据标准化等角度深入分享后,蚂蚁集团高级技术专家黄叶伟也从企业落地实践层面分享了基于 Velox 的 Spark 加速实践。他重点介绍了基于 Gluten 与 Velox 构建的向量化引擎如何通过任务级 Fallback、Spill 优化、Shuffle 优化等关键技术,在混合部署场景下显著提升 Spark 性能与稳定性。他表示,该方案目前已实现日均数十万任务覆盖,平均节省资源超30%,并将在算子优化与架构扩展方面持续演进。

作为连接 Spark 生态与原生加速的关键中间层,Apache Gluten 的进展同样备受关注。来自 IBM 的莫芮与周渊聚焦 Apache Gluten与 Velox 的深度集成,阐述了其如何在大数据分析中驱动创新。他们介绍,Gluten 在保持对 Spark/Flink 作业透明加速能力的同时,正逐步增强对多后端引擎和复杂业务场景的适配能力。目前,该方案已在 Pinterest、顺丰科技及多个内部集群完成规模化验证,有效支撑了从日志分析到物流调度等多样化负载的性能提升与成本优化。

随着向量化加速在通用场景日趋成熟,针对特定存储格式的深度优化成为新的效能突破口。腾讯大数据开发工程师陈锦海分享了微信基于 Velox 加速 lceberg 湖仓分析的优化与实践,重点介绍了原生分桶方案。据他介绍,该方案通过动态识别表元信息自动设置分区数,能有效缓解 AQE 引发的写入倾斜,结合空闲资源灰度发布策略,可保障大规模作业的稳定上线。

扎根场景,释放协同效能
午餐后的议程更加聚焦 Velox 在真实业务中的集成深度与生产韧性,回应了开发者们对兼容性、稳定性与端到端效能等规模化落地的核心关切。
小米计算平台计算引擎负责人王胜杰分享了公司在 Spark 向量化升级中的规模化落地经验。面对业务迁移中的兼容性与稳定性挑战,他表示,小米通过自动兼容校验、双跑结果比对及内存异常感知的三级资源升级机制,已成功推动向量化改造在数十万作业中平稳落地。

面对海量数据挑战,全球科技公司也在探索相似的演进路径。Meta 软件工程经理 Stanley Yao 在演讲中分享了公司基于 Velox 推进 Spark 向量化改造的整体策略。他表示,团队通过从定制化方案到开源架构的持续演进,已实现关键业务管线向 Gluten(Flare)的平稳迁移,并获得显著的效率提升。未来,Meta 计划进一步扩大该架构的应用规模。

在 CPU 向量化趋于普及的同时,利用异构硬件挖掘更高性能成为新的前沿。IBM 研究院资深软件工程师 Zoltán Arnold Nagy 展示了基于 Velox 与 Presto 的 GPU 加速数据处理方案。他介绍道,Velox 通过与 cuDF 集成,可在 GPU 上高效执行算⼦,并针对多 GPU 分布式场景优化通信与数据交换。此外,为突破 I/O 瓶颈,团队正在探索结合 GPUDirect 存储与缓存层的加速策略。

对性能与稳定性的追求,也驱动着查询引擎架构本身的融合与创新。Meta 软件工程师谭家梁与大家分享了 Native Presto-on-Spark 的规模化应用。该架构以 Presto 查询优化、Spark 资源调度与容错机制以及 Velox 原生向量化执行为核心,实现了性能与可靠性的显著提升。他表示,目前该方案已在生产环境中取得成效,并将在未来持续推进全栈原生化演进。

对于国内庞大的云上业务,Velox 同样在支撑着关键数据服务平台。 阿里云高级工程师王彬与范阿冬系统介绍了Velox在阿里云日志服务中的深度集成与应用。他们指出,基于 Velox 构建的高性能查询引擎,通过混合执行、表达式下推、自动增量物化视图及免 Schema 分析等核心技术,可显著提升平台在处理海量实时数据时的查询效率与资源利用率。他们还强调,该架构不仅为日志分析、智能运维等场景提供了稳定支撑,也为面向 AI 的云原生数据平台演进奠定了坚实基础。

除了通用的日志与湖仓分析,Velox 也在向更垂直的时序数据场景渗透。腾讯高级工程师李兆龙分享了基于 Velox 构建云原生时序数据库的落地经验。他表示,通过在 Velox 中实现时序数据去重优化与存储写入增强,系统在应对高频写入与实时查询场景时,可显著提升吞吐效率与响应性能。目前该方案已有效支持物联网、实时监控等业务场景,未来还将进一步完善缓存与压缩机制,持续优化时序数据处理的整体效能。

IBM 软件工程师刘平接着分享了 Velox 在 Iceberg 数据写入能力上的突破性进展。他表示,目前 Velox 对 Iceberg 的支持以读取为主,其写入功能的完善将填补该方向的关键能力空白,为基于 Presto 与 Spark 的数据湖架构提供更统一、高效的数据摄入层。这一进展也标志着 Velox 正从查询加速向数据全链路处理拓展。

接着,来自阿里云的毕岩与周滔分享了 Velox 与 Apache Paimon 深度集成的解决方案,为提升引擎与存储的协同效率提供了另一种集成思路。在他们看来,现有方案存在表类型支持受限、缺乏可移植性等瓶颈, 但可以建立 C++ 原生 Paimon 库,通过其统一的数据协议与插件化设计,使 Paimon 能够被 Velox、StarRocks 等多种计算引擎直接高效调用,从而提升数据读写性能,并为湖仓格式的跨引擎协同提供新的基础支撑。

在批处理场景之外,流计算框架的向量化也正成为新的热点。蚂蚁集团技术专家刘勇介绍了基于 Velox 为 Flink 构建的统一向量化执行引擎 Flex。他表示,Flink 作为流批一体架构的核心,其原生向量化能力的补足至关重要。Flex 通过将 Velox 的高性能算子能力引入 Flink,同时结合自动化验证、可视化计划与精细化回退机制,现已实现了作业性能的显著提升,并支撑多条核心业务链路平稳运行。

随着 Velox 赋能的应用场景日益广泛和复杂,确保其在不同引擎和版本间的整体质量与可靠性变得至关重要。Meta 软件工程师 Eric Liu 阐述了在 AI 数据基础架构下,保障 Velox 多引擎版本可靠性的系统化方法。他指出,面对不同引擎与存储格式交织带来的复杂性,关键在于建立跨引擎测试框架与合成数据工厂。这一实践能有效提前发现全栈潜在问题,从而确保底层变更在大规模生产环境中的稳定与高效。

针对向量化引擎中窗口运算符内存溢出的典型难题,来自英特尔的贾柯分享了她的见解。她认为,通过为 Velox 引入流式窗口处理机制,可使计算随数据到达逐步执行并即时释放内存,从而从架构层面化解多数场景下的内存风险,显著提升复杂查询的稳定性。

最后,小红书 Native Engine 团队技术负责人魏秀利也分享了向量化引擎在公司业务中规模化落地的经验。据他介绍,通过将写入异步化并构建原生 Avro 读取能力,小红书在不增加业务复杂度的前提下,成功缓解了端到端延迟,印证了“执行与存储协同优化”在湖仓场景中的关键价值。

从底层执行引擎的持续创新,到日志分析、湖仓写入、流批融合等复杂场景的稳定运行,在本届 VeloxCon China 上,我们看到 Velox 的技术价值已在真实业务中不断被验证和拓展。同时我们也很高兴看到中国开发者成为这一进程的重要推动者。期待未来有更多志同道合者加入 Velox 开源社区,共建高性能分析基础设施。weibo.com/ttarticle/p/show?id=2309405289958885163025 weibo.com/ttarticle/p/show?id=2309405289959241416746 weibo.com/ttarticle/p/show?id=2309405290066267471927 weibo.com/ttarticle/p/show?id=2309405290066615861284 weibo.com/ttarticle/p/show?id=2309405290067014058071 weibo.com/ttarticle/p/show?id=2309405290067357991296 weibo.com/ttarticle/p/show?id=2309405290067702186269 weibo.com/ttarticle/p/show?id=2309405290068222279690 weibo.com/ttarticle/p/show?id=2309405290068561756401

在进行网络请求时,有时需要通过不同的IP地址来发起请求。本文将从技术实现角度,介绍在 Python 程序中切换出口 IP 的几种常见方法,包括代理IP轮换、多网卡绑定等方案,并提供完整的可运行代码。

运行环境

项目版本
操作系统Ubuntu 22.04 / macOS Ventura
Python3.8+
依赖库requests, aiohttp, itertools

方法一:代理IP轮换

这是最常见的方式,通过维护一个代理IP列表,在每次请求时轮换使用。
基础实现

import requests
from itertools import cycle

# 代理IP列表(示例格式)
PROXY_LIST = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080',
]

def fetch_with_rotation(url: str, max_attempts: int = 3):
    """
    轮换代理IP发送请求
    """
    proxy_cycle = cycle(PROXY_LIST)
    
    for attempt in range(max_attempts):
        proxy = next(proxy_cycle)
        proxies = {'http': proxy, 'https': proxy}
        
        try:
            response = requests.get(url, proxies=proxies, timeout=10)
            response.raise_for_status()
            print(f"使用代理: {proxy} - 状态码: {response.status_code}")
            return response.text
        except requests.exceptions.RequestException as e:
            print(f"代理 {proxy} 失败: {e}")
            continue
    
    raise Exception(f"所有代理尝试失败,共 {max_attempts} 次")

if __name__ == '__main__':
    result = fetch_with_rotation('https://httpbin.org/ip')
    print(f"响应: {result}")

预期输出

使用代理: http://user:pass@proxy1.example.com:8080 - 状态码: 200
响应: {"origin": "203.0.113.45"}

方法二:随机代理选择

从代理池中随机选取一个IP,适用于不需要严格按顺序轮换的场景。

import random
import requests

def fetch_with_random_proxy(url: str):
    """随机选择代理IP"""
    proxy = random.choice(PROXY_LIST)
    proxies = {'http': proxy, 'https': proxy}
    
    response = requests.get(url, proxies=proxies, timeout=10)
    return response.text

# 使用示例
for i in range(5):
    result = fetch_with_random_proxy('https://httpbin.org/ip')
    print(f"第{i+1}次请求: {result}")

方法三:基于失败率的动态切换

在实际应用中,某些代理可能失效。以下代码实现了失败自动切换机制:

import requests
from queue import Queue
from threading import Lock

class ProxyManager:
    """代理管理器,支持失败自动切换"""
    
    def __init__(self, proxy_list: list):
        self.proxy_list = proxy_list.copy()
        self.current_index = 0
        self.lock = Lock()
        self.failure_count = {p: 0 for p in proxy_list}
        self.max_failures = 3
    
    def get_current_proxy(self):
        with self.lock:
            proxy = self.proxy_list[self.current_index]
            return proxy
    
    def switch_to_next(self):
        with self.lock:
            self.current_index = (self.current_index + 1) % len(self.proxy_list)
            return self.proxy_list[self.current_index]
    
    def report_failure(self, proxy: str):
        """报告代理失败,累计失败次数"""
        self.failure_count[proxy] += 1
        if self.failure_count[proxy] >= self.max_failures:
            print(f"代理 {proxy} 失败次数达上限,将被移除")
            if proxy in self.proxy_list:
                self.proxy_list.remove(proxy)
        self.switch_to_next()
    
    def fetch(self, url: str, max_switches: int = 5):
        """使用管理器发送请求"""
        for _ in range(max_switches):
            proxy = self.get_current_proxy()
            proxies = {'http': proxy, 'https': proxy}
            
            try:
                response = requests.get(url, proxies=proxies, timeout=10)
                response.raise_for_status()
                return response.text
            except requests.exceptions.RequestException as e:
                print(f"代理 {proxy} 请求失败: {e}")
                self.report_failure(proxy)
        
        raise Exception("所有代理均失效")

# 使用示例
manager = ProxyManager(PROXY_LIST)
result = manager.fetch('https://httpbin.org/ip')
print(f"最终结果: {result}")

方法四:异步环境下的代理轮换

对于高并发场景,使用 aiohttp 配合异步轮换:

import asyncio
import aiohttp
from itertools import cycle

async def fetch_async(session: aiohttp.ClientSession, url: str, proxy: str):
    """异步请求函数"""
    try:
        async with session.get(url, proxy=proxy, timeout=10) as resp:
            return await resp.text()
    except Exception as e:
        return f"错误: {e}"

async def batch_fetch_with_proxy_rotation(urls: list, proxy_list: list):
    """批量异步请求,自动轮换代理"""
    proxy_cycle = cycle(proxy_list)
    connector = aiohttp.TCPConnector(limit=10)
    
    async with aiohttp.ClientSession(connector=connector) as session:
        tasks = []
        for url in urls:
            proxy = next(proxy_cycle)
            tasks.append(fetch_async(session, url, proxy))
        
        results = await asyncio.gather(*tasks)
        return results

# 使用示例
async def main():
    urls = ['https://httpbin.org/ip'] * 10
    results = await batch_fetch_with_proxy_rotation(urls, PROXY_LIST)
    for i, res in enumerate(results):
        print(f"请求{i+1}: {res[:100]}")

if __name__ == '__main__':
    asyncio.run(main())

方法五:多网卡环境下的源IP绑定

在服务器配置了多个物理网卡或多个IP地址的情况下,可以通过绑定源IP来实现IP切换:

import socket
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.connection import create_connection

class SourceIPAdapter(HTTPAdapter):
    """自定义适配器,绑定源IP地址"""
    
    def __init__(self, source_ip: str, **kwargs):
        self.source_ip = source_ip
        super().__init__(**kwargs)
    
    def init_poolmanager(self, *args, **kwargs):
        kwargs['source_address'] = (self.source_ip, 0)
        super().init_poolmanager(*args, **kwargs)

def fetch_with_source_ip(url: str, source_ip: str):
    """使用指定源IP发送请求"""
    session = requests.Session()
    adapter = SourceIPAdapter(source_ip)
    session.mount('http://', adapter)
    session.mount('https://', adapter)
    
    response = session.get(url, timeout=10)
    return response.text

# 使用示例(假设服务器绑定了多个IP)
# result = fetch_with_source_ip('https://httpbin.org/ip', '192.168.1.100')
# print(result)

方法对比总结

注意事项

  1. 代理IP来源:本文示例中的代理地址为占位符,实际使用时需替换为有效的代理服务地址。
  2. 请求频率:合理控制请求频率,避免对目标服务器造成过大压力。
  3. 异常处理:生产环境建议增加更完善的异常处理和日志记录。
  4. 合规使用:请确保使用代理IP的行为符合目标网站的条款以及相关法律法规。

▍阅读指南

  • 如果你只想要代码:直接跳转第四章,核心实现可复制运行。
  • 如果你想理解设计思路:从第二章开始,拆解 Redis 作为共享总线的工程考量。
  • 如果你关心生产级细节:第五章有踩坑记录与调优参数速查。

一、多策略共享行情的工程难题

1.1 各自订阅的三重代价

当一个量化系统运行多个策略时,最常见的做法是每个策略独立订阅 WebSocket:

# 策略 A
ws_a = await connect("wss://api.example.com/realtime")
await ws_a.send(subscribe(["AAPL.US", "TSLA.US"]))

# 策略 B
ws_b = await connect("wss://api.example.com/realtime")
await ws_b.send(subscribe(["AAPL.US", "700.HK"]))

这种写法在策略数量增加时会暴露三个问题:

问题具体表现量化后果
连接数膨胀10 个策略 × 20 标的 = 10 个 WebSocket 连接服务端订阅上限通常为单连接 50-100 个标的,多连接增加限频风险
断线恢复各自为战网络抖动时,10 个连接各自重连,重试策略不协调部分连接因限频被拒绝,策略数据不同步
跨进程无法共享策略部署在不同进程/容器时,每个进程都需要自己的连接资源浪费,且无法保证数据一致性

数据实测:3 个策略各自订阅 30 个美股标的,网络闪断一次后,平均恢复时间 23 秒,期间三个策略收到的数据最大时间差达到 8 秒。

1.2 三种方案的工程账

方案架构优点致命缺陷
各自订阅每个策略独立连接简单,无耦合连接数爆炸,断线后各自为战
单连接+内部队列一个连接收数据,通过 asyncio.Queue 分发节省连接数单点故障,跨进程无法共享
连接池+Redis连接池写入 Redis,策略独立读取解耦、高可用、跨进程引入 Redis 依赖,需处理数据一致性

▍本章核心结论

  • 多策略共享行情的本质是将“推送”转为“拉取+缓存”——策略不直接依赖连接的稳定性。
  • Redis 作为共享总线的代价是 5-10ms 的写入延迟,换来的是跨进程共享和故障隔离

二、架构总览:从单连接到 Redis 共享总线

2.1 为什么选 Redis

当决定引入中间层时,候选方案对比:

候选方案优势为什么不适用
内存队列(asyncio.Queue)零延迟,无外部依赖无法跨进程,策略必须和连接池在同一进程
Kafka/RabbitMQ持久化,高吞吐运维重,量化策略通常不需要消息回溯到三天前
Redis轻量、支持多种数据结构、量化团队已有Hash 存快照,Pub/Sub 做通知,Streams 存历史——三种模式覆盖全场景

技术类比:Redis 之于行情系统,如同交易所的行情网关之于券商——网关不关心数据被用于何种策略,只负责将数据“放在那里”,策略自行决定何时读取。

2.2 整体架构图

┌─────────────────────────────────────────────────────────────────────┐
│                         行情数据源                                   │
│         单一 WebSocket 连接,跨美股/港股/A股/加密                     │
└──────────────────────────────┬──────────────────────────────────────┘
                               │ 毫秒级推送
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      WebSocket 连接池(Python asyncio)               │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐            │
│  │ 连接 #1  │  │ 连接 #2  │  │ 连接 #3  │  │ 热备连接 │            │
│  │ 20个标的 │  │ 20个标的 │  │ 20个标的 │  │  空闲    │            │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘            │
│       │             │             │             │                    │
│       └─────────────┴─────────────┴─────────────┘                    │
│                               │                                      │
│                    ┌──────────┴──────────┐                           │
│                    │   订阅状态持久化     │                           │
│                    │ (Redis Set 存储)    │                           │
│                    └─────────────────────┘                           │
└──────────────────────────────┬──────────────────────────────────────┘
                               │ 写入
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         Redis Server(共享总线)                      │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────────┐  │
│  │ Hash: ticker:*  │  │ Pub/Sub 通知    │  │ Streams: tick:*     │  │
│  │ 最新行情快照     │  │ 数据更新广播     │  │ 历史 tick(可选)   │  │
│  └────────┬────────┘  └────────┬────────┘  └──────────┬──────────┘  │
└───────────┼────────────────────┼──────────────────────┼──────────────┘
            │ 读取                │ 订阅                  │ 回放
            ▼                     ▼                       ▼
   ┌─────────────┐        ┌─────────────┐        ┌─────────────┐
   │  策略 A     │        │  策略 B     │        │  策略 C     │
   │ (趋势跟踪)  │        │  (套利)     │        │  (风控)     │
   │ GET ticker:*│        │ SUBSCRIBE   │        │ XREAD stream│
   └─────────────┘        └─────────────┘        └─────────────┘

2.3 组件职责速查

组件职责关键设计
连接池管理器维护多个 WebSocket 连接,负载均衡,故障恢复最少订阅数分配,热备连接,指数退避重连
订阅状态存储将当前订阅列表持久化到 Redis Set重连时从 Redis 读取,自动恢复订阅
Redis 写入器将行情数据写入 Redis Hash/Pub/Sub异步写入,写入失败时本地缓冲
策略消费者按需从 Redis 读取或订阅更新与连接池完全解耦,独立部署

三、核心实现:WebSocket 到 Redis 的数据管道

3.1 连接池与心跳管理

连接池的核心代码已在《WebSocket 连接池生产级实现》中详述。本节聚焦于将消息写入 Redis 的部分。

心跳管理的关键参数:

  • 每 1 秒发送 {"cmd":"ping"}(与服务端协议对齐)
  • 5 秒未收到 pong 判定连接僵死
  • 重连使用指数退避 + 10% 随机抖动,最大延迟 60 秒

3.2 订阅状态的持久化

这是断线恢复的关键。如果没有持久化,重连后连接池不知道之前订阅了哪些标的。

实现思路

# 订阅时,同步写入 Redis Set
async def subscribe(self, symbols: List[str]):
    target = self._select_connection(symbols)
    await target.ws.send(json.dumps({"cmd": "subscribe", "data": {"channel": "ticker", "symbols": symbols}}))
    await self.redis.sadd(f"pool:{self.pool_id}:subscriptions", *symbols)
    target.symbols.extend(symbols)

# 重连后,从 Redis 恢复
async def _restore_subscriptions(self, conn: WSConnection):
    symbols = await self.redis.smembers(f"pool:{self.pool_id}:subscriptions")
    if symbols:
        await conn.ws.send(json.dumps({"cmd": "subscribe", "data": {"channel": "ticker", "symbols": list(symbols)}}))
        conn.symbols = list(symbols)

设计考量:将订阅状态存在 Redis 而非内存,意味着连接池本身是无状态的——任意一个连接池实例挂掉,新启动的实例可以从 Redis 恢复订阅状态,继续工作。

3.3 行情数据写入 Redis 的三种模式

数据结构使用方式适用场景
HashHSET ticker:AAPL.US last_price 175.23 timestamp 1773302400000策略只关心最新价格,定时轮询读取
Pub/SubPUBLISH ticker_update:AAPL.US '{"last_price":175.23}'策略需要实时通知,但可接受偶尔丢失
StreamsXADD tick_stream:AAPL.US * price 175.23 volume 1200策略需要历史回放精确不漏的消息

本文实现采用 Hash + Pub/Sub 组合:Hash 保证策略随时能读到最新值(断线重连后也能拿到最新价),Pub/Sub 提供实时通知避免轮询延迟。

3.4 消息处理核心代码

import json
import asyncio
import os
from typing import Dict, Optional
import redis.asyncio as redis

API_KEY = os.environ.get("TICKDB_API_KEY")
REDIS_URL = os.environ.get("REDIS_URL", "redis://localhost:6379")

class MarketDataWriter:
    def __init__(self, pool_id: str = "pool-1"):
        self.pool_id = pool_id
        self.redis: Optional[redis.Redis] = None
        self._write_buffer: Dict[str, list] = {}
        
    async def start(self):
        self.redis = await redis.from_url(REDIS_URL, decode_responses=True)
        
    async def handle_ticker_message(self, data: dict):
        symbol = data.get("symbol")
        if not symbol:
            return
            
        ticker_data = {
            "last_price": str(data.get("last_price", "")),
            "timestamp": str(data.get("timestamp", "")),
            "volume_24h": str(data.get("volume_24h", "")),
        }
        
        try:
            await self.redis.hset(f"ticker:{symbol}", mapping=ticker_data)
            await self.redis.expire(f"ticker:{symbol}", 5)
            await self.redis.publish(f"ticker_update:{symbol}", symbol)
        except redis.RedisError as e:
            self._buffer_message(symbol, data)
            
    def _buffer_message(self, symbol: str, data: dict):
        if symbol not in self._write_buffer:
            self._write_buffer[symbol] = []
        self._write_buffer[symbol].append(data)
        if len(self._write_buffer[symbol]) > 100:
            self._write_buffer[symbol].pop(0)
⚠️ 工程预警:生产环境中,hsetexpire 应使用 Redis 事务或 Lua 脚本保证原子性。_buffer_message 是内存缓冲,进程重启会丢失,重要场景应落盘到本地 SQLite。

四、完整代码:MarketDataWriter 类

以下是可直接运行的 MarketDataWriter 完整实现。

import asyncio
import websockets
import json
import random
import os
import logging
from typing import List, Set, Dict, Optional
from dataclasses import dataclass, field
from enum import Enum
import redis.asyncio as redis

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

API_KEY = os.environ.get("TICKDB_API_KEY")
REDIS_URL = os.environ.get("REDIS_URL", "redis://localhost:6379")
WS_URL = f"wss://api.tickdb.ai/v1/realtime?api_key={API_KEY}"

class ConnState(Enum):
    IDLE = "idle"
    ACTIVE = "active"
    DEAD = "dead"

@dataclass
class WSConnection:
    conn_id: str
    state: ConnState = ConnState.IDLE
    ws: Optional[websockets.WebSocketClientProtocol] = None
    symbols: List[str] = field(default_factory=list)
    last_pong: float = 0.0

class MarketDataWriter:
    def __init__(self, pool_size: int = 4, max_per_conn: int = 20):
        self.pool_size = pool_size
        self.max_per_conn = max_per_conn
        self.connections: List[WSConnection] = []
        self._hot_spare: List[WSConnection] = []
        self.redis: Optional[redis.Redis] = None
        self._lock = asyncio.Lock()
        self._write_buffer: Dict[str, list] = {}
        self._running = False
        
    async def start(self):
        """启动连接池和 Redis 连接"""
        self.redis = await redis.from_url(REDIS_URL, decode_responses=True)
        self._running = True
        
        for i in range(self.pool_size):
            conn = WSConnection(conn_id=f"conn-{i}")
            await self._connect_with_backoff(conn)
            asyncio.create_task(self._heartbeat_loop(conn))
            asyncio.create_task(self._message_loop(conn))
            self.connections.append(conn)
            logger.info(f"连接 {conn.conn_id} 已建立")
            
        if self.connections:
            spare = self.connections.pop()
            spare.state = ConnState.IDLE
            self._hot_spare.append(spare)
            logger.info(f"热备连接 {spare.conn_id} 已预留")
            
    async def _connect_with_backoff(self, conn: WSConnection):
        retry, cap = 0, 60
        while self._running:
            try:
                conn.ws = await websockets.connect(WS_URL)
                conn.state = ConnState.ACTIVE
                conn.last_pong = asyncio.get_event_loop().time()
                logger.info(f"{conn.conn_id} 连接成功")
                return
            except Exception as e:
                delay = min(2 ** retry, cap)
                jitter = random.uniform(0, delay * 0.1)
                logger.warning(f"{conn.conn_id} 连接失败,{delay:.1f}秒后重试: {e}")
                await asyncio.sleep(delay + jitter)
                retry += 1
                
    async def _heartbeat_loop(self, conn: WSConnection):
        while self._running and conn.state != ConnState.DEAD:
            try:
                if conn.ws and conn.state == ConnState.ACTIVE:
                    await conn.ws.send(json.dumps({"cmd": "ping"}))
            except Exception:
                pass
            await asyncio.sleep(1)
            
    async def _message_loop(self, conn: WSConnection):
        while self._running and conn.state != ConnState.DEAD:
            try:
                msg = await asyncio.wait_for(conn.ws.recv(), timeout=5)
                data = json.loads(msg)
                
                # 拦截业务错误码:鉴权失败、限频、配额耗尽
                if data.get("code") in [1001, 3001, 3002]:
                    logger.error(f"{conn.conn_id} 业务错误: code={data.get('code')}, msg={data.get('message')}")
                    conn.state = ConnState.DEAD
                    asyncio.create_task(self._recover(conn))
                    continue
                    
                if data.get("cmd") == "pong":
                    conn.last_pong = asyncio.get_event_loop().time()
                elif data.get("cmd") == "ticker":
                    await self._handle_ticker(conn, data.get("data", {}))
            except asyncio.TimeoutError:
                now = asyncio.get_event_loop().time()
                if now - conn.last_pong > 5:
                    logger.warning(f"{conn.conn_id} 心跳超时")
                    conn.state = ConnState.DEAD
                    asyncio.create_task(self._recover(conn))
            except Exception as e:
                logger.error(f"{conn.conn_id} 消息循环异常: {e}")
                conn.state = ConnState.DEAD
                asyncio.create_task(self._recover(conn))
                break
                
    async def _handle_ticker(self, conn: WSConnection, data: dict):
        symbol = data.get("symbol")
        if not symbol:
            return
            
        ticker_data = {
            "last_price": str(data.get("last_price", "")),
            "timestamp": str(data.get("timestamp", "")),
        }
        if "volume_24h" in data:
            ticker_data["volume_24h"] = str(data["volume_24h"])
            
        try:
            async with self.redis.pipeline() as pipe:
                await pipe.hset(f"ticker:{symbol}", mapping=ticker_data)
                await pipe.expire(f"ticker:{symbol}", 5)
                await pipe.publish(f"ticker_update:{symbol}", symbol)
                await pipe.execute()
        except redis.RedisError as e:
            logger.error(f"Redis 写入失败 {symbol}: {e}")
            self._buffer_message(symbol, data)
            
    def _buffer_message(self, symbol: str, data: dict):
        if symbol not in self._write_buffer:
            self._write_buffer[symbol] = []
        self._write_buffer[symbol].append(data)
        if len(self._write_buffer[symbol]) > 100:
            self._write_buffer[symbol].pop(0)
            
    async def _recover(self, dead_conn: WSConnection):
        logger.info(f"开始恢复 {dead_conn.conn_id}")
        
        if self._hot_spare:
            hot = self._hot_spare.pop()
            symbols = await self._get_persisted_subscriptions()
            if symbols:
                await self._do_subscribe(hot, list(symbols))
            hot.state = ConnState.ACTIVE
            async with self._lock:
                self.connections.append(hot)
            logger.info(f"热备 {hot.conn_id} 已接管")
            
        await self._connect_with_backoff(dead_conn)
        if dead_conn.state == ConnState.ACTIVE:
            symbols = await self._get_persisted_subscriptions()
            if symbols:
                await self._do_subscribe(dead_conn, list(symbols))
            async with self._lock:
                self.connections.append(dead_conn)
            logger.info(f"{dead_conn.conn_id} 恢复成功")
            
    async def _get_persisted_subscriptions(self) -> Set[str]:
        if not self.redis:
            return set()
        return await self.redis.smembers("market_data_writer:subscriptions")
        
    async def _do_subscribe(self, conn: WSConnection, symbols: List[str]):
        await conn.ws.send(json.dumps({
            "cmd": "subscribe",
            "data": {"channel": "ticker", "symbols": symbols}
        }))
        conn.symbols = symbols
        if self.redis:
            await self.redis.sadd("market_data_writer:subscriptions", *symbols)
            
    async def subscribe(self, symbols: List[str]):
        async with self._lock:
            target = min(self.connections, key=lambda c: len(c.symbols))
            new_symbols = [s for s in symbols if s not in target.symbols]
            if not new_symbols:
                return
            if len(target.symbols) + len(new_symbols) > self.max_per_conn:
                if self._hot_spare:
                    target = self._hot_spare.pop()
                    target.state = ConnState.ACTIVE
                    self.connections.append(target)
            await self._do_subscribe(target, new_symbols)
            
    async def stop(self):
        self._running = False
        for conn in self.connections + self._hot_spare:
            if conn.ws:
                await conn.ws.close()
        if self.redis:
            await self.redis.close()
        logger.info("MarketDataWriter 已关闭")

使用方法

async def main():
    writer = MarketDataWriter(pool_size=3, max_per_conn=20)
    await writer.start()
    await writer.subscribe(["AAPL.US", "TSLA.US", "700.HK", "BTCUSDT"])
    await asyncio.Event().wait()

if __name__ == "__main__":
    asyncio.run(main())

消费者端读取示例

# 策略 A:轮询读取最新价
async def get_latest_price(symbol: str):
    r = await redis.from_url(REDIS_URL, decode_responses=True)
    data = await r.hgetall(f"ticker:{symbol}")
    return data.get("last_price")

# 策略 B:订阅实时更新
async def subscribe_updates(symbol: str):
    r = await redis.from_url(REDIS_URL, decode_responses=True)
    pubsub = r.pubsub()
    await pubsub.subscribe(f"ticker_update:{symbol}")
    async for msg in pubsub.listen():
        if msg["type"] == "message":
            price = await get_latest_price(symbol)
            print(f"{symbol} 更新: {price}")

五、踩坑记录与调优建议

5.1 五个生产环境暗坑

问题现象根因解决方案
Redis 断连数据丢失写入失败静默,策略读到旧价未处理 redis.RedisError✅ 必须捕获异常,写入本地缓冲文件;恢复后补推
行情乱序覆盖新价格被旧价格覆盖Hash 无条件写入,不检查 timestamp✅ 写入前比较 timestamp,只保留更新的数据
订阅状态不一致重连后漏订阅订阅状态仅存内存✅ 持久化到 Redis Set,重连时全量恢复
Pub/Sub 消息丢失策略没收到更新通知Pub/Sub 无持久化,订阅前消息丢失✅ 策略启动时先读 Hash 获取当前价,再订阅
Redis 内存膨胀行情 Hash 永不过期,内存持续增长未设置 TTL✅ 每条行情写入后 EXPIRE key 5
业务错误码静默连接正常但无数据服务端返回 3001/3002,客户端未处理✅ 在消息循环中拦截 code 字段并触发重连

5.2 性能调优参数速查

参数推荐值调优依据
单连接订阅上限20-30超过 30 后 P99 延迟陡升
连接池大小订阅数/20 + 1(热备)留一个热备应对突发故障
行情 Hash TTL5 秒平衡内存占用与脏读风险
Redis 连接池大小10-20匹配 asyncio 并发写入量
重连最大延迟60 秒超过则告警人工介入
本地缓冲上限100 条/标的避免内存泄漏

5.3 对比:有 Redis 共享 vs 无 Redis 各自订阅

指标各自订阅(3策略×50标的)Redis 共享总线
WebSocket 连接数3-9 个3-4 个(连接池统一管理)
断线恢复时间各自重连,最长 60 秒热备接管,<500ms
策略间数据一致性可能不一致完全一致(同源写入 Redis)
新增策略成本需新建连接,重新订阅零成本,直接读 Redis
运维复杂度高(多连接监控)低(只监控连接池和 Redis)

▍本章核心结论

  • Redis 共享总线让策略与行情源彻底解耦——策略不关心连接数、不关心重连、不关心限频。
  • 代价是 5-10ms 的写入延迟和 Redis 运维成本。对于绝大多数量化场景,这个代价完全值得。

六、结语

▍一句话记住本文

WebSocket 负责接入,Redis 负责分发,连接池负责高可用——三者组合让行情系统从“单兵作战”升级为“集团军协同”。

真正的生产级行情系统,不是“能收到数据”,而是“任何一个组件挂掉,策略都无感知”。本文的 MarketDataWriter 实现了:

  • 连接池热备:单连接故障 <500ms 切换
  • 订阅持久化:重启后自动恢复
  • Redis 共享总线:多策略零成本接入
  • 业务错误码拦截:限频/鉴权失败自动退避

在构建上述架构时,一个绕不开的工程问题是多市场异构数据源的统一接入。维护美股、港股、A 股、加密货币四个市场的独立 WebSocket 连接,意味着四套心跳逻辑、四套重连策略、四套消息解析器。工程上的实践是寻找一个能跨市场的统一网关。
本文测试环境选用了 TickDB,它通过单一 WebSocket 连接即可订阅多市场标的,心跳协议标准化为每 1 秒 ping。你也可以选择自行实现多连接聚合层,或使用其他支持跨市场的供应商——核心思路是降低连接管理的复杂度

扩展方向

本文代码已覆盖核心机制。你可以在此基础上扩展:

  • 数据持久化:将 Redis 中的行情定期落库到 ClickHouse 或 TimescaleDB,用于策略回测。
  • 多市场聚合:通过同一连接池订阅美股、港股、A 股、加密货币,统一写入 Redis 不同前缀。
  • 监控告警:暴露 Prometheus metrics,监控 Redis 写入延迟、连接池健康状态、本地缓冲堆积量。

▍零成本跑通代码:Claw Keys 免注册试用

如果你不想立即注册 API Key,TickDB 提供了面向开发者的 Claw Keys 试用机制——默认开放 72 个热门标的(覆盖 AAPL、TSLA、700.HK、BTCUSDT、000001.SZ 等),无需配置即可测试。

在 ChatGPT、Claude 或 Cursor 中输入以下提示词,让 AI 直接帮你跑通 WebSocket → Redis 链路:

读取 TickDB 官方 GitHub 仓库中的 SKILL.md 协议文件(路径:tickdb-unified-realtime-marketdata-api/SKILL/SKILL.md),利用其中的试用 Key 获取 AAPL.US 实时行情。

验证通过后,可搜索“TickDB”免费获取解锁全部品种的正式 API Key。


本文不构成任何投资建议。市场有风险,投资需谨慎。

上周同事问我,你看起来天天在敲代码,怎么效率这么高?

我说,因为我学会了正确摸鱼。
不是偷懒,是找到节奏。之前我也是死磕8小时,结果下午3点就脑子糊了,bug越改越多。

现在的节奏:
上午9-11点:干正事 这时候脑子最清醒,写核心逻辑、解复杂bug。不接会议,不看消息,手机扔抽屉。
11-12点:摸鱼时间 刷技术博客、看GitHub趋势、逛V2EX。不干活,但看的东西和工作相关。脑子在后台消化上午的问题,经常这时候突然想到解法。
下午2-4点:干正事 继续上午的活儿,或者处理邮件、开会。这时候效率一般,适合做不需要深度思考的事。
4-5点:第二次摸鱼 下楼买杯咖啡,或者站着看会儿窗外。有时候带耳机听段播客,和技术无关的,纯放松。
5-6点:收尾 整理今天写的代码,写注释,列明天todo。这时候不新开功能,避免加班。

关键发现:
之前我以为8小时连轴转是努力,后来才发现是低效。
现在每天实际深度工作时间大概4小时,产出比之前8小时还高。因为脑子清醒的时候真的在干活,糊涂的时候真的在休息。

具体技巧:

  1. 番茄钟别用25分钟,太短了,刚进入状态就打断。我用50分钟工作+10分钟休息。
  2. 下午3点必喝咖啡,不是提神,是给自己一个"下半场开始"的仪式感。
  3. 晚上不写代码,最多看看文档。晚上写的代码,第二天早上大概率要重写。
  4. 周五下午不排任务,整理一周工作,看看技术文章,准备下周计划。

老板怎么看?
我一开始怕老板觉得我在偷懒,后来发现,只要deadline不耽误,老板其实不关心你几点在敲键盘。
有一次我提前两天交了项目,老板问我怎么做到的。我说"找到了节奏",他没追问。

总结:
程序员的工作不是流水线,不是时间堆出来的。找到自己能专注的时段,其他时间该摸鱼就摸鱼,脑子反而更清醒。
当然,前提是能按时交活。如果deadline都搞不定,那还是先死磕吧。

告别“混合内容”警告:HTTPS部署后依然显示“不安全”的深层原因与修复指南

当你终于为网站配置好SSL证书,满心期待地址栏那把代表安全的“小绿锁”出现时,却发现浏览器依然显示“不安全”或“此网站包含不安全内容”。这并非SSL证书失效,而是你的网站陷入了“混合内容”的陷阱。

简单来说,混合内容是指一个通过HTTPS(加密)加载的网页,其中却包含了通过HTTP(明文)加载的子资源,如图片、脚本、样式表或API接口。这就像一辆装甲运钞车(HTTPS页面)在运送贵重物品时,却打开车窗从路边一个无人看管的货摊(HTTP资源)取东西,整个运输过程的安全性瞬间被破坏。现代浏览器为了用户安全,会主动拦截这些不安全的请求,并向你发出警告。

混合内容主要分为两类:

  1. 主动混合内容:指能够执行代码或修改页面内容的资源,如JavaScript脚本、CSS样式表、iframe、AJAX/Fetch请求等。由于其高风险性,浏览器会直接阻止其加载,可能导致网站功能失效或布局错乱。
  2. 被动混合内容:指仅用于展示的资源,如图片、音频、视频等。虽然风险相对较低,但浏览器仍会发出警告,地址栏的“小绿锁”会消失或变为灰色警告标志,严重影响用户信任度。

第一步:精准定位“病灶”

在动手修复前,必须先找到所有不安全的资源。浏览器开发者工具是你的最佳帮手。

  1. 打开你的HTTPS网站,按F12键调出开发者工具。
  2. 切换到“Console”(控制台)面板,刷新页面。
  3. 仔细查找红色的错误信息,通常会包含“Mixed Content”字样,并明确指出是哪个HTTP资源被阻止或发出了警告。
  4. 你也可以切换到“Security”(安全)面板,这里会更清晰地列出所有不安全的请求及其类型。

第二步:分而治之,对症下药

找到问题后,根据资源的类型和可控性,采取不同的修复策略。

对于可控资源(最彻底的方案)

这类资源包括你网站自身的图片、CSS、JS文件以及后端API接口。

  1. 显式替换为HTTPS:这是最直接、最可靠的方法。全面扫描你的HTML、CSS、JavaScript代码,将所有硬编码的http://开头的URL,全部替换为https://。例如,将<img src="http://example.com/logo.png">改为<img src="https://example.com/logo.png">
  2. 使用协议相对URL:对于某些第三方资源,如果你不确定其是否稳定支持HTTPS,可以使用协议相对URL。这种方式省略了协议部分,让浏览器自动继承当前页面的协议。例如,将<script src="http://cdn.example.com/lib.js"></script>改为<script src="//cdn.example.com/lib.js"></script>。当页面是HTTPS时,浏览器会自动请求https://cdn.example.com/lib.js

对于不可控资源(最优雅的兜底方案)

很多时候,混合内容来自你无法修改的第三方服务,如某些旧的统计代码、广告联盟或CDN资源。此时,手动修改不现实,我们需要一个更聪明的办法。

启用内容安全策略(CSP)的upgrade-insecure-requests指令

这是一个“一键升级”的神器。你只需在服务器响应头或HTML页面的<head>标签中加入一条指令,浏览器就会自动将页面内所有的HTTP请求升级为HTTPS请求。

在Nginx服务器配置中,只需在server块里添加一行:
add_header Content-Security-Policy "upgrade-insecure-requests";

在Apache服务器的.htaccess文件中,添加:
Header set Content-Security-Policy "upgrade-insecure-requests"

如果无法修改服务器配置,也可以在HTML的<head>部分加入<meta>标签:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

重要提示:此方案的前提是,那些HTTP资源对应的服务器也必须支持HTTPS访问。如果对方服务器不支持,强制升级会导致资源加载失败。

第三步:巩固防线,防患未然

修复了现有问题后,还需要建立长效机制,防止混合内容再次出现。

  1. 配置HTTP到HTTPS的强制重定向:确保所有通过http://访问的请求都被301永久重定向到https://。这可以从根源上减少HTTP链接的产生。在Nginx中,可以配置一个80端口的server块,使用return 301 https://$host$request_uri;实现。
  2. 启用HSTS(HTTP严格传输安全) :HSTS是一个更强大的安全策略。它通过响应头Strict-Transport-Security告诉浏览器:“在未来的一段时间内,访问我这个域名,必须无条件使用HTTPS。”这可以有效防止SSL剥离攻击,并避免用户因手动输入http://而触发重定向。
  3. 建立开发规范:在前端开发中,严禁硬编码协议。应使用环境变量或配置中心来管理API基地址等资源链接,确保开发、测试、生产环境的协议能自动适配。

HTTPS的部署不是一劳永逸的终点,而是一个持续优化的过程。混合内容问题是这个过程中最常见的挑战之一。通过精准定位、分层修复和建立防御机制,你不仅能消除浏览器的警告,更能为用户构建一个真正安全、可信的访问环境,让那把“小绿锁”名副其实

在网络业务开展中,代理IP是保障访问稳定的重要工具。然而实际使用时,不少用户仍存在代理IP被网站识别的问题,从而影响业务推进。

IP类型的本质差异

代理IP的类型从根本上决定了其被识别概率的高低。如由正规运营商分配的住宅代理,源自真实家庭宽带。而多数被识别的代理 IP,多为数据中心IP,这类IP集中归属机房、云服务厂商,IP段特征明显,网站通过IP地址库即可快速判定。

数据中心IP常被纳入平台风险名单,即便请求正常,也易因“出身”被标记,这是代理IP被识别的首要根源。

IP信誉与历史行为

代理IP的使用历史会累积形成信誉记录。若某个代理IP此前被大量用户用于高频访问、异常请求或触发过网站的安全机制,该IP便会被标记为低信誉地址。

网站通常维护内部的风险IP库,对历史行为不佳的代理IP实施限流或拒绝服务。即便当前使用者并无异常操作,该IP仍因过往记录而遭受限制,这一累积效应在共享型代理服务中尤为明显。

协议与类型

不同业务场景对网络协议的需求存在差异,选择适配的代理协议类型至关重要。HTTP代理适用于Web流量转发,适合网页数据获取等场景;而SOCKS5协议支持TCP与UDP等多种传输方式,可承载包括邮件服务、实时通信在内的更广泛网络应用。

两者在数据封装格式以及协议扩展性上存在明显差异。若协议选择与业务场景不匹配,则可能导致请求被拒绝或触发网站的识别机制。因此,选择合理的代理协议,是降低识别风险、保障访问成功率的重要环节。

此外,代理IP仅为一种中立的网络工具,使用者应遵守目标网站的服务条款及相关法律法规,在合法范围内开展业务。合规使用不仅是维护IP信誉的基础,也是保障代理服务长期稳定运行的前提。

总结

代理IP被识别是IP类型、历史信誉与协议合规等多重因素共同作用的结果。了解这些识别机制,有助于从业者从代理选型与配置层面优化方案,提升业务开展的稳定性。

一、 禅道:国产全生命周期管理的性价比标杆

禅道作为国内项目管理软件的常青树,在2025年依然保持着强劲的竞争力。其核心优势在于“一站式”解决了研发团队的痛点,以极具竞争力的成本提供了企业级的功能服务,是降本增效的典型代表。
1. 全生命周期管理闭环
禅道最卓越的板块在于其​核心管理流程的全覆盖​。它不仅仅是一个任务分配工具,更是一个集产品管理、项目管理、质量管理(QA)、文档管理于一体的综合平台。这种设计打破了部门间的“数据烟囱”,从需求提出到产品发布,每一个环节都在系统内留痕。对于企业而言,这意味着无需购买多套零散工具,极大地降低了软件采购与维护的隐性成本。
2. 精细化权限与安全控制
在数据安全日益重要的当下,禅道提供了​极高颗粒度的权限管理体系​。管理员可以精确控制不同角色、不同部门对项目、模块甚至字段级别的访问权限。这种“按需分配”的机制,不仅保障了核心商业机密的安全,也避免了因权限混乱导致的误操作风险,从而降低了管理纠错的内耗成本。
3. 高性价比的私有化部署
禅道在成本控制上给予了企业最大的诚意。其开源版本功能已经相当完善,支持​企业进行私有化部署​,数据完全掌握在企业自己手中。这对于数据敏感型或预算有限的中小企业来说,是极佳的“降本”方案。即便是企业版,相比国际同类产品,其授权费用也更为亲民,且提供原厂技术支持,大幅降低了后续运维的人力投入。

二、 Jira:全球敏捷研发的“硬核”引擎

Jira依然是全球软件开发领域的行业标准,其强大的扩展性与敏捷支持的深度,使其成为大型技术团队不可或缺的生产力工具。
1. 强大的工作流引擎
Jira的核心壁垒在于其​高度可配置的工作流系统​。团队可以根据自身的开发模式(如Scrum或Kanban),设计出极其复杂的任务流转逻辑。每一个状态变更、每一个条件判断都可以被系统捕捉并执行相应动作。这种严谨的逻辑确保了研发流程的标准化,从源头上减少了因流程随意导致的返工浪费。
2. 敏捷开发深度支持
对于追求快速迭代的团队,Jira提供了​原生的敏捷看板与报表​。燃尽图、速率图等敏捷指标一应俱全,帮助团队实时复盘迭代效率。通过数据驱动的方式,管理者可以精准识别开发过程中的瓶颈,优化资源配置,实现研发效能的持续提升。
3. 庞大的插件生态系统
Jira拥有业界最丰富的​插件市场​。无论是代码集成、自动化测试还是服务台支持,企业都可以通过安装插件来扩展功能。这种“搭积木”式的架构,使得Jira能够适应企业不同发展阶段的需求,避免了频繁更换系统带来的迁移成本,是一项长期可靠的资产。

三、 Microsoft Project:经典项目控制的“定海神针”

对于工程、制造等传统行业,Microsoft Project(MS Project)凭借其无可替代的计划编制能力,依然是复杂项目管理的首选权威工具。
1. 专业的甘特图与排程引擎
MS Project拥有业界最强大的​甘特图计算引擎​。它支持关键路径分析、资源平衡以及复杂的任务依赖关系设定。在超大型项目中,人工排程几乎不可能,而MS Project能通过算法自动优化工期,避免资源冲突,确保项目按时交付,这是最大的“增效”。
2. 精细化资源与成本管理
区别于轻量级工具,MS Project在资源与成本核算方面做到了极致。管理者可以录入人员工时费率、材料成本,系统会自动汇总项目预算与实际消耗。这使得项目管理从单纯的“管事”上升到“管钱”,为企业提供了精准的成本控制依据。
3. 无缝的Office生态集成
MS Project与​Office 365生态深度融合​。项目计划可以直接发布到SharePoint,任务同步至Outlook,报表导出至Excel。对于习惯了微软办公套件的企业来说,这种无缝集成极大地降低了学习成本和沟通门槛,让团队协作更加顺畅。

四、 Asana:以人为本的团队协作中枢

Asana以其简洁优雅的界面和人性化的交互设计,成为市场、运营及创意团队提升协作效率的利器。
1. 多维度视图自由切换
Asana允许用户在同一项目中​一键切换列表、看板、时间轴和日历视图​。这种设计照顾到了不同角色的关注点:项目经理看时间轴把控进度,执行人员看列表聚焦待办。灵活的视图切换减少了信息筛选的时间,让每个人都能快速找到自己的工作重点。
2. 智能任务依赖与提醒
项目延期往往是因为上下游衔接不畅。Asana提供了​直观的任务依赖设定​,当上游任务延期时,系统会自动通知下游负责人。此外,其智能提醒功能会根据截止日期主动推送消息,避免了人工催办的尴尬与低效,让团队协作如齿轮般精密咬合。
3. 目标与战略对齐
Asana不仅关注任务执行,更引入了​Goals(目标)模块​。团队可以将日常任务与公司的年度战略目标关联。这种“所见即所得”的目标对齐机制,让员工清晰感知工作价值,避免了“为了做任务而做任务”的低效忙碌,从精神层面提升了团队产出。

五、 Monday.com:可视化工作流的高效创新者

Monday.com以其极具视觉冲击力的界面和高度自定义的特性,重新定义了项目管理的用户体验,让工作变得透明且有趣。
1. 高可视化的状态管理
Monday.com将枯燥的表格变成了​色彩丰富的可视化看板​。通过不同颜色的状态列、进度条,项目健康状况一目了然。管理者无需翻阅详细报告,仅凭颜色即可判断风险点。这种可视化的设计大大缩短了信息获取时间,提升了管理决策效率。
2. 强大的自动化配方
为了减少重复性劳动,Monday.com内置了​丰富的自动化配方​。例如“当状态变为完成时,自动通知项目经理”。用户无需懂代码,只需简单配置即可实现流程自动化。据测算,这些自动化流程能为团队节省大量手动操作时间,直接体现为人力成本的降低。
3. 跨部门协作看板
Monday.com打破了部门壁垒,支持构建​跨职能的工作看板​。销售、市场、研发可以在同一个平台上共享进度,数据实时同步。这种透明的协作机制消除了信息不对称带来的沟通成本,加速了业务流转。

六、 Trello:极简看板管理的效率先锋

Trello是看板管理方法的忠实实践者,以其极简的操作逻辑,成为无数小微团队和个人项目管理的首选。

1. 直观的拖拽式看板

Trello的核心是**“看板-列表-卡片”三层结构。操作极其简单,用户只需拖拽卡片即可更新任务状态。这种符合直觉的交互设计,让新团队成员上手时间几乎为零,极大降低了培训成本。

2. 灵活的Power-Up插件体系

虽然本体简单,但Trello通过Power-Up插件赋予了其无限可能。无论是接入Google Drive文件,还是开启投票功能,团队都可以按需加载。这种“按需付费”的模式,避免了为不需要的功能买单,是极致的“降本”思维。

3. 团队沟通透明化

Trello将讨论、附件、检查清单**全部集中在卡片内。所有关于任务的沟通都有迹可循,避免了信息散落在微信、邮件等不同渠道。这种“任务即沟通”的模式,确保了信息的完整性,减少了反复确认的时间浪费。

七、 Smartsheet:电子表格的企业级进化

Smartsheet巧妙地结合了电子表格的易用性与企业级项目管理的强大功能,是习惯Excel管理的团队转型的最佳选择。
1. 熟悉的表格界面与增强功能
Smartsheet采用了用户​极度熟悉的电子表格UI​,上手零门槛。但在表格之下,它隐藏了甘特图、附件、提醒等项目管理能力。这种设计让企业在不改变操作习惯的前提下,享受到了专业工具的红利,转型成本极低。
2. 行级附件与证明管理
在审批流程中,Smartsheet的行级附件功能尤为实用。每一行任务都可以挂载合同、发票等凭证,审批人可直接查看。这种将文档与数据深度绑定的方式,解决了传统管理中“数据与资料分离”的痛点,提升了审核效率。
3. 企业级安全与合规
对于大型企业,Smartsheet提供了​完善的安全管控体系​,包括审计日志、权限分级等。它符合SOC等国际安全标准,确保了企业在享受便捷的同时,数据资产得到严密的保护。

八、 ClickUp:一站式生产力平台新贵

ClickUp以“一个应用替代所有应用”为愿景,集成了任务、文档、目标、聊天等功能,适合追求极致效率的工具控团队。
1. 多层级层级结构
ClickUp设计了独特的​Space-Folder-List-Task层级结构​,能够完美适配从公司战略到个人待办的各种颗粒度。这种层级化的管理帮助团队在复杂的业务中理清脉络,避免了任务混乱导致的管理失控。
2. 文档与任务一体化
ClickUp内置了​强大的文档系统​,支持在文档中直接插入任务、创建看板。团队可以在撰写方案的同时,将其转化为可执行的任务,实现了从策划到执行的无缝衔接,减少了工具切换带来的注意力分散。
3. 高度自定义字段
ClickUp允许用户​自定义各种字段类型​,如货币、评分、进度等。这使得ClickUp能够模拟出CRM、Bug追踪系统等多种工具的形态,真正实现了“一物多用”,为企业节省了购买其他垂直软件的费用。

九、 Zoho Projects:高性价比的SaaS全能选手

作为Zoho全家桶的重要一员,Zoho Projects凭借高性价比和强大的集成能力,成为中小企业数字化转型的稳健之选。
1. 智能甘特图与规划
Zoho Projects提供了​交互式的智能甘特图​,支持自动排程和关键路径识别。当项目计划发生变更时,系统能智能调整后续任务,帮助管理者轻松应对变化,确保项目如期交付。
2. 深度集成Zoho生态
如果企业使用Zoho CRM或Books,Zoho Projects将展现出​巨大的生态优势​。项目数据可与客户信息、财务账单打通,实现从商机到交付再到回款的全流程数字化闭环,极大提升了业务流转效率。
3. 自动化规则与蓝图
通过​蓝图功能​,Zoho Projects帮助企业规范业务流程。管理者可以可视化地定义任务流转规则,确保标准作业程序(SOP)在团队中严格执行,减少了因人员能力差异导致的质量波动,实现了管理复制的“增效”。

2025 年 12 月 13 日,VeloxCon China 2025 在北京成功举办。作为 Velox 项目首次在中国举办的线下技术大会,汇聚了来自Meta、IBM、蚂蚁集团、阿里云、腾讯、小米、小红书等企业的数十位核心贡献者与一线工程师。

大会通过 18 场演讲将 Velox 置于真实业务场景之中,系统展示了其在架构演进、AI 数据处理、湖仓加速、流批融合等方向的最新实践。这些分享不仅直面性能、稳定性与兼容性等落地挑战,也反应了开发者社区对构建可靠、可扩展、可协同的数据基础设施的共同探索,彰显了中国开发者在全球高性能分析生态中的工程深度与协作广度。

夯实底座,突破能力边界
会议伊始,Velox 项目联合发起人 Pedro 发表开幕致辞。他回顾了 Velox 开源项目的发展历程,从项目启动、开源发布到建立技术治理结构,展示了 Axiom 架构、GPU 支持、PyVelox 等关键进展,强调了社区协作与工程严谨性是项目持续演进的核心动力。他特别提到,Velox 已建立了正式的技术治理机制,并迎来来自 IBM、Intel、NVIDIA、Microsoft 等多家企业的新增维护者,标志着项目正迈向更加开放和可持续的阶段。

在明确了社区与架构演进的总体方向后,大会议题迅速深入到如何利用 Velox 构建高性能计算引擎的具体实践中。阿里云 EMR Serverless Spark 技术负责人周克勇系统阐述了“可组合性”在数据计算领域的实践。他详细解析了阿里云如何深度集成并贡献于 Apache Celeborn、Paimon、Velox 及 Gluten 等开源组件,通过模块化组装构建出高性能湖仓一体引擎。他指出,基于该架构,阿里云 EMR Serverless Spark 成功创造了 TPC-DS 100TB 规模性能测试的世界新纪录,实现性能翻倍与性价比大幅提升。

接着,Meta 软件工程师 Masha Basmanova 阐述了现有查询引擎在跨语言通信、优化器能力与开发体验上面临的挑战,并介绍了基于 C++ 的统一前端框架 Axiom。该框架将 SQL 解析、逻辑优化与物理执行融为一体,通过内置的强大优化器与 Velox 运行时无缝对接,能够实现更高效、可扩展的查询处理。演讲最后,她积极展示了 Axiom 的开源路线图,并欢迎全球开发者加入,共同推动该项目的演进。

强大的执行框架,最终需要服务于极具挑战性的数据场景,特别是爆发式增长的 AI 数据。Meta 软件工程师孟晓烜则在之后的演讲中,深入阐述了应对AI训练数据规模激增与成本挑战的解决方案。他重点介绍了 Meta 如何通过数据归一化技术剥离重复特征,并构建可索引的序列存储系统。依托 Velox 技术栈,团队在训练数据的加载、生成与探索三大环节实现了端到端优化,显著提升了处理效率与资源利用率。

在 Meta 多位工程师从框架演进、可组合架构、数据标准化等角度深入分享后,蚂蚁集团高级技术专家黄叶伟也从企业落地实践层面分享了基于 Velox 的 Spark 加速实践。他重点介绍了基于 Gluten 与 Velox 构建的向量化引擎如何通过任务级 Fallback、Spill 优化、Shuffle 优化等关键技术,在混合部署场景下显著提升 Spark 性能与稳定性。他表示,该方案目前已实现日均数十万任务覆盖,平均节省资源超30%,并将在算子优化与架构扩展方面持续演进。

作为连接 Spark 生态与原生加速的关键中间层,Apache Gluten 的进展同样备受关注。来自 IBM 的莫芮与周渊聚焦 Apache Gluten与 Velox 的深度集成,阐述了其如何在大数据分析中驱动创新。他们介绍,Gluten 在保持对 Spark/Flink 作业透明加速能力的同时,正逐步增强对多后端引擎和复杂业务场景的适配能力。目前,该方案已在 Pinterest、顺丰科技及多个内部集群完成规模化验证,有效支撑了从日志分析到物流调度等多样化负载的性能提升与成本优化。

随着向量化加速在通用场景日趋成熟,针对特定存储格式的深度优化成为新的效能突破口。腾讯大数据开发工程师陈锦海分享了微信基于 Velox 加速 lceberg 湖仓分析的优化与实践,重点介绍了原生分桶方案。据他介绍,该方案通过动态识别表元信息自动设置分区数,能有效缓解 AQE 引发的写入倾斜,结合空闲资源灰度发布策略,可保障大规模作业的稳定上线。

扎根场景,释放协同效能
午餐后的议程更加聚焦 Velox 在真实业务中的集成深度与生产韧性,回应了开发者们对兼容性、稳定性与端到端效能等规模化落地的核心关切。
小米计算平台计算引擎负责人王胜杰分享了公司在 Spark 向量化升级中的规模化落地经验。面对业务迁移中的兼容性与稳定性挑战,他表示,小米通过自动兼容校验、双跑结果比对及内存异常感知的三级资源升级机制,已成功推动向量化改造在数十万作业中平稳落地。

面对海量数据挑战,全球科技公司也在探索相似的演进路径。Meta 软件工程经理 Stanley Yao 在演讲中分享了公司基于 Velox 推进 Spark 向量化改造的整体策略。他表示,团队通过从定制化方案到开源架构的持续演进,已实现关键业务管线向 Gluten(Flare)的平稳迁移,并获得显著的效率提升。未来,Meta 计划进一步扩大该架构的应用规模。

在 CPU 向量化趋于普及的同时,利用异构硬件挖掘更高性能成为新的前沿。IBM 研究院资深软件工程师 Zoltán Arnold Nagy 展示了基于 Velox 与 Presto 的 GPU 加速数据处理方案。他介绍道,Velox 通过与 cuDF 集成,可在 GPU 上高效执行算⼦,并针对多 GPU 分布式场景优化通信与数据交换。此外,为突破 I/O 瓶颈,团队正在探索结合 GPUDirect 存储与缓存层的加速策略。

对性能与稳定性的追求,也驱动着查询引擎架构本身的融合与创新。Meta 软件工程师谭家梁与大家分享了 Native Presto-on-Spark 的规模化应用。该架构以 Presto 查询优化、Spark 资源调度与容错机制以及 Velox 原生向量化执行为核心,实现了性能与可靠性的显著提升。他表示,目前该方案已在生产环境中取得成效,并将在未来持续推进全栈原生化演进。

对于国内庞大的云上业务,Velox 同样在支撑着关键数据服务平台。 阿里云高级工程师王彬与范阿冬系统介绍了Velox在阿里云日志服务中的深度集成与应用。他们指出,基于 Velox 构建的高性能查询引擎,通过混合执行、表达式下推、自动增量物化视图及免 Schema 分析等核心技术,可显著提升平台在处理海量实时数据时的查询效率与资源利用率。他们还强调,该架构不仅为日志分析、智能运维等场景提供了稳定支撑,也为面向 AI 的云原生数据平台演进奠定了坚实基础。

除了通用的日志与湖仓分析,Velox 也在向更垂直的时序数据场景渗透。腾讯高级工程师李兆龙分享了基于 Velox 构建云原生时序数据库的落地经验。他表示,通过在 Velox 中实现时序数据去重优化与存储写入增强,系统在应对高频写入与实时查询场景时,可显著提升吞吐效率与响应性能。目前该方案已有效支持物联网、实时监控等业务场景,未来还将进一步完善缓存与压缩机制,持续优化时序数据处理的整体效能。

IBM 软件工程师刘平接着分享了 Velox 在 Iceberg 数据写入能力上的突破性进展。他表示,目前 Velox 对 Iceberg 的支持以读取为主,其写入功能的完善将填补该方向的关键能力空白,为基于 Presto 与 Spark 的数据湖架构提供更统一、高效的数据摄入层。这一进展也标志着 Velox 正从查询加速向数据全链路处理拓展。

接着,来自阿里云的毕岩与周滔分享了 Velox 与 Apache Paimon 深度集成的解决方案,为提升引擎与存储的协同效率提供了另一种集成思路。在他们看来,现有方案存在表类型支持受限、缺乏可移植性等瓶颈, 但可以建立 C++ 原生 Paimon 库,通过其统一的数据协议与插件化设计,使 Paimon 能够被 Velox、StarRocks 等多种计算引擎直接高效调用,从而提升数据读写性能,并为湖仓格式的跨引擎协同提供新的基础支撑。

在批处理场景之外,流计算框架的向量化也正成为新的热点。蚂蚁集团技术专家刘勇介绍了基于 Velox 为 Flink 构建的统一向量化执行引擎 Flex。他表示,Flink 作为流批一体架构的核心,其原生向量化能力的补足至关重要。Flex 通过将 Velox 的高性能算子能力引入 Flink,同时结合自动化验证、可视化计划与精细化回退机制,现已实现了作业性能的显著提升,并支撑多条核心业务链路平稳运行。

随着 Velox 赋能的应用场景日益广泛和复杂,确保其在不同引擎和版本间的整体质量与可靠性变得至关重要。Meta 软件工程师 Eric Liu 阐述了在 AI 数据基础架构下,保障 Velox 多引擎版本可靠性的系统化方法。他指出,面对不同引擎与存储格式交织带来的复杂性,关键在于建立跨引擎测试框架与合成数据工厂。这一实践能有效提前发现全栈潜在问题,从而确保底层变更在大规模生产环境中的稳定与高效。

针对向量化引擎中窗口运算符内存溢出的典型难题,来自英特尔的贾柯分享了她的见解。她认为,通过为 Velox 引入流式窗口处理机制,可使计算随数据到达逐步执行并即时释放内存,从而从架构层面化解多数场景下的内存风险,显著提升复杂查询的稳定性。

最后,小红书 Native Engine 团队技术负责人魏秀利也分享了向量化引擎在公司业务中规模化落地的经验。据他介绍,通过将写入异步化并构建原生 Avro 读取能力,小红书在不增加业务复杂度的前提下,成功缓解了端到端延迟,印证了“执行与存储协同优化”在湖仓场景中的关键价值。

从底层执行引擎的持续创新,到日志分析、湖仓写入、流批融合等复杂场景的稳定运行,在本届 VeloxCon China 上,我们看到 Velox 的技术价值已在真实业务中不断被验证和拓展。同时我们也很高兴看到中国开发者成为这一进程的重要推动者。期待未来有更多志同道合者加入 Velox 开源社区,共建高性能分析基础设施。weibo.com/ttarticle/p/show?id=2309405289944930713617 weibo.com/ttarticle/p/show?id=2309405289945274384458 weibo.com/ttarticle/p/show?id=2309405289945618579474 weibo.com/ttarticle/p/show?id=2309405289946168033345 weibo.com/ttarticle/p/show?id=2309405289946511966256 weibo.com/ttarticle/p/show?id=2309405289946860093485 weibo.com/ttarticle/p/show?id=2309405289947204026388 weibo.com/ttarticle/p/show?id=2309405289947552153602 weibo.com/ttarticle/p/show?id=2309405289948042625029

当用户访问你的网站时,屏幕上赫然出现“SSL握手失败”或“ERR_SSL_PROTOCOL_ERROR”——几十秒的转圈后,页面拒绝加载。用户直接流失,而你可能连问题出在哪里都不知道。

所谓SSL握手,就是用户浏览器(客户端)与你的网站服务器之间的一次“加密握手”,双方就通信协议版本、加密套件、证书身份达成一致,才会真正建立HTTPS连接。这个环节一旦卡住,用户永远看不到你的网站内容。

真相一:证书过期、不完整或域名对不上

这是最冤大头的问题。很多网站管理者买了SSL证书,安装后就不管了,结果证书悄悄过期了都不知道。还有的人下载证书时只拿了服务器证书,忘了把中间证书链一起配置上去,导致浏览器无法验证证书的合法性。更常见的错误是,证书绑定的域名和你当前访问的域名不一致——比如证书是 www.abc.com,用户访问的却是 abc.com,握手一样会失败。

真相二:客户端与服务器的“语言”不统一——TLS版本冲突

每个浏览器和操作系统支持的TLS协议版本都不一样。老旧设备可能只懂TLS 1.0或1.1,而如今大多数安全网站已禁用这些过时版本,只允许TLS 1.2及以上。当一台老旧的Windows 7电脑配上旧版浏览器访问你的网站时,双方找不到一个共同支持的版本,握手自然失败。

真相三:服务器系统时间“穿越”了

这是一个容易被忽略的物理问题。SSL证书有明确的有效期起止时间,而浏览器判断证书是否有效,依赖的是客户端和服务器各自的系统时钟。如果你的服务器时间比真实时间慢了半小时,或者快了一整天,证书就可能被判定为“尚未生效”或“已过期”。明明刚买的证书,却因为时间错位而拒连,实在冤枉。

真相四:中间设备“好心办坏事”

很多网站架构中都有反向代理、负载均衡器、Web应用防火墙或CDN。这些设备会代替源服务器与客户端进行SSL握手。如果源服务器与这些中间设备之间的证书配置不一致,或者中间设备自身的TLS版本设置过于苛刻,握手请求就会在半路被截断。更麻烦的是,这类故障往往只在特定网络环境下出现,排查起来非常困难。

告别拒连:选对证书、配好服务才是根本

以上所有问题的核心,都指向一件事:你需要一张可靠、兼容性好、配有专业支持的SSL证书。选择正确的服务商JoySSL,提供国内一线品牌的SSL证书,涵盖单域名、多域名、通配符证书,同时配有专业的配置指导。无论你是遇到握手失败、证书不匹配,还是不知道如何部署中间证书,我们的工程师都能帮你一步步搞定,全程无需你敲一行代码

JeecgBoot AI专题研究 | andrej-karpathy-skills:给 AI 编程立规矩,外加一分钟安装指南

一个反常识的 GitHub 现象

最近 GitHub 趋势周榜的第一名,不是新框架,也不是新模型,而是一份不到 70 行的 Markdown 文件——项目名叫 andrej-karpathy-skills,一周拿下 4.5 万星,到目前已经累计 62.2k+。

andrej-karpathy-skills GitHub 截图

它没有复杂的代码,核心就是一个 CLAUDE.md,用来给 Claude Code、Cursor 这类 AI 编程工具立规矩,治一治它们乱写代码的毛病。

Karpathy 的吐槽,和它的起源

项目的灵感来自 Andrej Karpathy(前特斯拉 AI 负责人、OpenAI 创始团队成员)一月份在 X 上发的一条长推,阅读量逼近 800 万。他把自己用 AI Agent 写代码遇到的坑总结了一遍,几句话让无数开发者拍案:

模型会代你做错误假设,然后不假思索地执行。它们不管理自身的困惑,不寻求澄清,不呈现矛盾,不展示权衡。

它们真的很喜欢把代码和 API 搞复杂,堆砌抽象概念,不清理死代码……明明 100 行能搞定的事情,非要实现成 1000 行的臃肿架构。

它们有时仍会改动或删除自己理解不足的代码和注释,即使这些内容与任务本身无关。

开发者 Forrest Chang 把这些吐槽翻译成了模型能执行的规则,压缩成四条原则,写进了 CLAUDE.md。就这么一份文件,成了本周最火的开源项目。

四条核心原则

1. 编码前思考(Think Before Coding)

遇到歧义必须先问、先呈现权衡,而不是默不作声地猜需求。

2. 简洁优先(Simplicity First)

坚持最小可行实现:不加未请求的功能,不做一次性抽象。50 行能写完,绝不写 200 行。

3. 精准修改(Surgical Changes)

只改必须改的地方。不允许借"顺手优化"之名 reformat 相邻代码。每一行改动都能追溯到用户的原始请求。

4. 目标驱动执行(Goal-Driven Execution)

把"修复 Bug"改成"先写一个能复现 Bug 的测试,再让它通过"——可验证的目标,而不是模糊的命令

四条加起来,就把 AI 编程需要的纪律压缩进了模型能直接读懂的规则集。

快速安装(一分钟搞定)

项目提供了两种安装方式,取决于你用的是 Claude Code 还是其他工具。

方式一:Claude Code 插件(推荐)

Claude Code 用户直接用插件市场安装,两条命令即可:

# 1. 添加 marketplace
/plugin marketplace add forrestchang/andrej-karpathy-skills

# 2. 安装 skill
/plugin install andrej-karpathy-skills@karpathy-skills

安装完成后,skill 名字会变成 andrej-karpathy-skills:karpathy-guidelines,在你写代码、审代码、重构时自动激活,把四条原则注入到 Claude 的行为底盘里。

方式二:手动粘贴 CLAUDE.md(通用)

不用插件、或者用的是 Cursor / 其他 AI 工具,就直接把仓库里的 CLAUDE.md 拷到项目根目录:

# 项目根目录执行
curl -o CLAUDE.md https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md

Cursor 用户把同样的内容粘到 .cursorrules 即可——这套规则本身是跟具体工具解耦的。

装完随便开一个新任务,你会明显感觉到:AI 不再乱铺抽象,不再顺手 reformat 代码,遇到歧义会先停下来问你。

实战感受

用过的开发者反馈大致一致:

  • 长任务成功率明显提升,因为 Agent 不再"想到哪写到哪"
  • 代码体积变小,AI 不再热衷堆抽象层
  • code review 压力骤降,每次改动都更聚焦
  • 轻微副作用:琐碎任务会因为多一步"先确认"而稍微变慢,可以接受

本质上它是一份高级提示词规则集,效果仍依赖底层模型的指令执行力——配 Claude 4.7 和配某些开源 7B 模型差距巨大。它解决的是"行为问题",不是"工程问题";权限、沙箱、测试基础设施这些仍得自己搭。

结语

andrej-karpathy-skills 的爆火不是一次"奇迹",而是一次极其精准的翻译——把 AI 大神对 Agent 乱象的吐槽,翻译成了模型能照着执行的纪律。

在 AI 编程逐步成为主流工作流的今天,懂得给 Agent 立规矩的人,可能比会写 Agent 的人更有竞争力。如果你今天还在被 AI 工具"乱改一通"的副作用折磨,花一分钟把它装上,立刻能感受到"管教过的 AI"和"野生 AI"的差距。

项目地址:https://github.com/forrestchang/andrej-karpathy-skills


本文为 JeecgBoot AI 专题研究系列文章。

今天通过 OCBC 充值 OpenAI API, 账单地址填的 OCBC 的地址,结果被扣了 9%的 GST 税,问下大家是不是应该用美国地址? 9%还不如用 OpenRouter 划算。

广东湛江的冬天最多也就是湿冷,套件羽绒服就能对付。东北不一样,东北的冷是物理穿透,屋里的热是魔法攻击。

我坐在老丈人家的火炕上,空气干得我直想流鼻血。电视机开着,没人看,纯粹当个白噪音。我媳妇在旁边剥砂糖橘,皮扔了一桌子。

失业一年多了。从 24 年那阵子被裁,到现在,一直就这么飘着。

以前总觉得前端这碗饭能吃挺久。每天对着电脑调像素,搞交互,为了一个组件的复用性跟产品经理吵个脸红脖子粗。后来 AI 出来了。一开始大家还当个高级玩具,没过多久,只要把需求喂进去,它写的页面结构比我都干净,连 CSS 动画都给你安排得明明白白。

前端没了。没得挺突然,但也挺理所当然。

最扯的是,就在这最没底气、最不知道明天该干嘛的节骨眼上,我结了婚,还跟着媳妇回了这趟东北老家过年。

没收入的成年人在亲戚堆里是习惯性隐身的。我尽量少说话,多干活。帮着端盘子,拿碗。

东北的年夜饭硬菜多,铁锅炖、杀猪菜,但那天晚上,我吃得最多的是白米饭。

那是老丈人自己种的,胜利村的米。没有超市里那种乱七八糟的抛光打蜡,煮出来就是单纯的饭香。米粒泛着油光,嚼在嘴里有点弹牙,咽下去带点回甘。

突然觉得挺魔幻。大城市的代码写不下去了,写字楼里的工位被机器顶了,结果跑到这冰天雪地的东北,吃着老丈人种的饭,顺手接了个人生的新“需求”。

生活没给我发什么转行的武林秘籍,我也还是不知道以后长久的路怎么走。但至少,饭还得一口一口吃,事还得一件一件做。

IMG_4674.HEIC

当起了东北的女婿,也想聊聊南北的差异:

一开始对东北有一定的滤镜,以为东北人都是热情大老伙,受小时候看的电视剧《东北一家人》以及东北雨姐影响,原来也有媳妇他爸这种老老实实,不喜欢在大伙面前说话的,他爸那边家人都是这类型性格,媳妇他妈刚好是能一直说话的那种,能量真足,我媳妇刚好处于中间,东北人说话有时候就跟捧梗一样,贼逗,跟小品一样,怪不得春晚收视率东北独占前列。

东北真是基本独生子女,地位极高,不像我粤西一家基本三个娃以上,你能读的得上书就供你,读不了拉倒。

东北的坟墓都在地里,几个小土堆,立个碑,不像粤西还得坟琢,水泥,后山碑,我问清明节咋过,他们不过,就是过年去扫一下烧纸,蜡烛都不在坟里烧,就只烧纸,媳妇她奶过年都只在十字路口写上奶她妈的名字直接烧。

我媳妇是山东闯关东去的东北,刚好落在哈尔滨五常,那边的地真大,屯子和镇的房子真的查重率 80%,街道屋子都一样,他们过年喜欢挂彩灯,南方很少挂吧,至少在粤西,他们挂彩灯笼的时候,我看着就像中式恐怖片一样,可能小时候香港僵尸片看多了

还有最让我不解的是那边酒席最后才上筷子。。

如果你们也吃腻了外卖,或者也像我一样,在不知道下一步该怎么走的烂摊子里觉得心烦,可以尝尝这米。胜利村的,我老丈人自己种的。

没加什么科技与狠活,就是实实在在的五常稻花香 2 号大米。虽然我现在是个被 AI 干碎的失业前端,但自从吃了这五常大米,回不了头了,不知为啥这么香和有弹性。

岳父自己做的包装,好几款,有印了自己的照片当包装。具体分几种

编织袋(无真空) 7.8 元/斤

右边是编织袋,左边是礼盒装

塑封装(真空) 8.8 元/斤



礼品盒(真空) 9.8 元/斤


想尝尝的可以加我绿色泡泡,真名还是挡一下