包含关键字 typecho 的文章

⚠️回帖抽马年纪念一钞一币礼盒,共计 5 套

⚠️大笑脸开户 · 专业低佣券商开户
⚠️开户送五常大米,推荐朋友有红包

⚠️大笑脸低佣开户推荐:
银河证券:ETF 万 0.5 免 5 [ETF,LOF ,etf 免五费率最低,适合 etf ,打新,纳指,宽基玩家。新手必备]
光大证券: 万 0.854 免 5 [头部龙头券商,股票 etf 费率都很低]
开源证券: 万 0.854 免 5 [国企券商,股票 etf 费率都很低]
国泰海通: 万 0.8 免 5 [头部龙头券商,费率最优惠,大客户专享,综合费率最低]
平安证券:50 万两融低至 3.58%

⚠️大笑脸联系方式和最新具体券商表格清单,随时更新 www.daxiaolian.com

MetaForm 低代码引擎系列 · 第 2 篇
技术栈:Vue.js 3 + Composition API + 动态组件

一、前端硬编码的终结

在传统前端开发中,表单页面是这样写的:

<!-- 硬编码的噩梦 -->
<el-form>
  <el-input v-model="form.name" placeholder="姓名" />
  <el-select v-model="form.gender">
    <el-option label="男" value="male" />
    <el-option label="女" value="female" />
  </el-select>
  <el-date-picker v-model="form.birthday" />
</el-form>

每个 <input>、每个 <select> 都硬编码在 .vue 文件中。这种做法在低代码系统中无法存活

  1. 结构不可预知:表单由租户管理员在运行时动态创建,前端不可能在编译期知道会存在哪些字段。
  2. 变更成本极高:一个 Placeholder 的变更都要走 拉分支 → 修改代码 → 构建 → 部署 的漫长流程。

要解决这个问题,前端必须与业务逻辑完全解耦:前端只提供原子化的组件和布局容器,页面的拓扑形态完全由后端下发的一份 JSON 元数据(Schema)动态决定。

这种架构在 Salesforce 中被称为 FlexiPageLayout 体系。


二、定义 Layout Schema 协议

在动手写前端代码之前,我们需要与后端确立一套接口规范。前端发起请求:

GET /api/layout/{form_id}

后端返回如下结构:

{
  "layout_id": "lay_1001",
  "title": "入职申请表",
  "action_url": "/api/data/frm_1001",
  "sections": [
    {
      "section_id": "sec_basic",
      "section_title": "基础信息",
      "columns": [
        {
          "items": [
            {
              "field_name": "employee_name",
              "field_type": "string",
              "component_type": "MetaInput",
              "label": "姓名",
              "required": true,
              "max_length": 50,
              "placeholder": "请输入真实姓名"
            }
          ]
        },
        {
          "items": [
            {
              "field_name": "gender",
              "field_type": "string",
              "component_type": "MetaSelect",
              "label": "性别",
              "required": false,
              "options": ["男", "女"]
            }
          ]
        }
      ]
    },
    {
      "section_id": "sec_detail",
      "section_title": "详细信息",
      "columns": [
        {
          "items": [
            {
              "field_name": "join_date",
              "field_type": "date",
              "component_type": "MetaDate",
              "label": "入职日期"
            }
          ]
        }
      ]
    }
  ]
}

注意那个关键的 component_type 字段——它将指导 Vue 引擎进行组件的动态装载。


三、Vue 3 动态渲染引擎实现

3.1 原子组件封装

首先,将底层 UI 库的组件封装为符合 Meta 规范的原子组件:

<!-- MetaInput.vue -->
<template>
  <!-- 动态读取 schema 中的 rules,转化为底层 UI 库的属性 -->
  <el-form-item :label="schema.label" :required="schema.required">
    <el-input
      v-model="internalValue"
      :placeholder="schema.placeholder"
      :maxlength="schema.max_length"
      :show-word-limit="!!schema.max_length"
    />
  </el-form-item>
</template>

<script setup>
import { computed } from "vue";

const props = defineProps({
  schema: Object,
  modelValue: [String, Number],
});
const emit = defineEmits(["update:modelValue"]);

const internalValue = computed({
  get: () => props.modelValue,
  set: (val) => emit("update:modelValue", val),
});
</script>

同理封装 MetaSelect.vueMetaDate.vue 等原子组件。

架构师提示(关于动态校验规则下发):底层的原子组件不仅负责渲染 UI,更需要忠实地继承 Layout Schema 中定义的业务规则。如上面的 MetaInput,通过直接读取 JSON 中的 requiredmax_length 属性,并绑定到 <el-input> 上,前端无需硬编码任何繁复的校验逻辑,便自然拥有了浏览器和 UI 库提供的表单拦截能力。

3.2 动态 Component Factory 解析器

核心魔法是 Vue 的内置 <component> 指令,结合 is 属性:

<!-- DynamicFormParser.vue -->
<template>
  <div class="dynamic-form" v-if="layoutSchema">
    <h2>{{ layoutSchema.title }}</h2>

    <div
      v-for="section in layoutSchema.sections"
      :key="section.section_id"
      class="form-section"
    >
      <h3>{{ section.section_title }}</h3>

      <!-- 细化层级结构:遍历列 (Column) -->
      <div class="section-layout" style="display: flex; gap: 24px;">
        <div
          v-for="(col, colIdx) in section.columns"
          :key="colIdx"
          class="layout-column"
          style="flex: 1;"
        >
          <!-- 引擎核心:<component :is> 动态加载该列中的 items -->
          <component
            v-for="item in col.items"
            :key="item.field_name"
            :is="getComponent(item.component_type)"
            :schema="item"
            v-model="formData[item.field_name]"
          />
        </div>
      </div>
    </div>

    <el-button type="primary" @click="submitData">提交表单</el-button>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import axios from "axios";
import MetaInput from "./components/MetaInput.vue";
import MetaSelect from "./components/MetaSelect.vue";
import MetaDate from "./components/MetaDate.vue";

const props = defineProps({ formId: String });

const layoutSchema = ref(null);
const formData = ref({}); // 核心:所有动态组件的数据归宿

const componentMap = { MetaInput, MetaSelect, MetaDate };
const getComponent = (typeStr) => componentMap[typeStr] || MetaInput;

onMounted(async () => {
  const { data } = await axios.get(`/api/layout/${props.formId}`);
  layoutSchema.value = data;
});

const submitData = async () => {
  // formData.value 就是完美的 JSON Payload
  await axios.post(layoutSchema.value.action_url, formData.value);
};
</script>

<style scoped>
.grid {
  display: grid;
  gap: 16px;
}
.form-section {
  margin-bottom: 24px;
}
</style>

四、双向绑定的精髓

这套代码中最精妙的一笔是 v-model="formData[item.field_name]"

formData 是一个初始化为空的 ref({}) 对象。当 Vue 渲染包含 field_name: "employee_name" 的组件时,它会自动在 formData 中创建键值 formData.employee_name,并通过 update:modelValue 事件实现双向绑定。

我们完全不用操心有多少个字段、什么嵌套结构。点击"提交"时,formData.value 里就是一份完美的、准备好塞给后端 JSONB payload 的数据体。


五、Schema 驱动渲染管线图解

Schema 驱动渲染管线

整个流程分为 4 步:

  1. API Response:后端返回 Layout JSON 描述(字段类型、名称、校验规则等)
  2. Vue Component Factory<component :is="..."> 解析器读取 JSON 并进行路由分发
  3. UI Components:分发出具体的原子组件实体(MetaInput、MetaNumber、MetaDate)
  4. State Collection:所有组件的值通过 v-model 双向绑定到集中的 JSON Payload State

小结

  • 前端零硬编码:所有表单结构由后端元数据驱动,无需手写模板
  • 可无限扩展:新增字段只需在元数据层配置,前端自动渲染对应组件
  • 数据自动收集formData 统一收集所有组件的值,与后端 DML 引擎无缝对接
下一篇预告:前端收集好了 formData,这份 JSON Payload 如何安全地经过类型转换、规范化编码后落入 PostgreSQL 的 JSONB 堆表?请看第 3 篇《运行时数据引擎 —— DML 拦截与 JSONB 检索》。

MetaForm 低代码引擎系列 · 第 3 篇 基于 JSONB 函数索引的高性能 DML 落地指南
技术栈:Python FastAPI + PostgreSQL JSONB + GIN 索引

一、规范化格式 (Canonical Format) 的必要性

上一篇中,Vue 前端收集到了一份 JSON Payload

{
  "employee_name": "张三",
  "age": "25",
  "join_date": "2024年1月1日"
}

如果直接把这段未经处理的 JSON 塞入 data_heap.payload,会埋下两颗定时炸弹:

  1. 类型崩坏:前端传来的 age: "25" 是字符串,字符串的 "100" 在字典序中排在 "25" 前面(因为首字符 1 < 9)。数值比较将完全错误。
  2. 格式灾难:中文日期格式无法使用数据库的原生时间窗口过滤功能。

由于我们放弃了关系型数据库原生的强类型列(int, timestamp),就必须在应用层用代码将类型安全补回来。这个过程叫做数据规范化 (Normalization) 与强制转换 (Type Cast)

数据入库拦截器

数据入库拦截器 - Data Cast Pipeline

前端的 Raw JSON 进入运行时引擎后,引擎从 UDD 缓存中拉取 meta_fields 进行对比,将字符型的 "18" 转换为整型 18,日期格式化为 ISO 8601,最终以 Formatted JSONB 落入 data_heap 物理表。


二、通用 DML 写入接口实现

我们设计 POST /api/data/{form_id} 作为所有数据的唯一入口:

from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks
from sqlalchemy.orm import Session
from datetime import datetime
import json, uuid

router = APIRouter(prefix="/api/data")

def canonical_encode(value, field_type: str):
    """根据元数据类型,强制格式化数据"""
    if value is None:
        return None
    if field_type == "number":
        return float(value)
    elif field_type == "date":
        # 支持多种输入格式,统一输出 ISO 8601
        if isinstance(value, str):
            for fmt in ["%Y-%m-%d", "%Y年%m月%d日", "%Y/%m/%d"]:
                try:
                    return datetime.strptime(value, fmt).isoformat()
                except ValueError:
                    continue
        return str(value)
    elif field_type == "boolean":
        return bool(value)
    else:
        return str(value)


@router.post("/{form_id}")
def insert_record(form_id: str, payload: dict, db: Session = Depends(get_db)):
    # 1. 加载元数据蓝图(通常走 Redis/LRU Cache)
    fields_meta = db.execute(
        "SELECT field_name, field_type, is_required FROM meta_fields WHERE form_id = :fid",
        {"fid": form_id}
    ).fetchall()

    # 2. 运行时类型转换与校验
    canonical_payload = {}
    for meta in fields_meta:
        raw_val = payload.get(meta.field_name)

        # 必填校验拦截
        if meta.is_required and raw_val is None:
            raise HTTPException(422, f"字段 '{meta.field_name}' 为必填项")

        if raw_val is not None:
            canonical_payload[meta.field_name] = canonical_encode(raw_val, meta.field_type)

    # 3. 组装 JSONB 并写入堆表
    record_id = str(uuid.uuid4())
    db.execute(
        """INSERT INTO data_heap (id, org_id, form_id, payload)
           VALUES (:id, :org_id, :form_id, :payload::jsonb)""",
        {
            "id": record_id,
            "org_id": "tenant-001",
            "form_id": form_id,
            "payload": json.dumps(canonical_payload, ensure_ascii=False)
        }
    )
    db.commit()
    return {"status": "ok", "id": record_id}

整个流程:加载元数据 → 类型转换 → 组装 JSONB → SQL Insert,一气呵成。


三、动态 SQL 与 JSONB 查询

数据落地后,更具挑战的是取出来。

假设前端请求:"查询年龄大于 18 岁的记录":

GET /api/data/frm_1001?age__gt=18

运行时引擎充当查询翻译器 (Query Builder)

  1. 解析字段名与操作符:提取字段 age,操作符 __gt (Greater Than)
  2. 结合元数据判定类型:查 meta_fields 缓存得知 ageNumber 类型
  3. 编译底层 PGSQL:使用 JSONB 深度提取操作符 ->>,附加显式类型转换 ::numeric

JSONB 查询翻译器

JSONB 查询翻译器

前端的 API 请求被 Query Builder 引擎结合元数据翻译为底层 SQL,关键在于 ->> 操作符和 ::numeric 类型强转:

SELECT id, payload
FROM data_heap
WHERE form_id = 'frm_1001'
  AND (payload->>'age')::numeric > 18;
@router.get("/{form_id}")
def query_records(form_id: str, request: Request, db: Session = Depends(get_db)):
    # 解析查询参数如 age__gt=18, name__contains=张
    filters = []
    params = {"fid": form_id}

    for key, value in request.query_params.items():
        if "__" in key:
            field_name, operator = key.rsplit("__", 1)
            # 从元数据获取字段类型
            field_meta = get_field_type(db, form_id, field_name)

            if operator == "gt":
                cast = "::numeric" if field_meta == "number" else ""
                filters.append(f"(payload->>'{field_name}'){cast} > :val_{field_name}")
                params[f"val_{field_name}"] = value
            elif operator == "eq":
                filters.append(f"payload->>'{field_name}' = :val_{field_name}")
                params[f"val_{field_name}"] = value

    where_clause = " AND ".join(filters) if filters else "1=1"
    results = db.execute(
        f"SELECT id, payload FROM data_heap WHERE form_id = :fid AND {where_clause}",
        params
    ).fetchall()

    return [{"id": r.id, "data": r.payload} for r in results]

四、性能进阶:索引策略

4.1 GIN 倒排索引

JSONB 之所以能在生产环境立足,是因为 GIN (Generalized Inverted Index) 倒排索引

-- 为整个 JSONB payload 建立 GIN 索引
CREATE INDEX idx_heap_payload ON data_heap USING GIN (payload jsonb_path_ops);

PostgreSQL 会将 JSONB 文档内所有键值组合索引化。使用 @> (包含) 操作符时,数据库直接走倒排索引,速度与普通 B-Tree 索引差距极小。

-- 精确匹配查询(走 GIN 索引)
SELECT * FROM data_heap
WHERE payload @> '{"status": "active"}'::jsonb;

4.2 性能核弹:函数/表达式索引 (Functional Indexes)

架构师提示(解决全表扫描的终极杀器):在我们上面的查询翻译器中,出现了 (payload->>'age')::numeric > 18 这样的条件。
必须警惕:在千万级数据量下,每次查询都做显式的 ::numeric 类型转换是无法命中普通 GIN 索引的,这必定会导致极其缓慢的全表扫描。

为了彻底解决 Schema-Free 宽表范围检索的性能瓶颈,Salesforce 在其底层架构中设计了复杂的 MT_Indexes(索引透视表)。而在现代 PostgreSQL 中,我们拥有更优雅的原生武器:函数索引(表达式索引)

对于那些在业务上被高频用于范围检索(大于、小于、区间等)的数字或日期字段,系统可以在后台自动静默建立一个强类型的表达式索引:

-- 为高频检索的数值字段 age 创建"提纯"的表达式 B-Tree 索引
CREATE INDEX idx_heap_age_numeric
ON data_heap USING BTREE (((payload->>'age')::numeric));

一旦建立了这个索引,PGSQL 的查询优化器(Planner)会非常聪明地在执行 (payload->>'age')::numeric > 18 查询时,自动感知并直接命中这个原生的强类型 B-Tree 索引,完全跳过全表扫描。这让 JSONB 的范围过滤拥有了与原生独立物理数据库列极度接近的极限查询性能!


小结

  • 拦截 + 编码:运行时引擎确保所有业务数据在写入前完成类型安全转换
  • JSONB + GIN:提供灵活的 Schema-Free 存储,同时保持高效查询能力
  • 统一入口:前端只需提交普通 JSON,后端负责全部转换与持久化
下一篇预告:数据能正确落库了,但如何在写入前自动执行业务校验规则(如"分数不能为负")?

MetaForm 低代码引擎系列 · 第 1 篇
技术栈:PostgreSQL (JSONB) + Python FastAPI + Vue.js

一、痛点引入:无限建表的 DDL 灾难

在传统的软件开发模式中,我们的潜意识里有一条不可动摇的黄金定律:一个业务对象,就必然对应数据库里的一张物理表。

比如我们要开发一个问卷系统,很自然地会建立 Survey(问卷表)、Question(题目表)、Response(答卷表)。表里定义好具体的列:titleVARCHARscoreINTcreated_atTIMESTAMP。各司其职,结构清晰。

但是,现代企业级 SaaS(比如低代码平台、灵活的 CRM 系统)面临的核心挑战是:极端的个性化诉求规模化。

设想一下,你的平台服务了成百上千个企业客户(租户):

  • A 企业希望在问卷里加一个"所属行业"字段;
  • B 企业希望加一个"紧急程度"字段;
  • C 企业甚至想完全新建一个叫"问卷回访跟进"的新业务模块。

如果坚持"一对象一表"的传统架构,灾难接踵而至:

  1. DDL 风暴 (Data Definition Language Storm):上百个租户各自在界面上点击"添加字段"时,后台就要向数据库发送大量 ALTER TABLE ADD COLUMN 语句。DDL 操作会锁表(Metadata Lock),在高并发的生产数据库中等同于自杀。
  2. 运维的无底洞:如果为每个租户单独建表,1 万租户 × 50 张表 = 50 万张表。数据字典极度膨胀,备份、升级、统一修改都变得困难。
  3. 隔离性极其脆弱:多租户环境下 Schema 完全不同,一套代码体系很难处理所有边缘情况,最后陷入 if-else 的泥潭。

面对这些困难,业界诞生了一个近乎"离经叛道"的核心选择:彻底放弃让应用层直接操作数据库 Schema。

数据库退化为纯粹的数据仓库,它不关心也不知道具体的业务模型长什么样。至于"系统里有哪些表、表里有哪些字段"这种工作,被"上架"到了应用层来管理。

这就是元数据驱动架构(Metadata-Driven Architecture)的起点。


二、核心理念:通用数据字典 (UDD)

元数据 (Metadata),简单来说就是"描述数据的数据"

如果说普通的业务数据记录的是"张三考了 95 分",那么元数据记录的就是"系统里有一个叫『问卷』的表,它有一列叫『分数』"。

管理这些元数据的系统,我们称之为 通用数据字典 (Universal Data Dictionary, UDD)

核心思想是:既然底层数据库不让自由建表了,那就拿两张固定的表当"户口本",把用户想要的表结构"登记"在册。

meta_forms(登记"有什么表")

当你在低代码后台点击"新建表单"并命名为"问卷调查"时,底层不会执行 CREATE TABLE。系统只是在 meta_forms 中插入一行记录。

meta_fields(登记"表里有什么列")

每当你在页面上拖拽生成一个"问卷标题"的输入框,系统就在 meta_fields 表里加上一行。

理解关键点:在这个体系里,修改系统结构不再是高危的数据库操作(DDL),而变成了最简单的增删改查(CRUD)。

三、架构对比图解

传统架构 vs 元数据架构对比

传统架构中,每个业务对象(User、Order、Survey)都有自己独立的物理表,每次结构变更都需要 ALTER TABLE。而在 MetaForm 的元数据架构中,只有两张配置表 meta_formsmeta_fields 负责定义结构,所有业务数据统一落入 data_heap 的 JSONB payload 字段中。


四、技术抉择:为什么是 PGSQL + JSONB

结构定义好了,实际的业务数据存哪里?

Salesforce 早期使用了 弹性宽表 (Flex Table) 方案:建一张超级大的宽表,包含 Value0Value500 共 500 个 VARCHAR(255) 列。元数据字典记录某个字段存入了哪个具体的 Slot(例如"手机号"存入 Value3)。

虽然实现了 Schema-Free,但痛点极多:

  • 所有数据都被强制转为字符串,数值排序、日期过滤极度痛苦
  • 空槽位造成巨大的存储浪费
  • 需要维护复杂的 Slot Mapping 逻辑

在现代技术栈下,我们选择 PostgreSQL + JSONB 作为底层底座。这是一种降维打击:

CREATE TABLE data_heap (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    org_id VARCHAR(64) NOT NULL,    -- 租户隔离
    form_id VARCHAR(64) NOT NULL,   -- 关联 meta_forms(⚠️ 绝对的隔离条件)
    payload JSONB NOT NULL,         -- 核心:所有业务数据打包在此
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- GIN 索引:加速 JSONB 内部的键值检索
CREATE INDEX idx_data_heap_payload ON data_heap USING GIN (payload jsonb_path_ops);
架构师提示(关于数据隔离的底线):由于所有的表单数据都在 data_heap 这个“大通铺”里,哪怕在单租户架构下,查询时 WHERE form_id = 'xxx' 也是绝对不可或缺的隔离条件。这就如同给数据分区,必须在后端底层DAO层强行统一带上 form_id,防止业务数据产生灾难级的越界。

### JSONB 的核心优势与 Key 映射规则

1. **天然 Schema-Free**:无论前端提交多少动态字段,直接打包成 JSON 塞进 `payload` 字段,彻底免除了维护 Slot Mapping 的痛苦。
   * ** 架构提示(关于 Key 的映射)**:在设计 `meta_fields` 时,强烈建议区分**显示名 (Label)** 和 **内部标识名 (DeveloperName / API Name, 如 `age__c`)**。JSONB 内部的 Key **必须**使用不可变的 `field_api_name`,而不是可能会被业务人员随时修改的中文显示名,以此保证底层物理数据的稳定性。
2. **极速数据定位**:通过 PGSQL 的 JSONB 操作符(如 `->>`、`#>>`),可以轻松查询深层结构:
   ```sql
   SELECT payload->>'phone_number' FROM data_heap WHERE form_id = 'frm_1001';
  1. GIN 索引加速:只需为 payload 建立一个 GIN 倒排索引,就能自动加速所有基于 JSON Key/Value 的检索,碾压传统的逐列 B-Tree 索引。

JSONB 存储映射透视

JSONB 存储映射透视图

上方 meta_fields 定义了字段名(如 AgeName)和类型,下方 data_heappayload 列中,这些字段名直接作为 JSON 的 Key 存储。元数据定义了 JSON 内部的结构。


五、 API 设计

了解了物理底座后,来看后端的 API 接口。整个平台只需要几个元数据管理接口:

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import List
import uuid

router = APIRouter(prefix="/api/meta")

class FieldCreate(BaseModel):
    field_name: str
    field_type: str  # 'string', 'number', 'boolean', 'date'
    is_required: bool = False

class FormCreate(BaseModel):
    name: str
    description: str = ""
    fields: List[FieldCreate]

@router.post("/forms")
def create_dynamic_form(body: FormCreate, db: Session = Depends(get_db)):
    """
    新建动态表单:操作元数据字典,而非 DDL 建表。
    """
    form_id = f"frm_{uuid.uuid4().hex[:8]}"

    # 1. 在 meta_forms 中登记"虚拟表"
    db.execute(
        "INSERT INTO meta_forms (form_id, name, description) VALUES (:fid, :name, :desc)",
        {"fid": form_id, "name": body.name, "desc": body.description}
    )

    # 2. 批量登记字段定义到 meta_fields
    for field in body.fields:
        db.execute(
            """INSERT INTO meta_fields (field_id, form_id, field_name, field_type, is_required)
               VALUES (:fld_id, :fid, :fname, :ftype, :req)""",
            {
                "fld_id": f"fld_{uuid.uuid4().hex[:8]}",
                "fid": form_id,
                "fname": field.field_name,
                "ftype": field.field_type,
                "req": field.is_required,
            }
        )

    db.commit()
    return {"status": "success", "form_id": form_id}

@router.get("/forms/{form_id}")
def get_form_meta(form_id: str, db: Session = Depends(get_db)):
    """
    获取表单的完整元数据蓝图,前端据此渲染 UI。
    """
    form = db.execute(
        "SELECT * FROM meta_forms WHERE form_id = :fid", {"fid": form_id}
    ).fetchone()
    if not form:
        raise HTTPException(404, "Form not found")

    fields = db.execute(
        "SELECT field_name, field_type, is_required FROM meta_fields WHERE form_id = :fid",
        {"fid": form_id}
    ).fetchall()

    return {
        "form_id": form.form_id,
        "name": form.name,
        "fields": [dict(f._mapping) for f in fields]
    }

调用 POST /api/meta/forms 时,虽然在业务概念上我们"新建"了一张表,但数据库底层仅仅发生了普通的事务性 INSERT。没有任何表结构被改动,也没有触发锁。


小结

元数据驱动的核心并不是消灭了结构,而是做了一次巧妙的维度提升。 我们将传统数据库赖以生存的 Schema 从底层剥离,搬到了更高一层的"应用层数据字典"中。

在这个世界里,无论租户有多少,无论他们定义怎样千奇百怪的表单,底层物理依然是一张纹丝不动、便于统一治理和灾备的 JSONB 堆表。

下一篇预告:后端有了"JSON 蓝图",前端 Vue.js 是如何像搭积木一样将它们动态渲染成生动、可交互、带双向绑定的表单界面的?

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

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

Audiobookshelf 是一个开源的、自托管的播客和有声书服务器。如果你手里有很多珍藏的有声书音频(比如评书、小说、外语听力),或者想集中管理订阅的播客,把它部署在 NAS 上,你就能拥有一个类似“喜马拉雅”或“小宇宙”的私人听书平台,不仅能记录播放进度,还支持多端同步!

这次我们以飞牛 NAS 为例演示部署过程,其他品牌(极空间、绿联、群晖等)的操作步骤也都大同小异

首先,打开 NAS 的 「文件管理」 应用,在 docker 文件夹里创建一个名为 audiobookshelf 的主文件夹。

接着,进入 audiobookshelf 文件夹,在里面再分别创建 4 个子文件夹:

  • audiobooks (存放有声书)
  • config (存放配置文件)
  • metadata (存放元数据)
  • podcasts (存放播客文件)

打开 「Docker」 应用,切换到 Compose 面板,点击新建一个项目:

  • 项目名称audiobookshelf
  • 路径:选择上一步创建的 /docker/audiobookshelf 文件夹路径
  • 来源:选择 创建 docker-compose.yml

在代码框中填入以下代码:

services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:latest
    container_name: audiobookshelf
    ports:
      - 13378:80
    volumes:
      - /vol1/1000/docker/audiobookshelf/audiobooks:/audiobooks
      - /vol1/1000/docker/audiobookshelf/podcasts:/podcasts
      - /vol1/1000/docker/audiobookshelf/metadata:/metadata
      - /vol1/1000/docker/audiobookshelf/config:/config
    restart: unless-stopped

💡 参数:

  • volumes 下的每一项,都对应我们在第一步创建的子文件夹。请注意将冒号前的内容修改为你自己 NAS 的真实路径。
  • 13378 是给 Audiobookshelf 映射的本地端口,如果这个端口被占用了,你可以自定义改成其他数字(比如 13379)。

等项目构建完成后,切换到 容器 面板,找到 audiobookshelf 这一项。点击它旁边的链接按钮(或者在浏览器输入 NAS的局域网IP:13378 ),就能打开 Audiobookshelf 了。

初次进入系统,你需要先创建一个管理员账号。

登录成功后,默认是英文界面。

想要调成中文很简单: 点击右上角的 Settings(设置),找到 Default Server Language,在下拉菜单中选择 简体中文,界面就会瞬间变得亲切起来。

接下来是添加有声书,点击左侧导航栏的 媒体库,选择 添加第一个媒体库。类型选择有声书,文件夹映射路径选择 /audiobooks

然后打开 NAS 的 「文件管理」 应用,找到我们第一步建好的 /docker/audiobookshelf/audiobooks 文件夹,把准备好的有声书文件(mp3、m4b 等格式)放进去。

回到 Audiobookshelf 网页端,点击 扫描

扫描完成后,点击左上角的 Audiobookshelf 图标回到首页,就能看到刚刚添加进来的有声书。

点开即可选择章节播放。

如果你使用的是飞牛、绿联等国产新势力的 NAS,通过它们的移动端 App 穿透,在手机上也可以随时随地直接连上 Audiobookshelf 听书,非常方便!


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

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

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

大家好! Carry Code v0.7.3 正式发布了!这是一个使用 Rust 彻底重写的, 终端原生的 AI 代码代理,能通过自然对话帮助你编写、重构、调试和理解代码。

Q: Carry Code 为什么选择做 Cli 作为交互形式?

A: 我们认为编程的最终形式是黑灯工厂, 端到端实现需求定义到产品交付, 甚至无需人工介入;

📦 v0.7.3 更新

  1. 环境变量自动加载 Model API Key:支持从环境变量读取 Claude 、Gemini 、OpenAI 、OpenRouter 的密钥, carry命令可以直接兼容你的其他 cli 客户端;
  2. Skills 智能推理:大模型能自动选择合适的技能, 功能上对齐 claude code 和 openclaw;
  3. MCP 输出标准化:与 Bash 工具输出格式对齐,更直观;
  4. 原生 GPT-5.4/5.4 Pro 支持, 原生 OpenRouter 支持;

iShot_2026-03-08_18.23.02|690x484

✨ 核心亮点

🤖 双模式 Agent

  • Build 模式:自主生成和编辑代码
  • Plan 模式:只读分析和规划方案,安全可控

🧩 MCP 协议支持

  • 通过 Model Context Protocol 扩展智能体能力,用 /mcp 轻松管理

🎯 SKILL 技能系统

  • v0.7.3 新增 16 个内置技能,大模型会自动选择合适的技能来完成任务
  • 与 Claude Code Skills 兼容,可用 /skill 管理

iShot_2026-03-08_18.23.02|690x484

📋 AGENTS.md

  • 在项目根目录放置 AGENTS.md ,CarryCode 就会遵循项目专属规范

🎨 精美终端 UI

  • 渐变 Banner 、Markdown 渲染、语法高亮、代码 Diff 预览
  • 亮色/暗色主题一键切换

🔌 17+ 模型服务商

  • OpenAI 、Claude 、Gemini 、DeepSeek 、Kimi 、GLM 、MiniMax 、通义千问、Ollama 、vLLM 、OpenRouter……总有一款适合你

🚀 240+ SOTA 模型

  • GPT-5.4/5.4 Pro 、Claude Opus/Sonnet 4.6 、Gemini 3 Pro/Flash 、Kimi 2.5 、DeepSeek V3.2 、Qwen3 等业界最新模型的原生支持(准确上下文适配和多模态识别).

🗜️ 智能上下文压缩

  • 自动压缩长对话,适应 Token 限制同时保留关键信息

📥 安装

 1 │ # MacOS / Linux
 2 │ curl -fsSL https://carrycode.ai/install.sh | sudo sh
 3 │ 
 4 │ # Windows
 5 │ irm https://carrycode.ai/install.ps1 | iex

 1 │ # 运行
 2 │ carry

或使用单次模式:

 1 │ carry --once "解释这个函数"

快来试试吧!🎉

业余做了个 AI 文字修仙游戏(凡人修仙传世界观),累计四五百人玩过,有人一口气打了五百回合。

技术栈是 Vue 3 + CloudBase + DeepSeek ,流式 SSE 输出。做的过程中在上下文管理上踩了不少坑,分享几个我觉得比较有价值的:

上下文不是内存,是注意力带宽

一开始用 history.slice(-10) 就够了。后来有人玩了五百轮,加到 35 轮历史反而更差——AI 搞混剧情线,在不该突破的时候写突破。

后来想明白了:塞太多进去不是"记住更多",而是每条信息都被更少地关注。

让 AI 自己做摘要

压缩历史的时机很关键。调额外的 AI 来压缩?用户等太久。最后发现让 AI 写故事时顺便输出 30 字摘要是最优解——刚写完 300 字,对"发生了什么"理解最准确,摘要几乎零成本。

做了三层分级:最近十几轮完整保留,再往前用摘要替代,更早的压缩成章节摘要。150 轮从 50000 字压到 10000 字。

堵不如疏(这是最大的教训)

储物袋 80 件上限,AI 不知道,继续写"你拿到了聚灵丹",前端拦截了——玩家看剧情说拿到了,打开背包没有。

本能反应是在 System Prompt 加规则。一条不够加两条,语气从"禁止"升级到"严禁"。光一月十八号一天就改了 8 次提示词。385 行膨胀到 654 行,效果越来越差。

后来换了思路:代码检测到物品超阈值,就在上下文末尾动态注入一条警告。物品清理后 condition 变 false ,警告自动消失。

30 条规则永驻上下文,AI 条条违规。每次只注入 1-3 条最相关的,条条遵守。不是 AI 变聪明了,是它不用同时关注 30 件事了。

就像家长同时念叨"坐直!作业呢?别玩手机!早点睡!"——小孩一条没听进去。但过马路时只说一句"看车",立刻照做。

选题材比写提示词重要

有玩家夸上下文管理做得好,其实那时候就一个 slice(-10)。效果好纯粹是题材红利——凡人修仙传在网上有海量素材,AI 训练时学了一大堆。选一个 AI 本身就"懂"的题材,比费劲写提示词教它有用得多。


71194ec3a4d74024.webp

游戏在这里,感兴趣可以试试: https://fanren.idealeap.cn/

邀请码:FTWK3TAM

欢迎交流,也欢迎来玩然后骂我

和 AI 对话超过 20 轮之后,看着它慢慢开始胡说八道,如果有过这种经历,那么你就应该看看这篇论文

跟 AI 聊天机器人对话时,用户输入的每一个字都会被保存,模型给出的每一条回复同样会被保存。所有历史内容在下一轮对话中被回传给模型,再下一轮,再下一轮,像河底的沉积物越堆越高。

每一个聊天机器人、每一个 AI Agent、每一个多轮对话系统都按这个方式运行。看起来理所当然,模型不存自己的回复,怎么"记住"之前说了什么?

重大发现有时源于一个不起眼的问题。而直到最近才有人问出来:如果存储 AI 自己的回复,反而在拖累它的表现呢?

MIT 在 2026 年 2 月发表了一篇论文来回答这个问题。标题刻意低调——"Do LLMs Benefit From Their Own Words?"——但结论一点都不低调。

测试一个没人质疑过的假设

实验设计很简单,正因如此结果才格外有意思。

研究人员从 WildChat 和 ShareLM 中抽取了真实的、杂乱的、来自实际使用场景的对话——不是精心构造的合成 benchmark,而是真实用户和 AI 系统聊真实话题的记录。他们在四个模型上用两种方式分别跑了一遍:Qwen3–4B、DeepSeek-R1–8B、GPT-OSS-20B 和 GPT-5.2。

 # 条件 A - 标准方式(今天每个聊天机器人都在做的事)  
 context = [user_1, assistant_1, user_2, assistant_2, …]  
 # 条件 B - 省略助手回复(没人尝试过的做法)  
 context = [user_1, user_2, user_3, …]  
 # 去掉所有之前的 AI 回复。只保留人类的消息。  
 # 然后比较质量。就这样。这就是整个实验。

简单,大胆。结果呢?

Removing prior assistant responses does not affect response quality on a large fraction of turns. Omitting assistant-side history can reduce cumulative context lengths by up to 10×.

上下文长度缩减约 10 倍,回复质量几乎不变。多轮提示中 36.4% 完全自包含,根本不需要任何历史记录;约 70% 的对话轮次要么不需要历史,要么仅凭用户消息就能重建上下文。

上下文污染的机制

典型的聊天过程:提一个问题,AI 回复,再追问。

但底层实际发生的事情更可能跟我们的理解不太一样:模型在处理追问时,看到的并不只是新的提问,而是新提问加上它之前给出的每一条回复的全文,包括其中所有的错误、幻觉、措辞偏差,以及几轮前引入的错误假设。

所以模型没有任何特殊标记来区分"这是我自己之前的输出"和"这是可信的外部信息"。它读取自己过去回复的方式,和读取 ground truth 完全一样。第二轮里自信说错的东西,第三轮会在上面继续往下搭,第四轮、第五轮照搬不误——每一轮都进一步偏离事实,同时愈发笃定。

论文给这种现象起了个名字。当模型过度依赖先前的回复,锁定早期的错误、幻觉或文体惯性并将其向后续轮次传播时,称为 context pollution——上下文污染。早期的偏差经由反馈循环不断放大。

MIT 团队选的这个术语很准确。长对话中观察到的质量滑坡并非随机的系统疲劳。

模型自己的声音才是污染源。

从 prompt 中删掉 AI 过去的回复,省下的并不只是算力和 Token 空间,更关键的是切断了模型饮用自己毒水的通路。

大多数对话并不需要想象中那么多历史

去掉 AI 的回复还能拿到质量相当的答案,为什么?论文给出的解释很直观,听完会觉得奇怪为什么没有人更早意识到。

多数对话轮次在本质上是自给自足的,真实多轮对话中 36.4% 的提示完全独立,跟之前的交互没有任何关联。另外约三分之一虽然引用了先前的助手回复,但其中并不包含任何可供模型利用的新信号。

两部分加起来,约 70% 的典型对话中,AI 存储的历史要么是无关噪声,要么更糟——失真的来源。一轮一轮忠实地把模型自己的话回传,大多数时候毫无帮助,有时候反而在拖后腿。

不是"一律删除",而是选择性过滤

别带着"论文让永远删掉所有对话历史"的印象离开。它没有这么说。

研究人员明确指出了一个限定条件。不同模型的表现并不一致:对于开源推理模型——DeepSeek-R1–8B 和 GPT-OSS-20B——有没有助手历史记录,回复质量基本持平;而 GPT-5.2 作为能力更强的闭源模型,移除助手历史确实导致了一定的质量下降。能力更强的模型似乎能从自身先前的上下文中提取更多有用信号,也更擅长利用这些上下文而不被带偏。

论文的主张不是全面省略,是选择性过滤。研究团队为此训练了一个分类器,逐轮判断保留 AI 之前的输出对当前回复究竟有益还是有害。在这种自适应省略策略下,回复质量和上下文缩减同时得到改善。明智的做法不是最大化上下文,而是只保留必要的上下文。

对现有每一个 AI Agent 的影响

AI Agent——那些部署来写代码、浏览网页、管理文件、在循环中回答客户问题的系统——运行起来动辄几十轮甚至上百轮。

每个 Agent 框架都存储完整轨迹:工具调用、中间推理步骤、每一条回复。上下文随对话长度线性增长,触及上限后,Cursor、Claude Code 这类系统开始压缩和裁剪,只为维持运转。这些手段本质上是搭建在一个有缺陷的假设之上的工程补丁。

这项研究指出默认策略应该翻转。问题不该是"什么时候修剪?"而该是"为什么要存储这些?"没有具体且合理的理由,就不要保留助手的回复。这是一种根本不同的设计哲学,会实质性地改变系统的构建方式。

过去数年,行业一直在追逐更长的上下文窗口——128K Token、1M Token,竞赛的主题始终是"装进更多内容"。没有人停下来问过:塞进去的大部分内容是否真的在发挥作用。

模型自己的话,可能是上下文窗口中价值最低的部分;在上下文污染发生时,反而是危害最大的部分。

其他论文中已有端倪

多轮 AI 对话比看起来更脆弱,这不是第一次出现信号。

微软 2025 年发表的研究得出了一组互补的结论:LLM 在多轮欠定义对话中的任务表现平均只有约 65%,比单轮场景下 90% 的表现低了 25 个百分点。论文将这种现象命名为 "lost in conversation"——模型一旦在早期走错方向,不会自我纠正,而是螺旋式恶化。

Chroma 同年发表的研究识别出一个相关现象,称之为 "context rot":随着输入长度增长,模型表现变得越来越不可靠,即便在简单的检索任务上也如此。测试覆盖了十八个不同模型,包括 GPT-4.1、Claude 4 和 Gemini 2.5。所有模型在长输入下都出现了退化——不是平滑的衰减,而是不规则的波动。

另一项关于 "context branching" 的独立研究发现,当上下文在多轮对话中逐渐被污染时,开发者经常遇到"看似合理但实际错误的解决方案",在探索性编程中尤为普遍——早期的错误假设持续累积,且无法在不重新开始对话的情况下回退。

Chroma Research (2025) · "Context Rot: How Increasing Input Tokens Impacts LLM Performance"

Laban et al. (2025) · "LLMs Get Lost In Multi-Turn Conversation" · Microsoft Research

总结

对于日常依赖 AI 工具的使用者——无论是编码助手还是研究型 Agent——这篇论文要求重新审视工作习惯。长对话直觉上让人觉得模型会"更聪明",因为上下文更多。事实恰好相反:对话进行了二十轮的模型很少比一个全新会话更准确,多数时候只是深陷在自己累积的错误里。点击"新建对话"不是在丢失上下文,有时只是在清除毒素。

对于系统构建者,默认的架构——将每一轮对话堆叠到窗口塞满——不仅浪费算力、增加延迟,还在通过自我强化的错误循环主动拉低输出质量。Agent 设计的下一个前沿不在于更好的压缩算法,而在于动态的、选择性的省略。

抛开 10x 的效率增益和架构层面的争论,这项发现还有一层更深的意味。过去几年行业构建了能对话的系统,然后强迫这些系统无休止地听自己说话,默认把自我引用等同于记忆。

证据表明两者并不等价。支撑所有多轮 AI 系统的基础假设多年来未经审视,而在构建下一个十年的 Agent 架构时,一个令人不安的结论浮出水面:有时候,AI 能做的最明智的事,是忘掉它刚才说了什么。

论文

https://avoid.overfit.cn/post/64b53523db514c199ce7b36c120abb39

by Ship X/ TechX

1、RAG介绍

RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合信息检索与文本生成的先进AI架构,其核心在于让大语言模型在回答问题前,先从外部知识库中“查找资料”,再基于查到的信息生成准确、有依据的回答。这种方法有效缓解了大模型常见的知识过时、幻觉等问题。
在这里插入图片描述

1.1、RAG基本原理

RAG的工作流程可分为三个关键阶段:数据准备 → 检索 → 生成,形成一个“先查后答”的闭环机制。

  • 数据准备(索引阶段):将企业文档、网页、PDF等非结构化数据加载并切分为小块(chunking),例如每段300–800字符。 使用嵌入模型(如text-embedding-3-small)将文本块转化为向量,并存储于向量数据库中,便于后续语义检索。
  • 检索阶段(Retrieval): 当用户提问时,系统将问题也转化为向量。 在向量数据库中通过相似度匹配(如余弦相似度)检索出最相关的若干个文本片段。 可结合关键词检索(BM25)与语义检索(DPR)进行多路召回,提升召回率与精准度。
  • 生成阶段(Generation): 将检索到的相关片段与原始问题拼接成提示词(Prompt),输入大语言模型。 模型基于这些“参考资料”生成最终回答,确保内容有据可依,减少虚构风险。

RAG的准确率瓶颈本质上是“检索上下文质量”的瓶颈。如果检索不到正确信息,再强的生成模型也无法给出正确答案。

1.2、RAG应用场景

RAG因其灵活性和高准确性,已在多个领域实现落地应用,尤其适合需要专业性、实时性、可解释性的场景。

  • 企业知识库问答:员工可通过自然语言查询内部制度、产品手册、项目文档。 无需人工整理,系统自动检索并生成摘要,提升信息获取效率。
  • 智能客服与售后服务:客户咨询产品功能、退换货政策时,RAG可实时检索最新服务条款,避免因信息滞后导致误答。 支持个性化回复,如结合用户历史订单生成定制化建议。
  • 医疗与法律辅助决策:医生可输入患者症状,系统检索最新诊疗指南或临床研究,辅助诊断。律师查询合同条款时,RAG能从历史案例或法规库中提取相关判例,提升合规性。
  • 学术研究与文献综述:研究者提出研究问题后,RAG可快速检索大量论文摘要,并生成初步综述框架。节省查阅资料时间,提高科研效率。
  • 动态内容生成与新闻撰写:结合实时数据(如股市行情、体育赛事结果),RAG可生成带最新信息的报告或新闻稿。适用于财经、体育、舆情监控等对时效性要求高的领域。

1.3、RAG核心技术

RAG的核心技术组成主要包括以下几个关键部分:

  • 信息检索模块(Retrieval Module):负责从大规模文档库中检索与用户查询最相关的文档片段。通常使用向量数据库(如Faiss、Pinecone、Milvus)存储文档的向量表示,通过计算查询向量与文档向量的相似度来实现快速检索。检索算法可以是基于关键词的(如BM25)或基于语义的(如DPR、Sentence-BERT)。
  • 嵌入模型(Embedding Model):用于将文本(文档和查询)转换为固定长度的向量表示,以便进行语义相似度计算。常用的嵌入模型包括:Sentence-BERT(SBERT)、OpenAI的text-embedding模型、通义千问的QwenEmbedding等。嵌入模型的质量直接影响检索效果。
  • 生成模型(Generation Model):通常基于大语言模型(LLM),如GPT系列、通义千问、Llama等。接收检索到的相关文档片段和原始查询作为输入,生成最终的回答。生成模型需要具备良好的上下文理解和语言生成能力。
  • 检索-生成融合机制(Retrieval-Generation Fusion):将检索到的文档片段与原始查询组合成提示(Prompt),输入到生成模型中。这个过程可以是简单的拼接,也可以是更复杂的融合策略,如注意力机制。
  • 向量数据库(Vector Database):用于高效存储和检索高维向量数据。支持快速的近似最近邻(ANN)搜索,是实现大规模文档检索的关键。常见的向量数据库包括:Faiss、Pinecone、Milvus、Weaviate等。
  • 数据预处理与后处理:数据预处理包括文档清洗、分块、去除无关内容等,以提高检索效率和质量。后处理可能包括答案过滤、格式化输出、引用标注等,以提升最终回答的可读性和可信度。这些组件协同工作,使得RAG能够在保持大语言模型强大生成能力的同时,通过外部知识库提供更准确、更可靠的问答结果。

上述组件协同工作,使得RAG能够在保持大语言模型强大生成能力的同时,通过外部知识库提供更准确、更可靠的问答结果。
本文选型 “Milvus(向量数据库)、Qwen(生成模型)、Qwen-embedding(嵌入模型)及SpringAI” 讲述及实践。

2、向量数据库

向量数据库是专门用于存储、管理和高效检索高维向量数据的新型数据库系统,它能将文本、图像、音频等非结构化数据,通过AI模型转化为蕴含语义特征的向量序列,再基于向量间的相似度实现“语义级检索”,解决传统数据库在非结构化数据处理上的局限性,为RAG智能问答、多模态搜索、智能推荐等AI应用提供底层支撑。

2.1、核心工作步骤

  • 数据向量化:生成“特征指纹”。这是向量数据库的前置核心环节,需借助Embedding模型将原始非结构化数据转化为高维向量,同时要平衡向量维度:维度越高特征表达越精细、检索精度越高,但存储和计算成本会指数级增长;维度越低效率越高,但可能丢失关键特征导致精度下降,工业级常规选择文本768-1536维、图像512-2048维。

    • 文本数据:可选用OpenAI的text-embedding-ada-002(通用场景最优,1536维)、国产开源的BGE(性价比之选,768维)、微调后的BERT(细分领域首选)等模型。
    • 图像数据:CLIP(支持文本搜图的多模态适配模型)、ResNet(纯图像特征提取模型)是常用工具。
    • 音频数据:Wav2Vec2(语音转向量)、VGGish(音频场景特征提取)可满足需求。
  • 存储与索引构建:加速相似性计算。向量数据库会将生成的高维向量存储起来,并构建特殊索引结构来提升检索效率,常见索引算法有IVF(倒排文件)、HNSW(分层可导航小世界图)等,它们能大幅降低相似性计算的耗时。
  • 相似性检索:找“最近邻”。当用户发起查询时,系统先将查询内容转为向量,再在数据库中寻找与其“距离最近”的Top-K个向量,常用的距离度量方式有三种:

    • 余弦相似度:最常用,只关注向量方向、忽略长度,适合语义级对比,如文本检索,计算结果取值范围[-1,1],越接近1相似度越高。
    • 欧氏距离:计算两个向量的直线距离,同时考虑方向与长度,适合关注绝对特征差异的场景,如图像检索,值越小相似度越高,需提前对向量进行归一化处理。
    • 点积相似度:计算速度最快,但受向量长度影响大,对向量进行L2归一化后,结果等价于余弦相似度,适合高并发低延迟场景,如实时推荐。

3、Milvus介绍

Milvus 是一款专为高维向量数据设计的云原生向量数据库,广泛应用于人工智能、机器学习和相似性搜索场景。它采用存储与计算分离的架构,具备高可用性、高性能和弹性扩展能力。

在这里插入图片描述

3.1、核心架构层次

Milvus 的系统架构分为四个主要层次:

  • 接入层(Access Layer):作为系统的入口,由一组无状态的 Proxy 组件构成,负责请求路由和负载均衡。
  • 协调服务(Coordinator Service):管理元数据、任务调度和状态同步,包括 Root Coordinator、Data Coordinator 和 Index Coordinator 等。
  • 执行节点(Worker Node):处理实际的数据插入、查询和索引构建等操作,包含 Query Node、Index Node 和 Data Node。
  • 存储层(Storage Layer):负责持久化存储,使用对象存储(如 S3、MinIO)来保存向量数据和索引文件,同时通过 etcd 和 Pulsar/Kafka 管理元数据和日志。

3.2、数据模型与存储机制:

维度Milvus关系型数据库说明
数据组织结构Database → Collection → Partition → Segment → EntityDatabase → Table → RowMilvus 以 Segment 为最小存储单元,支持分片;关系库以页或块为单位
存储介质对象存储(S3/MinIO)+ 元数据存储(etcd)+ 消息队列(Pulsar/Kafka)磁盘文件 + 日志(Redo Log)Milvus 使用对象存储持久化数据,元数据由 etcd 管理;关系库依赖本地存储
索引机制支持多种 ANN 索引(HNSW、IVF、FLAT 等)B-tree、Hash、Bitmap 等Milvus 为高维向量优化索引,支持近似搜索;关系库为低维结构化字段设计

3.3、术语映射关系:

Milvus 术语关系型数据库术语说明
DatabaseDatabase数据库是组织和管理数据的逻辑单元。为了提高数据安全性并实现多租户,你可以创建多个数据库,为不同的应用程序或租户从逻辑上隔离数据。Milvus 在集合之上引入了数据库层,为管理和组织数据提供了更有效的方式,同时支持多租户
CollectionTable数据集合,定义字段结构。用于存储和管理实体的主要逻辑对象。
PartitionPartition集合内的物理分区
SegmentPage / Block定义数据类型和数据属性的元信息。每个 Collections 都有自己的 Collections Schema,该 Schema 定义了 Collections 的所有字段、自动 ID(主键)分配启用和 Collection 说明
FieldColumn字段类型支持标量与向量
EntityRow单条数据记录
IndexIndex向量索引,类型多样

4、Milvus本地部署

4.1、Docker Compose 部署

Milvus 提供了 Docker Compose 配置文件:

wget https://github.com/milvus-io/milvus/releases/download/v2.6.11/milvus-standalone-docker-compose.yml -O docker-compose.yml

sudo docker compose up -d

Creating milvus-etcd  ... done
Creating milvus-minio ... done
Creating milvus-standalone ... done

启动完成后可以访问 Milvus WebUI网址( http://127.0.0.1:9091/webui/ )了解有关 Milvus 实例的更多信息。

4.2、Attu(可视化工具)安装

Attu是 Milvus 官方推出的图形化管理工具,提供直观的可视化界面,方便用户查看和管理向量数据库。通过 Attu,用户可以轻松完成数据库架构设计、数据操作、向量搜索等复杂任务,大大降低 Milvus 的使用门槛。

docker run -d --name milvus-attu \
  -p 8000:3000 \
  -e MILVUS_URL=localhost:19530 \
  zilliz/attu:v2.6

Attu 启动完成后可以访问( http://localhost:8000 ),以图形化方式查看和管理Milvus 实例。
在这里插入图片描述

5、模型本地安装

RAG系统依赖Embedding与Generation两类模型:

  • 嵌入模型(Embedding Model):用于将文本(文档和查询)转换为固定长度的向量表示,以便进行语义相似度计算。常用的嵌入模型包括:Sentence-BERT(SBERT)、OpenAI的text-embedding模型、通义千问的QwenEmbedding等。嵌入模型的质量直接影响检索效果。
  • 生成模型(Generation Model):通常基于大语言模型(LLM),如GPT系列、通义千问、Llama等。接收检索到的相关文档片段和原始查询作为输入,生成最终的回答。生成模型需要具备良好的上下文理解和语言生成能力。

本文分别选择 “qwen3-embedding” 与 “qwen3.5” 作为嵌入模型与生成模型,Ollama本地安装如下;

admin@Mac-miniM4 milvus % ollama list
NAME                                ID              SIZE      MODIFIED    
qwen3.5:2b                          324d162be6ca    2.7 GB    3 hours ago    
qwen3-embedding:0.6b                ac6da0dfba84    639 MB    4 hours ago    

6、RAG系统设计

RAG 知识库的核心价值在于「结构化检索(关系型)+ 语义检索(向量)」的融合,实体模型设计需同时兼顾关系型数据的结构化关联能力和向量数据的语义匹配能力,既要保证实体间的逻辑关联清晰,又要实现基于语义的精准检索。以下聚焦「关系型 + 向量数据融合」的实体模型设计,包含核心实体定义、数据存储分工、关联逻辑、落地实现四大核心模块。

6.1、核心设计原则(融合版)

  • 分工明确:关系型数据库(MySQL)存储「实体元数据、关联关系、检索过滤条件」,向量数据库(Milvus)存储「文本语义向量」,避免单库承载所有压力;
  • 双向关联:关系型数据与向量数据通过唯一 ID(chunk_id)绑定,支持「从关系型维度筛选→向量语义检索」「从向量检索结果→回溯关系型元数据」;
  • 轻量化融合:向量数据仅存储核心检索单元(Chunk)的向量,不冗余存储文档 / 实体的全量向量,关系型数据补充向量无法表达的结构化信息(如实体类型、文档来源)。

6.2、核心实体模型(关系型 + 向量融合)

实体分工总览

数据类型存储载体存储内容核心作用
关系型数据MySQL/PostgreSQL文档 / Chunk / 业务实体的元数据、实体间关联关系、检索过滤字段(状态 / 租户 / 类型)结构化筛选、实体关联、结果回溯
向量数据Milvus/PGVector/FAISSChunk 的 Embedding 向量、向量索引(IVF_FLAT/HNSW)语义相似度检索

关系型实体表设计(核心元数据 + 关联)

  • Knowledge(知识库实体,关系型):存储知识库定义元数据,维护知识库Embedding模型、向量数据库设置信息。
  • Document(文档实体,关系型):存储文档级结构化元数据,是所有子实体的根节点,不存储完整内容和向量。
  • Chunk(文本块实体,关系型):
    存储 Chunk 的元数据,仅保留向量 ID(与向量库绑定),不存储原始向量,是关系型与向量数据的核心桥梁。
  • 向量数据模型设计(语义检索核心)
    Milvus 中创建「knowledge_vector_collection」集合,与关系型 Chunk 表的vector_id一一对应:

7、RAG关键代码

7.1、Maven依赖引入

使用SpringAI进行模型与向量数据库集成,需要添加如下依赖:

<!-- milvus -->
<dependency>
    <groupId>io.milvus</groupId>
    <artifactId>milvus-sdk-java</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>

7.2、知识数据向量化入库

核心流程为:「文档分块 → 向量化 → Milvus 入库」

// 1、初始化Embedding模型
EmbeddingModel embeddingModel = OllamaEmbeddingModel
                .builder()
                .defaultOptions(OllamaEmbeddingOptions
                        .builder()
                        .model(EMBEDDING_MODEL_NAME)
                        .dimensions(VECTOR_DIMENSION)
                        .build())
                .ollamaApi(ollamaApi)
                .build();

// 2、知识文档正文分块
List<String> chunks = splitDocument(doc.getContent());

// 3、Chunk文档向量化处理
List<float[]> vectors = embeddingModel.embed(texts);

// 4、知识数据向量化入库
List<JsonObject> vectorData = process(vectors);
UpsertResp upsertResp = client.upsert(UpsertReq.builder()
                .collectionName(collectionName)
                .data(vectorData)
                .build());

7.3、知识相似度检索

核心流程为:「问题向量化 → Milvus 检索」

// 1、问题向量化
float[] keywordVector = embed(List.of(keyword)).get(0);

// 2、向量 检索
SearchReq searchReq = SearchReq.builder()
                    .collectionName(buildCollectionName(kbId))                                  
                    .data(Collections.singletonList(new FloatVec(keywordVector)))  
                    .annsField("contentVector")                                                     
                    .outputFields(Arrays.asList("id", "chunkId", "contentVector"))     
                    .limit(TOP_K_COUNT)
                    .searchParams(Map.of("radius", SIMILARITY_THRESHOLD))   // 相似度阈值
                    .build();
SearchResp searchResp = client.search(searchReq);

7.4、知识库系统交互

知识库系统交互见下文,支持针对文档进行新建、管理、向量化/Embedding、相似度检索等操作。为RAG、
部分截图如下:

  • 知识库管理:
    在这里插入图片描述
  • 知识相似度检索:
    在这里插入图片描述

⚠️

1. 发现经过

  • 配置时间:大前天开启。
  • 具体情况:配置了 GCP Vertex AI,但是由于 openclaw3.2 bug 实际上没有跑通,后面换了别的。昨日发现突然 VertextAi 费用高到 $179 刀,经排查发现是 openclaw 再大前天就被扫了。。
  • 损失金额:短时间内产生了 $179 的高额扣费。

2. 安全建议

强烈建议大家注意安全,不要轻易使用厂商提供的 One-key (一键)脚本! 这种脚本权限往往不可控,极易导致 API 被刷或配置失衡。

3. 现场截图

腾讯云 1

腾讯云 2

一. 前提说明

客观上介绍了个人站 HelpAIO, 为了体验放在文章末尾

二. 使用中转前应该知道的

了解下面的信息, 基本能帮助入门, 避坑

1. 不用中转,自己开账号可以吗

省流: 能的, Claude Code Max20 自己开完一个月, 比任何中转都便宜

  • Claude Code: 多维度风控, 人称 A➗, 严重到肉身在国外开, 正常用都封号. 老号风控较轻, 新号风控很严格, 建议不要直接开 Max20, 分发的话更容易被封; 这个确实不是在传播焦虑(经常能在 v2,推特等地方看到“如何防封”);


2. 中转能不能看到我的数据, 有没有可能卖数据, 恶意投毒

省流: 理论上能, 实际站长更想赚钱.

使用中转站就相当于 HTTPS 中间人攻击, 理论上能实现的数据收集, 也能投毒.

我个人大概想法是去饭店不能去后厨看, 否则可能吃不下饭, 尽量找靠谱的馆子吃饭.

对于大型中转来说, 稳定本身就是一种商誉价值.


3. 中转倍率是什么

中转站一般面向国内用户, 倍率是模型的美元价格转成人民币计价后的比例.
一般默认 1 元=1 美刀, 也就是 1:1, 下面是一个示例.

  • 1 倍:1 元 换 1 美元
  • 1.5 倍:1.5 元 换 1 美元
  • 7 倍:7 元 换 1 美元


4. 中转渠道说明

省流: 一定要问清楚中转提供的是什么渠道, 官方和逆向价格差 5~6 倍.

在一切开始前, 要先介绍渠道, 渠道大概分为两种.

  • 官方渠道:
    • 来源: 如Claude Max20x 订阅, Claude 官方 API, Aws, Azure这种官方或一线服务商
    • 优点: 公认效果最好, 模型能力最强, 但 Claude 官方订阅仅限 Claude Code 中使用(甚至不支持自家 sdk 用)
    • 缺点: 普遍较贵, 一小时 20~30 块正常, 建议选购价, 0.85~1.5 元每刀
  • 逆向渠道:
    • 来源: 如 Kiro, Cursor, Windsurf, Awsq, Warp 等一些编辑器或终端本身集成了, 逆向出来给客户用
    • 优点: 可以在 Claude Code 外面使用, 价格一般是官渠的 0.2~0.3 倍, 少数如反重力模型能力很强的可以到 0.6 倍率;
    • 缺点: 大部分逆向模型能力有缺陷, 比不上官方
      • 智商低: 逆向渠道可能带固定的提示词, 能力不如官方
      • 没缓存: 有些渠道没缓存, 缓存是站长加的(比如写死 80%~88%)
      • 工具调用失败: MCP, Skill, Tool 调用失败, 或调用也无法正常完成任务
      • 上下文短: 比如 Claude Code 官方是 200K 上下文, 逆向渠道可能是 128K
      • 断流: 经常用着用着就断了


5. 中转会不会掺假

省流: 会的, HelpAIO 发现过, 包括前几天都有论文实锤了.

问就是上游掺假

中转为了提高 SLA 可用率, 除了自己的号池外, 还会找一些其他渠道, 也就是上游, 这个客观存在
包括中转站之间都可能互为上游.

现在普遍情况就是, 如果被用户发现就说是其他渠道, 上游的锅.
大概就是: 上游可能谈的时候给的是 max, 等用了就会给你惨点儿逆向, 类似直播带货的 AB 货.

当然也有站长自己发现, 然后主动公告给用户退款.

(1) 怎么惨?

  • 正常官方, 官方挂了逆向
  • 官方+逆向: 混着卖, 比例不定, 看站长良心, 有可能 9:1, 有可能 1:9
  • 官方+其他模型
  • 其他模型(GLM, DeepSeek, Gemini)

(2) 几种情况

  • 最好: 站长主动发现自己的上游渠道有问题, 主动公告并退款
  • 一般: 问是不是纯官方, 会说惨的, 或者沉默
  • 略差: 被用户发现, 答复上游惨的
  • 差的: 后台偷偷换, 用户发现就 T 了


6. 中转好不好的核心

  • 渠道: 上面已经说了
  • 价格组成:
    • 输入: 读取文件的花费
    • 输出: 写入文件的花费
    • 缓存创建: 读过的文件, 可以创建缓存, 后续读取缓存更便宜. 缓存创建价格如 Claude Code, 5 分钟缓存价格是输入的 1.25 倍, 1 小时缓存价格是输入的 2 倍
    • 缓存读取: 从缓存里面读取, 价格是输入的 0.1 倍
  • **缓存率: “价格” 只是一个显眼指标,缓存率同样重要, 缓存率差 10%, 价格便宜的渠道可能更贵
    • 参考缓存率: 一线中转 Claude Code 缓存率 80%以上, Codex 缓存率 85%以上
    • 统计缓存率:
      • 网页的Claude Code Hub: 网页版, 适合团队用户, 可部署在服务器或 Docker
      • HelpAIO 开源的aio-coding-hub: Tauri2 开发的本地客户端, 支持 Mac, Win, Linux
  • 可用率: 价格再低, 不可用等于 0

上面的信息, HelpAIO都有

  • 价格收集, 比价: 目前主要收集 Claude Code 官方渠道(Max)
  • 可用率检测: 7*24 小时不间断检测 Claude Code, Codex 可用率
  • 渠道说明: 官方, 逆向, 官逆混用
  • 优缺点, 近期体验: 自己作为用户的一些体验分享


7. 其他风险

  • 中转作为下游, 受到上游政策影响, 可能随时调整价格.
  • 中转可能随时不可用, 如某 8 站之前经常出现.
  • 中转可能随时跑路, 某 P 站至今退款难, 甚至起诉用户(太抽象了); 某 8 站持续不可用, 停摆两个月, 不过近期开始恢复并退款.


8. HelpAIO 是怎么排名的

  • 基础分
    • 服务设施分 65%: 后台有 50+个指标, 所有中转都在同一指标下进行打分得出(个人深度使用的经验看服务设施非常重要!).
    • 模型价格分 35%: 模型价格便宜, 分越高.
  • 动态排名: 最终排名=基础分✖️3 日模型可用率, 防止宕机很久了排名还很高.
  • 新站收录: 收录小于 3 天, 权重额外✖️0.8, 收录大于 3 天小于 7 天权重额外✖️0.9(测试无法 24 小时不间断, 降权是为了收集可用率).
  • 渠道争议: 发现模型与描述渠道不符(比如承诺 Max 渠道, 惨逆向), 前 10 天权重额外✖️0.3, 后 20 天线性恢复.
    Xnip2026-03-08_14-22-18.png


三. 写在最后

HelpAIO 是我第一个创业项目, 借着 AI 的东风, 也说一些迭代到现在的一些想法.
一家之言, 欢迎讨论.

code is cheap, show me the idea

不知道大家知不知道, 微舆这个开源项目作者发布 3 个月被盛大陈天桥投资 3000 万, 这个项目就是 idea 价值的一个体现

对于陈天桥来说他真的是看好这个项目吗, 个人感觉是一种更多是"紧迫感", 自己不革命, 就要被别人革命的紧迫感

是否是真的其实不是关键, 但能看到的是AI 是工业革命级别的机会, 不断涌现项目, 可以说 AI 缩小了差距, 有 idea 和行动力, 比单纯的开发能力更重要.

不要有完美的"执念"

很多开发者对自己有很高的要求, 要搞得满足自己的要求才发布, 结果搞着搞着自己怎么都不满意, 最终放弃了.

但 AI 来了, 试错的成本已经无限降低, 现在一个天能完成以前一个周工作, 今天不发布, 明天可能就被别人发布了

快速验证接受市场检验越来越重要

重视用户的反馈

作为 PM, 要乐于接受用户的反馈, 合理的规划需求.

我特别感谢一个网友,这个网友对当时那个版本的 HelpAIO 评价大概意思是: "有用但有点儿花里胡哨, 没有重点"

是这个评价让我快速优化了几个大版本, 实用性增强了不少

快速迭代

AI 磨平了差距, 也带来了弊端, 产品一旦在市场上被发现, 可能就会被快速 copy.

你的项目可能好, 但是可能不如别人会营销. 一定要重视营销, 快速迭代. 如最近出现的openclaw 三省六部开源项目疑似抄袭 原作者 300star, 而该仓库 5000star

总之要快速持续迭代.

最后欢迎大家使用 HelpAIO 了解中转, 希望能帮助大家选到合适的中转站.
中转评测: https://www.helpaio.com/transit

中转比价: https://www.helpaio.com/transit/compare

image.png

中转可用率: https://www.helpaio.com/transit/availability

image.png

👉 访问地址:免费 SSL 证书签发

前言

兄弟们,最近运维圈有个大事:2026 年 3 月 15 日起,行业新规正式生效。原本能管一年的付费证书,最长有效期也被强行砍到了 200 天

这就非常尴尬了:以前很多人花钱买证书是为了“一年才折腾一次”,现在既然连付费的都要半年折腾一回,那跟 90 天有效期的 Let's Encrypt 相比,手动更新的性价比已经彻底没了。

既然横竖都要频繁折腾,为什么不直接搞个“全自动续期”?上周我因为忘记续期导致子域名报不安全,被吐槽了一顿,痛定思痛,我自己撸了一个自动化工具分享给大家。

为什么要搞这个?

目前市面上的工具要么太笨重(要装各种 Certbot 依赖、跑命令行),要么太封闭(云厂商工具只管自家的,跨云就不灵了)。

我的需求很简单:

  1. 别让我注册(这种救急工具,注册流程真的很拦人)。
  2. 别让我手动改 DNS 验证(手动加 TXT 记录太反人类,还容易忘删)。
  3. 申请完能直接拿走,也可以一键托管。

功能亮点

  • 🚀 免注册领证:输入域名和解析商 API,后台自动跑脚本,直接出证书 ZIP 包(含有 .crt 和 .key),拿走即用。
  • ☁️ 多云适配:目前跑通了阿里云、腾讯云的 DNS API,自动添加验证记录并自动删除,保持解析列表干净。
  • 🛠️ 自动化托管:你可以选择“拿到证书就走”,也可以一键开启“自动托管”,以后每 90 天它会自动去跑挑战并续期,你只需要坐收通知。

操作流程

  1. 输入域名:比如 yourdomain.com
  2. 选择解析商:目前支持阿里云、腾讯云。
  3. 填入 API Key:为了安全,强烈建议去云商后台开一个只具备“DNS 修改权限”的子账号(RAM/CAM),别用主账号 Key。
  4. 一键生成:后台异步调用逻辑,自动修改 DNS 并向 CA 机构发起挑战。
  5. 下载 & 托管:拿到证书后,可以顺手勾选“自动续期”,从此彻底告别证书焦虑。

最后

这个小工具目前部署在 AWS 上,还是 MVP 阶段,界面走极简风格。大家如果正好有证书快到期的,欢迎来“救急”测试,反馈 Bug:

👉 访问地址:免费 SSL 证书签发

PS: 暂时只做了基础功能。如果大家有需要增加其他解析商(如华为云、Cloudflare)支持的,可以在评论区留言,我在线蹲一个反馈!


标签: #SSL证书 #HTTPS #自动化运维 #阿里云 #腾讯云 #acme.sh #后端开发

🎵 你的听歌历史,不应只是流媒体服务器上的冷数据

大家好,作为一名 macOS 深度乐迷,我一直觉得:音乐不仅是流动的空气,更是我们生命中不曾停歇的数字资产。

然而,目前的流媒体平台( Apple Music, Tidal, Qobuz 等)往往将我们的听歌记录封锁在各自的围墙内。如果你使用 AudirvanaRoon 追求极致音质,这些宝贵的聆听痕迹更是难以被统一记录和深度挖掘。

于是,我用 Go 编写了 SonicLens (音眸)


✨ 什么是 SonicLens ?

SonicLens 是一架专为 macOS 用户打造的“声之透镜”。它静默地守候在播放器之后,通过高频采样与无感监控,将你的每一次聆听凝结为属于你个人的、跨平台的音眸轨迹

🔗 GitHub: https://github.com/vincentchyu/sonic-lens


🚀 核心亮点

  • 🛡️ 数据资产化: 所有播放数据通过 SQLite 、MySQL 存储在本地,彻底摆脱平台限制,你的数据你做主。
  • 🎧 多平台无感监控: 基于 Go 并发特性,完美支持 AudirvanaRoon 以及 Apple Music 的实时状态采集。
  • 👁️ 音眸智能洞察 (Sonic Insight): 接入 AI 大模型( Gemini/Ollama 等),对歌词进行深度情感与语义解析,帮你从文字维度重新认识每一首歌,尤其是小语种。
  • 实时交互仪表板: 采用 WebSocket 架构,秒级同步播放状态(比特率、封面、进度等),UI 追求极致的设计感。
  • 📮 一键分享印记: 生成带有封面的 AI 见解海报,让你的聆听瞬间充满仪式感。


🛠️ 技术侧写

作为一个程序员,我在实现过程中加入了一些好玩的细节:

  • 使用 Goroutines 为每个播放器开启独立监听。
  • 通过 AppleScript 实现对底层播放器的无感采样。
  • 遵循 Last.fm 协议实现 Scrobble 逻辑,并使用 Redis 进行状态预测加速。
  • 前端基于 SSE (Server-Sent Events) 实现 AI 解析结果的流式呈现。


📸 效果展示

(附上 README 中的几张截图)

项目展示
AI 解析展示 1
AI 解析展示 2
播放展示


📢 结语

这个项目是我对“科技与人文”结合的一次尝试。如果你也是对音质有追求、对数据有执念的 macOS 用户,欢迎试用并提出你的建议!

如果觉得还不错,也欢迎点个 Star 鼓励一下。

再次感谢大家的时间。


GitHub 地址:https://github.com/vincentchyu/sonic-lens


小红书可以搜索 #Soniclens #音眸轨迹 词条

今日速览

  1. TestSprite 2.1:AI 团队的自动化测试管家,速度提升 5 倍。
  2. Copperlane:用 AI 秒批贷款,告别漫长等待。
  3. Codex Security:代码安全守护者,自动揪出漏洞。
  4. FasterGH:GitHub 镜像加速器,浏览快如闪电。
  5. 21st Agents SDK:一键集成 AI 代理,让应用秒变智能。
  6. Variant:创意无限的设计灵感库,滑动即得。
  7. LTX Desktop:本地开源视频编辑器,GPU 加持 AI 生成。
  8. Thinking Line:AI 涂鸦转矢量,轻松制作解说视频。
  9. Tailwind Form Builder:拖拽生成响应式表单,无需登录。
  10. NotchPad:Mac 刘海里的安全记事本,点击即用。


1. TestSprite 2.1

这款神器能帮 AI 原生团队自动搞定测试,让开发流程无缝衔接。

  • 直接连到 IDE,自动生成完整测试套件,无需手动操作
  • 测试引擎提速 4-5 倍,几分钟内完成全量测试
  • 可视化编辑器支持点击查看实时快照,即时修复问题
  • 集成 GitHub,PR 时自动运行测试,失败则阻止合并

热度:🔺401

TestSprite 2.1

访问官网 Product Hunt 详情


2. Copperlane

它用 AI 重构贷款流程,把几小时的审批压缩到秒级。

  • AI 助手 Penny 优化利率定价,指导借款人
  • 自动验证文档,大幅缩短处理时间
  • 基于人工智能的贷款发放系统,提升效率

热度:🔺276

Copperlane

访问官网 Product Hunt 详情


3. Codex Security

你的代码安全管家,自动扫描漏洞并给出修复方案。

  • 发现代码库中的潜在漏洞
  • 验证漏洞真实性,提出修复建议
  • 帮助团队聚焦关键问题,加速发布

热度:🔺274

Codex Security

访问官网 Product Hunt 详情


4. FasterGH

给 GitHub 加个涡轮,用镜像界面实现低延迟浏览。

  • 基于 Convex 提供实时缓存和同步
  • 保持 GitHub 为数据源,提升读取速度
  • 优化开源代码浏览体验

热度:🔺224

FasterGH

访问官网 Product Hunt 详情


5. 21st Agents SDK

最快的方式把 AI 代理塞进你的应用,省去基础设施烦恼。

  • 用 TypeScript 定义代理,一键部署
  • 内置流媒体、会话管理和计费功能
  • 提供即用型聊天界面,专注差异化
  • 获 Y Combinator 支持

热度:🔺187

21st Agents SDK

访问官网 Product Hunt 详情


6. Variant

告别解释,直接滑动获取无尽设计灵感,像有个创意总监随时待命。

  • 直观展示设计选项,无需描述需求
  • 捕捉氛围感,应用到你的项目中
  • 提供丰富视觉选择,激发创意

热度:🔺134

Variant

访问官网 Product Hunt 详情


7. LTX Desktop

一款本地运行的开源视频编辑器,GPU 加速 AI 生成,免费又强大。

  • 非线性视频编辑,结合设备端 AI 技术
  • 完全免费开源,本地运行不依赖云
  • 基于 LTX-2.3 版本,GPU 优化提升性能

热度:🔺125

LTX Desktop

访问官网 Product Hunt 详情


8. Thinking Line

用 AI 把涂鸦变成可编辑的矢量图和视频,让创意动起来。

  • 将提示转换为 SVG 文件,支持编辑
  • 生成引人入胜的解说视频
  • 基于人工智能进行图像矢量化

热度:🔺112

Thinking Line

访问官网 Product Hunt 详情


9. Tailwind Form Builder

拖拽几下,就能生成干净漂亮的响应式表单,连登录都免了。

  • 免费拖拽构建器,快速创建 HTML 表单
  • 专为 Tailwind CSS 设计,导出纯净代码
  • 支持 HTML、React 或 Vue,无平台限制
  • 无需注册登录,即用即走

热度:🔺103

Tailwind Form Builder

访问官网 Product Hunt 详情


10. NotchPad

把 MacBook Pro 的刘海变成随时可用的安全记事本,点击即写。

  • 集成在刘海区域,无需切换窗口
  • 结合便签、剪贴板管理和代码片段功能
  • 支持 AES-256 加密、1Password 和 Touch ID
  • 数据本地保存,15 天免费试用后一次性付费

热度:🔺98

NotchPad

访问官网 Product Hunt 详情

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

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

AutoPiano(自由钢琴)是一款网页钢琴模拟器,支持电脑键盘和鼠标演奏,内置多种乐器音色与教学曲谱,零基础也能轻松上手。

01.png

在飞牛 NAS,找到“文件管理”App,在“docker”文件夹里创建一个“autopiano”文件夹。

02.png

然后打开“Docker”App,在“Compose”页面创建一个项目。

相关配置如下图所示。

03.png

代码如下:

services:
  autopiano:
    image: wbsu2003/autopiano:latest
    container_name: autopiano
    ports:
      - 2338:80
    restart: unless-stopped

这里配置的端口是 2338,如果这个端口和你其他项目冲突了,可以设置成别的端口。

项目构建成功后,在浏览器访问 NAS的IP:2338 就可以弹琴了。

04.png

AutoPiano 内置了一些琴谱,你跟着琴谱打字就可以弹出一首曲子了。

你就弹吧~


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

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

往期推荐:

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

在中国银行 app 首页即可看到该活动。
如果有实际消费可以实际消费,如果没有的话,可以给余额宝或是微信零钱通充 10000,然后再提现。
大部分是实际消费的。
活动内容具体看介绍吧。

image

image

11 月份的又报名了。

有人中一等奖、二等奖,我就不上传图片了,等自己中了再上传实际的图片。

即上次 openai 出现 bug 重置额度后,今天又重置了额度。官方人员说是因为有用户反馈额度消耗过快,所以重置了。

切换 gpt-5.4 后,额度消耗真的很快,我以为是因为 5.4 输出快导致的,没想到很可能是一个 bug 。

这世界果然都是草台班子。

南瓜叶片病害图像分类数据集(2000张图片已划分、已标注)| AI训练适用于目标检测任务

本数据集共包含 2000 张南瓜叶片图像,涵盖 5 种常见病害与健康叶片状态。每张图像分辨率为 640×640 像素,图像质量清晰,适用于深度学习图像分类任务。
在这里插入图片描述

数据集已经完成标准训练集划分:

  • 训练集:1400 张
  • 验证集:400 张
  • 测试集:200 张
    应用:
    疾病诊断:开发机器学习模型,自动检测和分类南瓜叶部病害。
    农业研究:研究各种南瓜病害的视觉症状,以增进理解和管理实践。
    教育工具:为农业科学和植物病理学教育提供资源。
    数据可访问性:
    数据集以标准图像格式(例如 JPEG、PNG)提供下载。数据集按病害类别和健康叶片分类,方便访问和整理。
    同时提供 中英文类别名称,方便国内外研究者使用。

示例训练命令(YOLOv8 分类任务):

yolo classify train data=main\datasets model=yolov8n-cls.pt epochs=200 imgsz=224

数据集下载

链接:https://pan.baidu.com/s/1Bfs0wgwggHTQhdsNmLbIZw?pwd=8jva
提取码:8jva 复制这段内容后打开百度网盘手机App,操作更方便哦
classes.txt
"Bacterial Leaf Spot"
"Downy Mildew"
"Healthy"
"Mosaic Disease"
"Powdery Mildew"

中文名称

英文类别中文类别
Bacterial Leaf Spot细菌性叶斑病
Downy Mildew霜霉病
Healthy健康
Mosaic Disease花叶病
Powdery Mildew白粉病

数据集介绍

数据集概述

南瓜是重要的经济作物之一,在世界范围内广泛种植。然而,在南瓜种植过程中,各类病害经常会对产量和品质造成严重影响。及时发现并识别南瓜叶片病害,对于提高农业生产效率、减少农药滥用以及保障作物健康具有重要意义。

本数据集专门针对 南瓜叶片病害图像分类任务构建,包含 2000 张高清叶片图像,涵盖 五类常见病害与健康状态。数据集经过人工筛选与整理,并按照机器学习训练流程完成标准数据划分,可直接用于深度学习模型训练与评估。

数据集具有以下特点:

  • 图像分辨率统一(640×640)
  • 类别划分清晰
  • 数据量适中
  • 中英文标签支持
  • 适用于多种深度学习框架

研究人员可以利用该数据集训练图像分类模型,实现对南瓜叶片病害的自动识别。


背景

在现代农业生产中,植物病害是影响作物产量和质量的重要因素之一。南瓜在生长过程中容易受到多种真菌、细菌以及病毒病害的侵袭,例如:

  • 白粉病
  • 霜霉病
  • 细菌性叶斑病
  • 花叶病毒病

传统的病害识别主要依赖农业专家或农户通过肉眼观察叶片症状进行判断,这种方式存在以下问题:

  1. 主观性较强
    不同人员判断结果可能存在差异。
  2. 效率较低
    大面积农田人工巡检耗时耗力。
  3. 专业门槛高
    普通农户难以准确识别不同病害。

随着人工智能和计算机视觉技术的发展,利用深度学习模型进行植物病害识别已经成为农业智能化的重要研究方向。通过构建高质量的叶片病害图像数据集,可以训练自动识别模型,实现:

  • 农作物病害自动诊断
  • 智能农业监测
  • 精准农业管理

该南瓜叶片病害数据集正是在这一背景下构建,为农业智能识别研究提供可靠的数据基础。


数据集详情

在这里插入图片描述

1 数据规模

本数据集共包含 2000 张南瓜叶片图像

数据集划分如下:

数据集数量
训练集1400
验证集400
测试集200

所有图像分辨率为:

640 × 640

2 数据组织结构

数据集采用 图像分类常见的目录结构

dataset/
│
├── train
│   ├── Bacterial Leaf Spot
│   ├── Downy Mildew
│   ├── Healthy
│   ├── Mosaic Disease
│   └── Powdery Mildew
│
├── val
│   ├── Bacterial Leaf Spot
│   ├── Downy Mildew
│   ├── Healthy
│   ├── Mosaic Disease
│   └── Powdery Mildew
│
└── test
    ├── Bacterial Leaf Spot
    ├── Downy Mildew
    ├── Healthy
    ├── Mosaic Disease
    └── Powdery Mildew

每个类别文件夹中存放对应类别的图像数据,方便直接用于深度学习训练。


3 图像格式

数据集采用标准图像格式:

  • JPEG
  • PNG

图像质量较高,适合用于模型训练和研究。


4 数据特点

本数据集具有以下特点:

1 病害类型明确

数据集包含五种典型类别:

  • 细菌性叶斑病
  • 霜霉病
  • 花叶病
  • 白粉病
  • 健康叶片

类别区分明显,有利于模型学习特征。

2 图像质量统一

所有图像统一为 640×640 分辨率,减少数据预处理成本。

3 适合分类任务

数据集结构天然适合:

  • CNN 图像分类
  • YOLOv8 分类模型
  • Transformer 视觉模型

在这里插入图片描述

适用场景

该数据集适用于多种研究和应用场景。

1 植物病害自动识别

可以训练深度学习模型,实现南瓜叶片病害自动检测,例如:

  • 白粉病识别
  • 霜霉病识别
  • 细菌性叶斑病识别

帮助农户快速判断作物健康状况。


2 智慧农业系统

在智慧农业系统中,可结合:

  • 农田摄像设备
  • 无人机巡检
  • 手机拍照识别

构建实时农作物健康监测系统。


3 农业科研

该数据集可用于研究:

  • 植物病害图像特征
  • 深度学习分类模型性能
  • 农业视觉识别算法

为农业智能化研究提供数据支持。


4 教学与课程实验

适合用于以下课程教学:

  • 计算机视觉
  • 深度学习
  • 农业信息化
  • 植物病理学

学生可以利用该数据集完成课程实验或毕业设计。


心得

在构建植物病害数据集的过程中,可以明显感受到 数据质量对模型性能的重要影响。相比复杂模型结构,高质量的数据往往能够带来更稳定的训练效果。

在农业视觉任务中,还存在一些典型挑战,例如:

  • 病害区域较小
  • 背景复杂
  • 光照条件变化
  • 叶片形态差异

因此在训练模型时,可以结合以下技术提升效果:

  • 数据增强(旋转、翻转、裁剪)
  • 迁移学习
  • 注意力机制
  • 轻量化模型设计

通过合理的数据处理和模型优化,可以显著提高植物病害识别的准确率。
在这里插入图片描述


结语

随着人工智能技术在农业领域的不断发展,利用计算机视觉进行植物病害识别已经成为智慧农业的重要研究方向。高质量的数据集是推动相关技术进步的重要基础。

南瓜叶片病害图像分类数据集提供了 2000 张高质量叶片图像,并涵盖 5 种典型病害类型,可广泛应用于图像分类模型训练、农业科研以及教学实践。

希望该数据集能够为农业智能识别研究提供帮助,推动农业信息化与智能化的发展。

事出有因:

我是一个有十年记账习惯的人,尤其最拿手零散流水账(日常每天大概 10-20 笔之类的量),但从不指望说记账能让你省钱之类的屁话,主要是记录自己的行为轨迹和部分大额特殊支出之类,以方便回溯记忆和跨年回顾。也使用过不少记账 app 。不是它们做得不好,要不就是太复杂,比如我一打开 app 就天花乱坠的,然后让我点点点搞一堆东西,再加上弹广告,甚至再来点误点击,我真的受不了。

更有甚者,就是不永远不知道你每天用的 app 能活多少天,万一不让导出数据(或者要买很贵的套餐之类),你数据说没就没了,完全没有安全感。

折腾之路:

不过对于我来说主要还是嫌弃麻烦,所以十年之间,我尝试了不少小工具,但是最后还是选择了基础表格 + 纯文本方式记账。

img

前些年主要用印象笔记,记不太清了,反正最开始免费用了好几年,后来为了支持也付费升级了高级用户。其实就差最后一点——我希望能支持表格的「 SUM 」加法功能,说白了就是表格流水账然后来个每日总额计算。然后要收费,还不便宜。

接下来两年转战了 Notion ,虽然日常笔记也记得多,但使用频率最高的部分还是表格记账。一样的结局:Ai 统计功能最后也需要付费,也不便宜。虽然可以跟 GPT 打配合去问询,但还是太麻烦了。

img

这个时候救星来了,就是「 Antigravity + Claude Opus 4.5 Thinking 」,我 Vibe 了一天,直接给我干了个可以跑的 demo 。要知道对于一个不会 Xcode 系任何编程语言的设计师来说,这玩意儿太梦幻了,让你有冲动直接干到底了。

所以接下来我有时间就开始干,当正事开始做,做自己之前不敢想的事情,一边开心一边加码做。从原型思考,到 Logo 设计,到品牌定位,到商标注册。从第一次接触 swift 实现 appleid 登录,到一脸懵逼开始 vibe 同步系统; 从海外 Gemini 到心忧数据安全问题切换千问,太难了,但是也太有趣了,磕磕碰碰真的一路干到了发布 Testflight 0.1.0 的公开测试版。

所以 记趣 · Kicho 是什么:

img

是一个利用 Ai 帮你轻松记流水账、分析消费的 iOS app (见谅暂时能力有限只支持 iphone 🥲 )。

  • 风格定位:极简,本人很烦无用的交互所以能砍的都尽量砍了,目前版本是基于自己实际习惯完成的
  • 免费功能:Ai 智能分类 / 消费分析(暂未开放) / 数据导出 / 多语言 / 隐私优先
  • 技术栈:Swift 原生 / 阿里云 RDS Supabase / 千问家族模型
  • 收费计划:目前用量小,暂时没啥野心,希望喜欢的朋友一起免费来玩来用来体验,如果要收费的话也可能是大量消耗 token 和服务器资源功能开放的时候吧。

如何下载:

  1. 需要下载 Testflight 。
  2. 需要更新到最新系统 ios 26.2 。
  3. 记趣 Kicho 测试版的公开链接:

https://testflight.apple.com/join/MDYUsbUX

也希望认识同好的 V2exer

img

望 V2exer 大神们轻喷 🙏

Shotcut 26.2 (Linux, macOS, Windows) - 免费开源视频编辑器

free, open source, cross-platform video editor

请访问原文链接:https://sysin.org/blog/shotcut/ 查看最新版。原创作品,转载请保留出处。

作者主页:sysin.org


Shotcut 是一个免费的、开源的、跨平台的视频编辑器。

Shotcut is a free, open source, cross-platform video editor.

sysin

关于

Shotcut 是适用于 Mac、Linux 和 Windows 的免费、开源、跨平台视频编辑器。

Shotcut 最初于 2004 年 11 月由 Charlie Yates 构思提出。Charlie Yates 是 MLT 的联合创始人之一,也是最初的首席开发者。当前版本的 Shotcut 是由另一位 MLT 联合创始人、现任首席开发者 Dan Dennedy 进行的完全重写。Dan 希望基于 MLT 创建一款新的编辑器,由于他非常喜欢 Shotcut 这个名字,因此决定沿用它。他希望通过这个项目来实践 MLT 新的跨平台能力,尤其是与 WebVfx 和 Movit 插件结合使用。

Dan Dennedy

Shotcut 与 MLT 的首席开发者

特性

Features

  • 广泛的格式支持

    得益于 FFmpeg,支持数百种音频和视频格式及编解码器。无需导入即可直接编辑,实现原生剪辑,并支持在同一项目中使用多格式时间轴、不同分辨率和帧率 (sysin)。对多种视频格式提供逐帧精确定位(Frame accurate seeking)支持。

  • 设备与传输选项

    支持 Blackmagic Design 的 SDI 和 HDMI 输入及预览监看。支持屏幕、摄像头和音频采集,网络流播放。最高支持 4K 分辨率,并可从 SDI、HDMI、摄像头、JACK 与 Pulse 音频、IP 流、X11 屏幕以及 Windows DirectShow 设备进行采集。

  • 简洁直观的界面

    提供多个可停靠与可分离的面板,包括详细的媒体属性、带搜索功能的最近文件、带缩略图视图的播放列表、滤镜面板、历史视图、编码面板、任务队列,以及 Melted 服务器和播放列表。同时支持从文件管理器直接拖拽资源。

新增功能

2026 年 2 月 26 日

版本 26.2.26 现已开放下载

修复内容(Fixes)

  • 修复了在使用 Qt 6.10.1 时,将较长视频添加到时间轴会导致崩溃的问题(v26.1 中引入)。
  • 修复了在 Windows 上,使用 HEVC 视频源并启用“设置 > 预览缩放 > 使用硬件解码器 + 预览缩放”时,底部出现黑色或绿色条的问题(v26.1 中引入)。
  • 在启用“视图 > 显示图标下方的文本”时,将“生成(Generate)”恢复到主工具栏(v26.1 中发生变更)。
  • 修复了 RGB Shift 视频滤镜中的崩溃问题(v25.12 中引入)。
  • 修复了 FLAC 导出时音频时长错误,导致播放器中拖动条不可用的问题(v25.12 中引入)。
  • 修复了在未选择任何项目时 (sysin),启用以下播放列表操作会导致崩溃的问题:

    • GoTo
    • Move Up
    • Move Down
    • Add Selected to Timeline
    • Add Selected to Slideshow
    • Sort By Name
    • Sort By Date
  • 修复了反向任务(reverse job)中“在文件中显示(Show In Files)”的问题。
  • 修复了在 macOS 上选择“导出 > 编码器 > h264_videotool”时,无法可靠地将 B 帧设置为 0 的问题。
  • 修复了“文本:打字机(Text: Typewriter)> 位置与大小(Position & Size)”中的关键帧无法正常工作的问题。

更改内容(Changes)

  • 在文本滤镜的字体对话框中,新增对下划线和删除线选项的支持。
  • 在字幕中新增搜索字段。
  • 在时间轴轨道上,按住 Alt 键并点击“静音(Mute)”或“隐藏(Hide)”时,可切换所有其他轨道的状态。
  • 新增按住 Shift 键并滚动鼠标滚轮来缩放播放器的功能 (sysin)。
  • 新增“播放列表 > 记录事件(Log Event,Shift+E)”,可在当前源播放器时间点追加一个 6 秒(±3 秒)的片段。
  • 提升了时间轴和关键帧波形渲染的性能 (sysin)。
  • 更改了视频缩放(Video Zoom)视频示波器中鼠标滚轮的行为:

    • 单独滚动滚轮(不按修饰键):垂直滚动
    • 按住 Ctrl:缩放
    • 按住 Alt:水平滚动
  • 移除了“设置 > 播放器 > 去隔行器 > Linear Blend”(已过时,且已在 FFmpeg 中移除)。

下载地址

Shotcut for macOS, Linux, Windows (2026-02-28)

请访问:https://sysin.org/blog/shotcut/

  • macOS (64-bit or ARM64 macOS 11+)

    • macOS Universal
  • GNU/Linux (64-bit Mint 20+, Ubuntu/Pop!_OS 20.04+, Debian 11+, Fedora 32+, Manjaro 20.2+, MX Linux 21+, elementary OS 6+)

    • Linux AppImage x86_64
  • Windows (64-bit or ARM64 Windows 10+)

    • Windows installer

更多:macOS 下载汇总 (系统、应用和教程)

很多人第一次接触中文域名时,都会遇到一个问题:明明输入的是中文网址,复制出来却变成了 xn-- 开头的一串字符。其实这不是乱码,而是域名系统使用的 Punycode 编码。

我做了一个用 Vue 开发的在线小工具——中文域名转码,专门帮助普通用户在中文域名和 Punycode 之间快速互转,打开网页就能用,不需要安装软件。

在线工具网址:https://see-tool.com/chinese-domain-converter
工具截图:

这个工具适合什么场景

  • 注册或购买中文域名前,先确认转码结果
  • 做网站配置时,查看中文域名对应的标准编码
  • 复制链接给他人时,判断域名是否正确
  • 遇到 xn-- 域名时,反查它原本对应的中文内容

怎么使用

  1. 打开“中文域名转码”工具页面。
  2. 在输入框里粘贴中文域名,或者 xn-- 开头的编码域名。
  3. 点击转换,页面会自动给出对应结果。
  4. 复制转换后的域名,用到浏览器、建站平台或解析配置中。

这个工具有什么优点

它会自动清理常见前缀和多余斜杠,比如有些人复制的是完整网址,工具会尽量帮你提取出可处理的域名部分,这样普通用户也不容易输错。

为什么做这个工具

很多域名工具更偏技术人员,普通用户看到一堆专业术语会有压力。我用 Vue 开发这个页面时,重点就是把操作做得更直接:输入、转换、复制,三步完成,不需要懂编码原理也能用。

如果你平时会接触中文网址、建站后台、域名购买页,或者只是想弄明白 xn-- 到底是什么,这个工具会比较实用。


“me stepping down. bye my beloved qwen.”(我卸任了。再见了,我亲爱的千问。)

林俊旸卸任推文

3 月 4 日凌晨,没有任何官方预热与体面的交接仪式,93年出生、阿里巴巴最年轻的 P10 级技术专家、千问(Qwen)核心负责人林俊旸在 X 平台上敲下了这句简短的告别。据传,有 Qwen 团队的同事在得知消息后“伤心地哭了”。

在这个大模型狂飙突进的时代,千问不仅是阿里 AI 战略的皇冠,更是全球开源大模型社区的一面旗帜。而现在,这面旗帜的扛旗人,在凌晨时分独自走下了牌桌。

伴随着他的离开,漫天的猜测如潮水般涌来:空降的高管、Gemini 商业模式的复制、内部算力的枯竭,以及那个让所有开发者倒吸一口凉气的传闻——Qwen 的开源时代,要终结了吗?

【笔者观点】
当一个估值千亿、牵动全球开源生态的核心业务负责人以如此决绝且非官方的方式宣布离职时,任何“和平分手”的公关辞令都显得苍白无力。林俊旸的离开,撕开了科技巨头在 AI 狂热期后最尴尬的遮羞布:当开源的理想主义撞上大厂严苛的商业化 KPI 考核时,天才科学家的纯粹,往往敌不过 CFO 报表里的算计。

一、 资源的傲慢:“无关政治”的权力洗牌

对于林俊旸的突然离职,阿里高层的反应不可谓不迅速。阿里巴巴董事长兼 CEO 吴泳铭、首席人才官蒋芳、阿里云 CTO 周靖人火速召开会议,给出了一个极具大厂标准公关话术的定性:“Qwen 没有收缩,这是一次团队扩张,无关任何政治斗争。”

但事实的颗粒度,往往隐藏在会议的细节里。阿里高层在会上多次强调,千问基础模型是集团当前最重要的事情,无论是基础模型研发,还是底层 infra 建设,都将在集团层面统筹推进,“一定要超越”。

阿里内部会议相关截图

外界盛传,阿里云 CEO 正在对 Qwen 采取更直接的管理与监督,并计划空降一位来自谷歌 Gemini 团队的新负责人。网传阿里正试图复制 Google Cloud 与 Gemini 的闭源商业模式,这无疑触碰了开源社区最敏感的神经。

社区关于闭源与Gemini模式的猜测

更令人匪夷所思的是周靖人在会上坦承的一个“反常识”现状:阿里内部的大模型团队,在算力和招聘名额上居然捉襟见肘,反而不如花钱购买阿里云算力的外部创业公司用得顺畅。

一边是集团口中“当前最重要的事情”,一边是连内部训练算力都要靠边站的资源窘境。

【笔者观点】
所谓“无关政治”,往往是企业内部最激烈政治博弈的代名词。一个反常识的真相是:在云厂商的逻辑里,能立刻带来真金白银收入的外部算力客户,永远比内部烧钱研发的开源团队优先级更高。当高层试图用“空降商业化高管”来接管极客团队,当内部算力分配开始为短期财报让路时,挤走林俊旸的绝不是什么个人职业规划,而是巨头在“要技术名声”还是“要商业变现”这一战略摇摆中的必然牺牲品。

二、 开源的黄昏:大厂容不下纯粹的“技术乌托邦”

林俊旸在技术圈的声望,是靠着一个个熬夜写代码的凌晨真刀真枪拼出来的。他带领团队硬生生向世界证明了一件事:开放权重的开源模型,同样可以与那些投入上千亿美元的闭源实验室保持同等甚至更快的进化速度。

Hyperbolic labs 联合创始人发推回忆并致敬,称这是“一个时代的结束”。

Hyperbolic labs联合创始人推文

社区网友也深情回忆了当他们在北京时间早上六点发布 Qwen 3 的 API 时,林俊旸和他的团队依然通宵达旦在线忙碌的场景。

社区网友致敬Qwen团队

在评论区,“Qwen is nothing without its people(没有了这些人,Qwen 什么都不是)”的呼声一度刷屏,甚至有网友悲观地评论:“阿里跌回 80 不是梦,幸好没买他家股票。”

社区评论区刷屏截图

xAI 研究员 Yao Fu 更是毫不吝啬地称赞其为“AI 发展史中最杰出的领导者之一,Qwen 成为最优秀的开源模型之一,并推动了整个科技行业的进步。”

【笔者观点】
我们必须承认一个残酷的现实:巨头做开源,从来不是为了做慈善,而是为了建立生态壁垒。但随着大模型参数量呈指数级膨胀,训练成本飙升,“赔本赚吆喝”的开源模式越来越难以在集团内部立足。如果 Qwen 真的因此走向闭源,林俊旸的离开就不只是一次人事变动,它标志着中国大模型历史上最具浪漫主义色彩的一段开源长征,被强行按下了终止键。

三、 人才的流失:你追随的是使命,还是公司的 Logo?

面对这场震动 AI 圈的人事地震,前阿里云副总裁贾扬清的点评尤为犀利。他直言不讳地指出:“我们正在进入一个‘人和影响力’比以往任何时候都更重要的时代。能够凝聚社区的技术领导者极其稀缺。无论这些领导者未来走向哪里,社区往往追随的是使命,而不仅仅是公司的标志。

贾扬清甚至用了一个极其经典的段子来讽刺大厂在人才管理上的短视:
CFO:如果我们投入资源培养员工,但他们离开了怎么办?
CEO:那如果我们不培养,而他们留下来怎么办?

林俊旸在离职前,已经开始在 Qwen 内部组建具身智能与机器人小组,试图带领团队在下一代 AI 浪潮中抢占先机。但他最终选择在凌晨挥手作别,留给阿里的是一个群龙无首的社区,和一个前途未卜的战略重心。

【笔者观点】
很多科技巨头至今仍深陷于工业时代的傲慢之中,认为平台是铁打的营盘,人才是流水的兵。但在顶尖 AI 领域,这是极其致命的战略误判。算力可以购买,可以堆叠,但顶级的技术直觉和在全球开源社区一呼百应的号召力,是任何猎头和预算都无法轻易填补的。逼走一个林俊旸,阿里失去的不仅仅是一个 P10,更是全球无数开发者对 Qwen 品牌的信仰。当大厂的体制连一个纯粹的技术天才都无法兼容时,这不仅仅是“一个时代的结束”,更是一场极具警示意味的系统性败局。

👇 欢迎关注我的公众号

在 AI 爆发的深水区,我们一起探索真正能穿越周期的技术价值。
微信搜索 【睿见新世界】 或扫描下方二维码,获取每周硬核技术推文:

微信图片_20260301232734_225_35.jpg

欢迎关注【睿见新世界】