普通视图

发现新文章,点击刷新页面。
今天 — 2026年3月25日首页

解决 Swift Testing 中 DI 容器的竞态条件

作者 RickeyBoy
2026年3月24日 20:38

欢迎给个 star:RickeyBoy-Github

🎬 背景:单元测试不稳定

当项目逐渐扩大,Unit Test 越来越多的时候,必然会出现问题:某些单元测试有时能通过,有时又不行。最麻烦的是有些时候本地运行能通过,在 CI Pipeline 中又通过不了。

通常来讲本地设备和 CI 设备确实很不一样,一个常见的问题就是存在静态条件(Race Condition)的问题,本篇就尝试从根本上解决这类似的问题,并且从原理层面也讲清楚来龙去脉。

🔁 快速回顾:为什么 DI 很重要

如果是在 SwiftUI 上使用 MVVM 的架构,那 DI (Dependency Injection 依赖注入)对你来说肯定不陌生。这里简单回顾一下,为什么要用 DI

不可测试的 ViewModel

final class CheckoutViewModel {
    private let paymentService = PaymentService()  // 硬编码的依赖

    func placeOrder() async throws {
        try await paymentService.charge(amount: 99.99)
    }
}

这个 ViewModel 直接持有了它的依赖。想在测试中把 PaymentService 换成 mock?根本换不了。

可测试的 ViewModel

final class CheckoutViewModel {
    private let paymentService: PaymentServiceProtocol

    init(paymentService: PaymentServiceProtocol) {
        self.paymentService = paymentService
    }
    func placeOrder() async throws {
        try await paymentService.charge(amount: 99.99)
    }
}

现在我们可以在测试中注入 mock,在生产环境中使用真实服务了:

// 生产环境
let vm = CheckoutViewModel(paymentService: StripePaymentService())
// 测试
let vm = CheckoutViewModel(paymentService: MockPaymentService())

生产环境中,ViewModel 连接真实服务。测试中,由 mock 替代:

image.png

道理很简单,小项目用着也没问题。但随着 app 不断膨胀,事情就开始变味了。

💥 MVVM 的依赖问题

构造器注入复杂度爆炸

现实中的 ViewModel 不可能只有一个依赖,随着业务迭代它们只会越来越多:

init(
    paymentService: PaymentServiceProtocol,
    orderRepository: OrderRepositoryProtocol,
    analyticsTracker: AnalyticsTrackerProtocol,
    authService: AuthServiceProtocol,
    featureFlagService: FeatureFlagServiceProtocol
) { ... }

而且如果父级 ViewModel 需要创建子级 ViewModel,那父级就必须知道子级的全部依赖。往下嵌套三层之后再新增一个依赖,你就得一路往上改文件……

SwiftUI 的 @Environment 帮不上忙

SwiftUI 有一个内置的 DI 机制,@Environment

struct CheckoutView: View {
    @Environment(.paymentService) var paymentService  // 可以!
}

看起来挺好。但问题是 @Environment 只能在 View 的 body 里用,不适用于 ViewModel:

class CheckoutViewModel {
    @Environment(.paymentService) var paymentService  // 编译报错
}

所以我们需要一个像 @Environment 一样好用,但能在 View 层之外工作的方案。

🏭 Factory:适配 MVVM 的 DI 框架

Factory 是一个轻量级的 DI 框架,刚好解决了这个问题。ViewModel 通过 @Injected 主动从容器中拉取依赖:

final class CheckoutViewModel {
    @Injected(.paymentService) private var paymentService
    @Injected(.orderRepository) private var orderRepository

    func placeOrder() async throws {
        let order = try await orderRepository.createOrder()
        try await paymentService.charge(amount: order.total)
    }
}

不用传 init 参数,也不用维护依赖链。容器负责创建每个服务,@Injected 在运行时自动解析,ViewModel 压根不需要关心依赖从哪来。

Factory 就像个中间人,根据当前环境决定注入什么:

image.png

ViewModel 只管说"我要什么",Factory 负责"给你什么"。

Container:依赖注册中心

Container 是你定义每个依赖创建方式的地方:

extension Container {
    var paymentService: Factory<PaymentServiceProtocol> {
        self { StripePaymentService() }
    }
    var orderRepository: Factory<OrderRepositoryProtocol> {
        self { OrderRepository() }
    }
}

在生产环境中,@Injected(.paymentService) 解析为 StripePaymentService()。在测试中,你可以覆盖它:

Container.shared.paymentService.register { MockPaymentService() }

SharedContainer:按模块组织依赖

一个全局 Container 小项目够用。但在拥有几十个服务的模块化工程里,它很快就变成了大杂烩。Factory 提供了 SharedContainer,让你按模块拆分管理,就像是文件夹一样:

PaymentSharedContainer
├── paymentService
└── paymentGateway

OrderSharedContainer
├── orderRepository
└── orderValidator

AuthSharedContainer
├── authService
└── tokenStorage

每个模块管好自己的容器,边界清晰,各司其职:

public final class PaymentSharedContainer: SharedContainer {
    public static var shared = PaymentSharedContainer()
    public let manager = ContainerManager()

    public var paymentService: Factory<PaymentServiceProtocol> {
        self { StripePaymentService() }
    }
    public var paymentGateway: Factory<PaymentGatewayProtocol> {
        self { PaymentGateway() }
    }
}

在 ViewModel 中使用:

final class CheckoutViewModel {
    @Injected(\PaymentSharedContainer.paymentService)
    private var paymentService
}

到这里一切都很美好,直到你开始并行跑测试(尤其是 Swift Testing 默认就是并行模式)。

🐛 核心问题:并行测试与共享可变状态

好,现在终于说到重点了。

一个典型的测试配置

@Suite
struct CheckoutViewModelTests {
    let mockPayment: PaymentServiceProtocolSpy
    let sut: CheckoutViewModel

    init() {
        mockPayment = PaymentServiceProtocolSpy()
        PaymentSharedContainer.shared.paymentService.register { mockPayment }
        sut = CheckoutViewModel()
    }

    @Test func placeOrder_chargesCorrectAmount() async throws {
        try await sut.placeOrder()
        #expect(mockPayment.chargeCallCount == 1)
    }
}

看着没毛病,单独跑这个测试 Suite 的时候确实也没问题。

并行执行时发生了什么

Swift Testing 默认并发执行测试。这对 CI 速度来说是好事,但这意味着多个测试 Suite 同时执行,且共享同一个 PaymentSharedContainer.shared 实例:

image.png

Suite A 注册了 MockASuite B 在同一个容器上注册了 MockB。当 Suite A 解析依赖时,它可能拿到的是 MockB,反过来也一样。最终结果完全取决于线程调度顺序,而线程调度本身就是不确定的。换句话说,你的测试结果现在全凭运气。

更糟糕的是:Suite 内部的竞态

即使是同一个 Suite 内部的测试,也可能产生竞态。Swift Testing 并不保证 @Test 方法按顺序执行:

@Suite
struct OrderViewModelTests {
    let mockRepo: OrderRepositoryProtocolSpy
    let sut: OrderViewModel

    init() {
        mockRepo = OrderRepositoryProtocolSpy()
        OrderSharedContainer.shared.orderRepository.register { mockRepo }
        sut = OrderViewModel()
    }

    @Test func fetchOrders_success() async {
        mockRepo.fetchOrdersResult = [Order.sample]
        await sut.fetchOrders()
        #expect(sut.orders.count == 1)
    }

    @Test func fetchOrders_empty() async {
        mockRepo.fetchOrdersResult = []
        await sut.fetchOrders()
        #expect(sut.orders.isEmpty)
    }
}

两个测试配置的是同一个 mockRepo 实例。并发运行时,一个测试的配置会影响到另一个,本来期望拿到空列表的测试,结果却看到了一条数据,显然这样会影响最终的测试结果。

最终症状

  • 测试本地通过但 CI 上失败(不同机器,不同时序)
  • 重跑失败的流水线就能通过
  • 添加或删除不相关的测试导致其他地方失败
  • 稳定运行很长时间的测试突然变得不可靠

根本原因都是一样的:DI 容器中的共享可变状态,导致 Race Condition

🔐 解决方案:使用 @TaskLocal 实现容器隔离

思路很简单:给每个测试分配自己的独立容器副本。不共享,自然就不会有竞态。

理解 @TaskLocal

在讲方案之前,先简单科普一下 @TaskLocal。这是 Swift Concurrency 提供的一个属性,它能让每个 Task 持有自己的 copy,互相之间完全隔离:

enum Scope {
    @TaskLocal static var currentUser: String = "default"
}

// Task A 看到 "Alice"
Task {
    Scope.$currentUser.withValue("Alice") {
        print(Scope.currentUser)  // "Alice"
    }
}

// Task B 看到 "Bob",完全独立
Task {
    Scope.$currentUser.withValue("Bob") {
        print(Scope.currentUser)  // "Bob"
    }
}

每个 Task 有自己的 currentUser。无需加锁,没有竞态,没有共享状态。

将 @TaskLocal 应用到容器

聪明的你大概已经猜到了,把容器的 shared 属性标记为 @TaskLocal,每个测试任务就能拿到自己的容器了:

public final class PaymentSharedContainer: SharedContainer {
    @TaskLocal public static var shared = PaymentSharedContainer()
    // ^^^^^^^^^ 就是这行代码

    public let manager = ContainerManager()

    public var paymentService: Factory<PaymentServiceProtocol> {
        self { StripePaymentService() }
    }
}

就这么一行代码的事。当测试运行在一个绑定了新容器到 $sharedTask 里时,所有 @Injected 解析拿到的都是当前测试专属的容器,而不是全局那个。

Factory 的内置支持:Container Traits

当然,你也可以手动调用 $shared.withValue(...),但写起来实在太啰嗦了。Factory(通过 FactoryTesting)提供了 Container Traits 来帮你搞定这些样板代码,可以直接嵌入 Swift Testing 的 @Suite@Test 属性。

定义 Container Trait

为每个 SharedContainer 在测试支持模块中定义一个 trait:

import Testing
import FactoryTesting

// 辅助方法:配置测试默认值
private func configurePaymentDefaults(_ container: PaymentSharedContainer) {
    container.paymentService.register { PaymentServiceProtocolSpy() }
    container.paymentGateway.register { PaymentGatewayProtocolSpy() }
}

// Suite 级别的 trait:隔离整个 Suite
extension SuiteTrait where Self == ContainerTrait<PaymentSharedContainer> {
    static var paymentContainer: ContainerTrait<PaymentSharedContainer> {
        let container = PaymentSharedContainer()
        configurePaymentDefaults(container)
        return .init(shared: PaymentSharedContainer.$shared, container: container)
    }
}

// Test 级别的 trait:允许单个测试覆盖配置
extension TestTrait where Self == ContainerTrait<PaymentSharedContainer> {
    static func paymentContainer(
        _ configure: @escaping (PaymentSharedContainer) -> Void
    ) -> ContainerTrait<PaymentSharedContainer> {
        let container = PaymentSharedContainer()
        configurePaymentDefaults(container)
        configure(container)  // 应用测试专属的配置
        return .init(shared: PaymentSharedContainer.$shared, container: container)
    }
}

在测试中使用 Traits

Suite 级别的隔离。 Suite 中的每个测试都获得自己的容器:

@Suite(.paymentContainer, .orderContainer)
struct CheckoutViewModelTests {
    let mockPayment: PaymentServiceProtocolSpy
    let sut: CheckoutViewModel

    init() {
        // 在隔离的容器上注册测试专属的 mock
        let spy = PaymentServiceProtocolSpy()
        PaymentSharedContainer.shared.paymentService.register { spy }
        mockPayment = spy
        sut = CheckoutViewModel()
    }

    @Test func placeOrder_chargesOnce() async throws {
        try await sut.placeOrder()
        #expect(mockPayment.chargeCallCount == 1)
    }

    @Test func placeOrder_passesCorrectAmount() async throws {
        try await sut.placeOrder()
        #expect(mockPayment.lastChargedAmount == 99.99)
    }
}

这样两个测试就可以放心地并行跑了,各自都有独立的 PaymentSharedContainer 实例,互不干扰。

Test 级别的覆盖。 还可以针对某个测试单独定制配置:

@Suite(.paymentContainer)
struct DiscountTests {
    @Test(
        "高级用户享受 20% 折扣",
        .paymentContainer { $0.discountRate.register { 0.20 } }
    )
    func premiumDiscount() async {
        let vm = CheckoutViewModel()
        let price = vm.calculateFinalPrice(for: 100.0)
        #expect(price == 80.0)
    }

    @Test("普通用户没有折扣")
    func noDiscount() async {
        let vm = CheckoutViewModel()
        let price = vm.calculateFinalPrice(for: 100.0)
        #expect(price == 100.0)  // 使用 Suite 默认值(无折扣)
    }
}

整体运作方式

用上 Container Traits 之后,每个测试都拥有自己的独立容器,彼此之间完全隔离:

image.png

不再有共享状态,不再有竞态,单元测试从此稳定!

📋 完整实践清单

我们在每个模块中遵循的模式:

1. 为 SharedContainer 标记 @TaskLocal

public final class OrderSharedContainer: SharedContainer {
    @TaskLocal public static var shared = OrderSharedContainer()
    public let manager = ContainerManager()
    // ... 依赖定义
}

2. 在测试支持模块中创建 trait 辅助方法:

// OrderMocks/ContainerTraits.swift
private func configureOrderDefaults(_ container: OrderSharedContainer) {
    container.orderRepository.register { OrderRepositoryProtocolSpy() }
    container.orderValidator.register { OrderValidatorProtocolSpy() }
}

extension SuiteTrait where Self == ContainerTrait<OrderSharedContainer> {
    static var orderContainer: ContainerTrait<OrderSharedContainer> {
        let container = OrderSharedContainer()
        configureOrderDefaults(container)
        return .init(shared: OrderSharedContainer.$shared, container: container)
    }
}

3. 在测试Suite中应用 traits:

@Suite(.orderContainer, .paymentContainer)
struct OrderFlowTests {
    // 每个测试都获得隔离的容器,可安全并行执行
}

🧭 核心要点

  1. DI 的本质是为了可测试性
  2. Factory 填补了 MVVM + DI 的空白,解决了 SwiftUI @Environment 无法覆盖的场景
  3. 并行测试 + 共享容器(Shared Container) = 竞态条件(Race Condition)
  4. @TaskLocal 容器隔离从根本上解决了问题,为每个测试提供独立的容器实例
  5. Container Traits 让方案切实可行, 每个模块定义一次,在每个测试Suite中声明式地应用

不依赖 Mac 也能做 iOS 开发?跨设备开发流程

2026年3月24日 17:58

在 iOS 开发这个领域,需要一台 Mac几乎是默认前提。项目创建、代码编译、设备调试都围绕着 macOS 和 Xcode 展开。但在一些实际场景里,比如临时接手项目、在非 Mac 设备上验证功能,这个前提会变成限制条件。

前段时间在帮朋友看一个小项目时,我尝试了一种不同的方式:在没有使用传统 Mac 开发环境的情况下,完成 iOS 应用的编写和运行。

项目不复杂,但流程完整,刚好可以验证这种开发方式是否可行。


在非传统环境中创建 iOS 项目

打开快蝎 IDE 后,可以直接进入项目创建界面。界面提供几种项目类型:

  • Swift
  • Objective-C
  • Flutter

选择 Swift 项目,输入名称后点击创建,IDE 会生成项目目录。

项目结构已经包含基础代码文件和资源目录。打开入口文件就可以开始写代码,没有额外的初始化步骤。

在这个阶段没有遇到环境缺失的问题。IDE 已经准备好编译所需工具,因此项目创建后可以直接进入开发阶段。 创建项目


编写一个简单功能验证项目

为了测试开发流程,我写了一个简单页面:

  • 一个按钮
  • 一个文本区域

按钮点击后读取本地数据,并把结果显示在界面上。

在代码编辑过程中,IDE 提供了自动补全和语法提示。输入类名或方法时,会弹出可选项列表。保存文件后,IDE 会检查代码结构并标记错误位置。

编辑体验接近常见代码编辑器,键盘操作和插件支持也比较完整。


连接 iPhone 并执行应用构建

代码写好之后,需要在真实设备上运行。

将 iPhone 连接到电脑 IDE 开始执行构建流程。

构建过程中会完成:

  • 编译源代码
  • 构建应用程序
  • 安装到手机

构建完成后,手机桌面上会出现应用图标。点击打开应用,可以看到界面正常显示。

点击按钮后,文本区域成功更新为读取的数据,说明代码已经正确执行。 连接手机


修改代码并再次运行

在开发过程中,需要不断调整代码。

我在按钮点击逻辑中增加了一段处理,然后保存文件并再次点击运行按钮。IDE 会重新编译应用并安装新版本。

打开手机应用,可以看到更新后的效果。

整个过程保持一致:

修改代码 → 点击运行 → 编译应用 → 安装到设备 → 查看结果

没有出现额外导出或手动安装的步骤。


编译能力的实现方式

在这个流程中,没有使用 Mac 上的 Xcode。

快蝎 IDE 内置了一套编译工具套装。安装 IDE 时,这些工具已经配置完成。点击运行或构建时,IDE 会调用内部工具完成代码编译和应用构建。

开发者在这种环境中可以直接编写 iOS 应用,并完成编译和运行。

对于需要在非 Mac 环境下验证代码的场景,这种方式提供了一种可行路径。


多项目类型的开发测试

为了进一步验证 IDE 的能力,我创建了一个 Flutter 项目。

Flutter 页面写好后,连接设备点击运行,IDE 可以完成编译并安装应用。

随后测试了 Objective-C 项目,也可以正常运行。

在同一个开发环境中可以处理:

  • Swift 项目
  • Objective-C 项目
  • Flutter 项目

这在需要跨项目开发时会比较方便。


构建安装包用于分发

当应用开发完成之后,需要生成安装包。

在快蝎 IDE 中,可以通过构建功能生成应用安装文件。IDE 会执行编译并输出安装包。

构建日志会显示在输出面板中,如果出现编译问题,可以查看详细信息。

生成的安装文件可以用于测试或分发。 构建

对于开发者来说,这种方式可以在特定场景下使用,例如临时开发、功能验证或环境受限时。 参考链接:www.kxapp.com/blog/15

Windows 上传 IPA 到 App Store 的步骤讲解

2026年3月24日 16:40

在 Windows 环境开发 iOS 项目时,最容易卡住的一步不是写代码,而是怎么把 IPA 上传到 App Store。

很多资料默认使用 Xcode 或 Transporter,但这些工具依赖 macOS。 如果开发和发布都在 Windows 上完成,就需要把流程分开:

  • IPA 可以在任意环境生成
  • 上传只是一个独立步骤

只要 IPA 符合要求,上传完全可以在 Windows 上完成。


确认 IPA 已经具备上传条件

在考虑上传之前,需要先确认 IPA 是“可发布包”。

检查三个关键点:

1. 使用的是发布证书

打包时必须使用:

  • Distribution 证书

如果是 Development 证书:

  • IPA 可以安装
  • 但无法上传 App Store

2. 描述文件类型正确

描述文件必须是:

  • App Store 类型

可以通过解包 IPA 检查:

unzip -p app.ipa Payload/*.app/embedded.mobileprovision

确认没有设备 UDID。


3. Bundle ID 与后台一致

需要保证:

  • IPA 中 Bundle ID
  • App Store Connect 中的 Bundle ID

完全一致。


在 Windows 准备上传环境

Windows 上没有 Xcode,但可以使用以下工具:

  • AppUploader
  • iTMSTransporter(需额外配置 Java 环境)
  • Fastlane(Windows 支持有限)

在实际使用中,直接使用图形工具或命令行工具会更稳定。


使用 AppUploader 上传 IPA

在 Windows 上,AppUploader(开心上架) 可以直接完成上传操作。

具体步骤如下:


1. 打开上传界面

启动 AppUploader,进入「提交上传」页面。


2. 设置 Apple 专用密码

需要在 Apple ID 中生成 App 专用密码。

输入:

  • Apple ID
  • 专用密码

注意:这里不能使用账号登录密码。 专用密码

app专用密码


3. 选择 IPA 文件

点击选择本地 .ipa 文件。


4. 选择上传通道

工具提供多个上传通道:

  • 通道 1(旧通道)
  • 通道 2(新通道)

如果上传过程中卡住,可以切换通道重新尝试。 上传页面


5. 执行上传

点击上传按钮,等待完成。

上传成功后,Apple 会返回处理结果。 上传成功


上传后的状态确认

上传完成并不代表立即可见。

需要进入:

App Store Connect → My Apps → TestFlight

Apple 会进行一次处理(Processing)。

处理完成后:

  • 构建版本才会出现
  • 才能提交审核

如果上传成功但没有构建

遇到上传成功但没有构建时,可以检查:

检查构建号

  • CFBundleVersion 必须递增

检查签名类型

  • 是否使用 App Store 描述文件

检查 Bundle ID

  • 是否与 App Store Connect 中一致

重新上传

可以换一个上传通道再次提交。


结合其他工具的上传方式

在一些团队中,上传流程会和构建工具结合。

例如:

Fastlane + Windows

可以在 Mac 构建后,将 IPA 传到 Windows,再用 AppUploader 上传。


CI 流程

流程可以拆成:

  1. Mac 或云端构建 IPA
  2. 上传到服务器
  3. Windows 节点执行上传

这样可以减少对 macOS 的依赖。


实际流程示例

团队使用 Windows 开发时,可以这样:

  1. 使用 HBuilderX 或 CI 构建 IPA
  2. 使用 AppUploader 创建证书和描述文件
  3. 下载 .p12.mobileprovision
  4. 打包生成 IPA
  5. 在 Windows 上使用 AppUploader 上传

整个流程中:

  • 不需要 Xcode 上传
  • 不依赖 macOS 设备

参考链接:www.appuploader.net/blog/231

Claude Code + OpenSpec 正在加速 AICoding 落地:从模型博弈到工程化的范式转移|得物技术

作者 得物技术
2026年3月24日 10:22

一、破局:AI 编码的真正瓶颈不是模型,是上下文管理

在软件开发的历史进程中,每一次效率的飞跃都伴随着抽象层次的提升。从汇编语言到高级语言,从手动内存管理到垃圾回收,开发者始终在寻求降低认知负荷的方法。进入 2026 年,生成式人工智能(GenAI)已成为编程领域不可或缺的力量。 然而,行业正经历从 “模型崇拜” 向 “工程落地” 的深刻转型,单纯依靠增加大语言模型(LLM)的参数规模已无法解决复杂业务逻辑中的幻觉与失控问题。

当前的共识是,AI 编码(AICoding)的真正瓶颈不在于模型的逻辑能力,而在于上下文管理(Context Management)的失效与开发意图(Intent)的模糊。

通过对 Anthropic 推出的 Claude Code(以下简称 CC)与 Fission AI 倡导的 OpenSpec 进行深度解构可以发现,两者正在通过 “代理化执行” 与 “规格化驱动” 双轮驱动,构建一套闭环的 AI 研发体系。这种结合不仅标志着 AI 编程工具从 IDE 插件向终端原生代理(Agentic Tool)的转变,更预示着 “规格驱动开发”(Spec-Driven Development, SDD)将成为企业级 AICoding 落地的核心范式。

在 AICoding 的早期阶段,开发者普遍认为只要模型足够强大,就能解决所有编程难题。然而,随着项目复杂度的增加,这种观点遭到了现实的挑战。研究表明,虽然 AI 编码助手的使用率在提升,但软件交付的稳定性却在下降。例如,Google 的 DORA 2024 报告指出,AI 采用率每增加 25%,交付稳定性反而下降 7.2%。

生产力悖论与认知负荷

AICoding 领域存在一个显著的 “生产力悖论”:开发者在使用 AI 时主观感知速度提升了 20%,但实际完成任务的时间却增加了 19%。这一现象的根源在于 AI 在处理长上下文时的效能衰减。随着任务推移,AI 往往会陷入修正循环(Fix/Test Loops),无法触及深层的业务功能,反而需要更多的人工干预。

模型的逻辑推理能力(Reasoning)在短小上下文中表现卓越,但在大型工程环境中,模型面临的是 “上下文中毒”(Context Poisoning)和 “注意力漂移”(Attention Drift)。当对话历史过长或包含过多无关代码时,模型的性能会呈现非线性下降。例如,GPT-4o 等先进模型在 1K Token 时的准确率为 99.3%,而当上下文扩展到 32K Token 时,准确率会暴跌至 69.7%。这种 “性能断崖” 意味着,单纯依靠扩大上下文窗口(Context Window)并不能解决问题。

上下文工程的兴起

上下文工程(Context Engineering)正在取代提示词工程(Prompt Engineering),成为 AICoding 的核心技术方案。上下文工程的核心不在于 “如何写更好的指令”,而在于 “如何为模型筛选最精准的 Token 集合”。

下表对比了传统缩放路径与上下文工程路径的局限性:

在大型组织中,上下文管理面临更严峻的挑战。很多关键决策并未记录在代码中,而是散落在飞书文档评论、群消息、会议或开发者的认知中。AI 代理在缺乏这些隐性知识(Implicit Knowledge)的情况下,生成的方案虽然符合语法,但却违背了架构初衷或业务约束。

上下文作为一等系统

现代 AI 代理架构开始将上下文视为一种具有自身架构、生命周期和约束的 “一等系统”。在这种视角下,上下文管理不再是临时的字符串拼接,而是一条精密的 “编译器管道”:

  • 存储与呈现分离: 区分持久化的会话状态(Session)与单次模型调用的工作上下文(Working Context)。
  • 显式转换: 通过命名的、有序的处理器(Processors)构建上下文,而非随机堆砌。
  • 默认作用域: 每个子代理仅能看到执行任务所需的最小上下文,通过工具(Tools)按需获取更多信息。

二、Claude Code:把 AI 变成真正懂你项目的编码伙伴

Claude Code (CC) 是 Anthropic 推出的原生代理工具,它直接运行在终端中,具备读取文件、运行命令、执行重构以及自主验证的能力。与传统的 IDE 插件相比,CC 的核心优势在于其“代理循环”(Agentic Loop)和对上下文协议的深度掌控。

代理循环:收集、行动与验证

CC 的工作流程被定义为一个闭环系统,旨在模仿人类工程师的思维过程:

  • Gather Context(收集上下文): CC 不会盲目读取整个目录,而是通过文件搜索、Git 状态检查以及读取特定的 CLAUDE.md 文件来建立认知。
  • Take Action(采取行动): 基于推理,CC 可以跨多个文件执行编辑,或者利用终端工具(如 npm install、git commit)操作环境。
  • Verify Results(验证结果): 这是 CC 最具杀伤力的特性。它能自动运行测试、捕捉错误,并根据反馈调整方案。研究表明,带有验证步骤的 Coding 生成过程,其成功率远高于单次生成。

终端原生的工程哲学

CC 选择了终端而非图形界面作为主场,这体现了其 “代理优先” 的设计哲学。CC 遵循 Unix 哲学,支持管道(Pipe)、脚本化和自动化集成。这种设计使得 CC 能够与现有的 CI/CD 流程完美衔接,例如在 GitHub Actions 中自动执行代码审计。Anthropic 最新推出的 Code Review 功能,就是通过 Claude Code 基于 PR 的方式进行 bug 的追踪。

下表详细对比了 CC 与行业领先的 AI 编辑器 Cursor 的差异:

MCP 与“即时上下文”

CC 深度整合了模型上下文协议(Model Context Protocol, MCP)。MCP 是一个开放标准,允许 AI 代理安全地访问外部数据源。

为了应对大规模工具定义导致的上下文溢出,CC 引入了 “工具搜索” 和 “代码执行” 模式。代理不再一次性加载成千上万个 API 定义,而是通过编写代码按需调用 MCP 服务。例如,在分析大型数据库时,CC 不会加载全量数据,而是编写针对性的查询语句,仅将结果摘要读入上下文。这种 “按需加载” 策略极大地提升了 Token 的效用。

CLAUDE.md 与自动记忆

CC 引入了 CLAUDE.md 文件作为项目的 “操作手册”。这是一个置于根目录的 Markdown 文件,用于存储项目特定的编码标准、架构决策和测试指令。与临时提示词不同,CLAUDE.md 提供了持久的、跨会话的约束。

此外,CC 具备 “自动记忆”(Auto Memory)功能。它会自动在 MEMORY.md 中记录项目的构建命令、调试心得和用户的偏好设置。每当新会话启动时,CC 会加载这些记忆的前 200 行,从而确保 AI 在长期协作中能够 “越用越懂你”。

三、OpenSpec:给 AI 编码加上"规格书",从失控到可沉淀

虽然 Claude Code 提供了强大的执行引擎,但在复杂业务中,AI 仍然可能因为意图不明而跑偏,最终导致交付的代码不符合预期。

OpenSpec 的出现为 AI 编码提供了 “规格说明书”,将 AICoding 从 “凭感觉写代码” 提升到了 “按规格执行任务” 的高度。

规格驱动开发 (SDD) 的兴起

OpenSpec 倡导的是一种 “规格驱动开发”(Spec-Driven Development)范式。其核心理念是:在写任何一行代码之前,先由人类与 AI 共同协商并锁定一份机器可读、人可评审的规格文档。

下表展示了 SDD 的三个演进阶段:

OpenSpec 的工件体系 (Artifacts)

OpenSpec 弃用了笨重的开发文档,转而采用一套轻量级的、面向 AI 优化的 Markdown 工件体系。每个变更(Change)都被组织在独立的文件夹中:

  • proposal.md: 描述变更的初衷(Why)和范围(What)。
  • specs/: 具体的逻辑规格,通常包含 “Scenario(场景)” 描述,通过具体的输入输出消除模糊性。
  • design.md: 技术设计方案,包括本次变更涉及的数据库变更、接口调整等。
  • tasks.md: 原子化的任务清单,作为 AI 的执行路径图。

解决上下文污染:提案、应用与归档

OpenSpec 最具洞察力的设计在于其生命周期管理。AI 在处理新任务时,最忌讳被旧任务的陈旧信息干扰。OpenSpec 的 “归档(Archive)” 机制解决了这一问题:

  • Proposal 阶段: 建立一个独立的变更上下文,让 AI 只关注当前变更。
  • Apply 阶段: AI 严格按照 tasks.md 执行,避免了盲目扫描全库导致的 Token 浪费。
  • Archive 阶段: 任务完成后,临时变更文档被移入归档,核心规格更新至主规格文件。这保证了 AI 始终在一个 “卫生” 的上下文环境下工作,同时也为项目留下了可追溯的决策链路。

四 、实战:CC + OpenSpec 如何落地真实业务

在实际的企业业务场景中,如何整合这两大工具?答案在于将 OpenSpec 的标准化指令集注入到 Claude Code 的会话环境中。

案例实战:复杂业务逻辑的重构

假设一个电商项目需要重构其优惠券结算逻辑。在传统的 AI 辅助下,AI 可能会在修改 CouponService.java 时遗漏分布式锁,或者破坏原有的满减叠加规则。采用 CC + OpenSpec 模式,流程如下:

第一步:提案初始化

执行 /opsx:propose "重构优惠券结算逻辑,引入 Redis 分布式锁并支持多卷叠加"。CC 会在 openspec/changes/refactor-coupon-logic/ 下生成整套骨架。AI 会通过分析现有代码,在 spec.md 中自动列出已知的结算场景。

第二步:规格对齐与边界确认

这时不用急着让 AI 写代码,而是需要先审阅 spec.md。如果发现 AI 没考虑 “优惠券过期临界点” 的并发问题,可以直接要求 AI 修改规格:“在 spec.md 中增加过期校验场景,并要求使用 Lua 脚本保证原子性”。

第三步:受控应用(Apply)

一旦规格通过人工评审,就可以执行 /opsx:apply 了。这时,CC 就变成了完美的执行机器。它不再 “猜” 开发者的意图,而是对照 tasks.md 逐项实施。每一项修改后,它都会运行相关的测试。如果测试失败,CC 会自动分析错误并重新修复,直到该项 Task 标为 “完成”。

第四步、归档与知识固化

任务结束后,执行 /opsx:archive。原本散落在会话记录中的重构逻辑,现在变成了 openspec/specs/coupon-settlement.md 中的标准规格。当下一次另一个 AI 代理(或新入职同事)需要修改此模块时,它只需读取这份规格,即可获得完整的业务语境。

工具链对比:为何选择 OpenSpec

在 SDD 工具链中,OpenSpec 展现出了极高的工程性价比:

OpenSpec 的优势在于它不试图改变开发者的工具偏好。无论是使用 Claude Code、Cursor 还是 Aider,都可以无缝接入 OpenSpec 的规格管理层。

五、沉淀:让 AI 编码能力在团队中持续积累

AICoding 落地的终极目标不是让个体开发者写得更快,而是提升整个团队的知识资产质量。AI 编码能力不应随对话窗口的关闭而消失,而应作为 “团队记忆” 沉淀下来。

从个人技能到组织技能

团队可以通过自定义 Skill 和 MCP Server 来固化组织资产。

  • Skill: 将公司特有的代码风格、安全审计清单,或者特定中间件的使用指南封装为 .claude/skills/。当团队成员使用 CC 时,AI 会自动加载这些技能,仿佛有一位资深架构师在时刻盯着每一行代码。
  • MCP Server: 连接企业内部的向量数据库(如基于 Zilliz 的语义搜索),让 AI 代理能够从数千万行历史代码中找到最佳实践。

建立 AICoding 效能飞轮

AICoding 的成功落地需要建立一套正向循环的 “飞轮”:

  • 规格积累: 每完成一个 PR,都强制更新对应的 OpenSpec 规格文件。
  • 指令进化:发现 AI 反复犯的错,就将其转化为 CLAUDE.md 中的负向约束(Prohibited rules)。
  • 并行执行: 利用 CC 的 Agent Teams 能力,让一个代理负责写规格,另一个代理负责审计代码,第三个代理负责集成测试。

角色转变:从 “码农” 到 “规格定义者”

在 CC + OpenSpec 模式下,软件工程师的角色正在发生质变。如果 AI 能够根据完美的描述生成任何代码,那么 “代码” 本身就变成了编译后的中间产物,而 “规格” 才是核心产品。领域专家(Domain Experts)的重要性显著提升,因为他们能提供最高质量的业务意图描述。这种趋势将迫使开发者从关注 “语法实现” 转向关注 “系统设计” 和 “逻辑严密性”。

六、结语:AICoding 落地的飞轮正在转动

在 2026 年,AICoding 已不再是科幻。Claude Code 提供的强大代理能力,配合 OpenSpec 提供的精密规格框架,为企业提供了一套可复制、可量化的研发新范式。

我们必须承认,AI 编码的瓶颈从来不是模型不够聪明,而是我们与 AI 之间的 “沟通带宽” 太低且 “上下文” 太脏。通过上下文工程化管理(CC)和意图标准化表达(OpenSpec),我们正在构建一套让 AI 能够长期、稳定产出的工程环境。

随着这一模式的普及,软件开发的门槛将进一步降低,而创新的上限将被无限拉高。AICoding 落地的飞轮已经转动,那些能够率先将 AI 编码能力转化为团队组织资产的企业,将在未来的数字化竞争中占据绝对的先机。毕竟,在 AI 时代,掌握了 “意图” 与 “上下文” 的人,才掌握了软件工程的未来。

参考文档:

  1. thenewstack.io/context-is-…
  2. github.blog/ai-and-ml/g…
  3. solguruz.com/blog/spec-d…
  4. medium.com/@eran.swear…
  5. www.anthropic.com/engineering…
  6. code.claude.com/docs/en/how…
  7. www.anthropic.com/engineering…
  8. code.claude.com/docs/en/bes…
  9. dev.to/webdevelope…

往期回顾

1.大禹平台:流批一体离线Dump平台的设计与应用|得物技术

2.基于 Cursor Agent 的流水线 AI CR 实践|得物技术

3.从IDE到Terminal:适合后端宝宝体质的Claude Code工作流|得物技术

4.AI编程能力边界探索:基于 Claude Code 的 Spec Coding 项目实战|得物技术

5.搜索 C++ 引擎回归能力建设:从自测到工程化准出|得物技术

文 /后羿

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

鸿蒙智行 9 车齐发!尚界 Z7 同步亮相,22.98 万元起

作者 李华
2026年3月24日 18:12

刚刚结束的华为春季全场景新品发布会,阵仗拉得挺大,台上一口气摆出了 9 辆新车,把问界、智界、享界和尚界这几个「界」字辈的阵容又集体刷了一遍。

此时距离 2026 款车型的发布仅仅过了半年。

在这份长长的名单里,问界 M 系列的三款 SUV 迎来了换新,享界和智界也拿出了各自的改款车型。华为和各大车企推进新车的速度确实很快,大家都得跟上目前极度内卷的行业节奏。

在一众熟悉的改款车型里,最具看点的新车,无疑是尚界量产的第二款产品——尚界 Z7 和它的衍生猎装版 Z7T。

我们今天的文章,就从这两台车聊起。

尚界也想冲高端

先看外观,尚界 Z7 和 Z7T 这次在造型和工艺上确实下了本钱。

结合此前工信部的申报信息,这两台车有着相同的底子。车长超过 5 米,轴距达到 3000 毫米。为了配合宽体低趴的姿态,尚界给它们全系标配了前 245、后 275 的鸳鸯胎。

在漆面处理上,官方把「5C2B」涂装工艺搬了出来。

5C2B 这个词这听起来像个生僻的噱头,其实就是汽车喷漆工序里的「五涂两烘」。

市面上绝大多数家用车用的都是三涂两烘,尚界多出来的这些漆面,影响的是车身在阳光下的厚重感和折射率。华为终端 BG CEO 何刚在发布会上表示,尚界砸钱上这套百万豪车标准的工艺,图的就是一个光泽亮丽、质感高级。

外观的辨识度很大一部分靠灯光来撑。Z7 的大灯采用了钻石切割设计,底部点缀了数百颗「星钻」,尾灯内部更是塞进了超过 4700 颗发光颗粒。

想要更战斗一点的用户,可以选装专属的追风运动套件。

拉开车门,座舱内部给出了五种配色——速影黄、沁夜红、凝夜紫、闪金黑以及缥云杏。大面积的麂皮材质和真碳纤维装饰,把运动氛围烘托得很到位。

这次,不少年轻人关心的「养生」需求也被照顾到了。

尚界 Z7 标配了阿尔卑斯健康座舱,这套座舱大量使用了能吸附和降解甲醛的 MOFs 材料。为了进一步讨好注重细节的用户,尚界还在车里放了一套水离子空调,主打给皮肤和头发保湿。

副驾前方的灵感橱窗和随动屏,在预热阶段就已经积攒了不少热度,车主可以在上面 DIY 摆放手办,布置属于自己的仪表台。

回到实用性层面,这也是 Z7T 作为猎装车最大的卖点。

两款车都采用了掀背式尾门,最大开口接近 1 米。由于车顶向后延伸,Z7T 把空间利用率推到了极致。何刚给出了一个很直观的数据——后排座椅放倒后,后备箱的最大拓展容积达到了 1694 升。

装下两个 28 英寸和一个 24 英寸的行李箱,或是塞进全套的户外装备,都毫无压力。

跑得远,自然需要扎实的底层架构来支撑。

Z7 和 Z7T 全系搭载华为巨鲸 800V 高压电池平台,最高能提供 905 公里的 CLTC 纯电续航。根据工信部的数据,新车提供单电机和双电机两个版本。双电机 Ultra 版拥有前 170kW、后 264kW 的动力储备,让 Z7 的零百加速跑到了 3.44 秒。

制动方面,Z7 全系标配华为图灵平台,百公里制动距离被控制在 33.1 米。

何刚还强调了车辆的被动安全能力,车身的高强钢和铝合金占比达到 91%,乘员舱骨架大量使用了 2000 兆帕的潜艇级热成型钢,车顶抗压能力达到 5.8 倍车重。

华为最拿手的高阶辅助驾驶自然没有缺席,Z7 全系都标配了 896 线激光雷达和华为 ADS 辅助驾驶系统。

最后是大家最关心的价格。

尚界 Z7 的预售价定在了 22.98 万元起,猎装版 Z7T 的预售价则是 23.98 万元起。现在下订,官方还提供至高 1.1 万元的购车权益。

摸着小米过河,踩中猎装的风口

去年年初,我们提出了一个观察:三排六座混动大 SUV,2025 年中国汽车市场的「版本答案」。回过头看,事实也确实如此。

理想 L9 和问界 M9 这对先行者,算是打开了 6 座 SUV 市场的胃口,引来了极氪 9X、乐道 L90、蔚来 ES8 等强有力的竞争选手,车企们几乎都在死磕大空间家用 SUV,生怕车子做小就卖不动。

但与此同时,一个车圈新星用自己的第一个作品,打破了「纯电轿车不好卖」的魔咒,把高端纯电轿车这个小众市场掰成了主流。当然,这辆车可不是今天发布会里的智界 S7,而是小米 SU7。

作为一个新来的插班生,小米 SU7 在造型上选择了一条差异化路线,车头被刻意拉长,车高被压低。雷军用实打实的交付量证明,年轻人非常愿意牺牲一点后排空间,来换取更好看的造型。不受待见的,反而是智界 S7 这种为了空间和风阻妥协的 One-Box 造型。

小米把路蹚平,证明放弃「最大公约数」照样能活得滋润,同行自然得火速跟进。

尚界 Z7 选在这个节点入场,刚好跳过了用户教育阶段,它瞄准的,正是那群既要运动造型、又离不开高阶辅助驾驶的用户。

如果说在轿跑市场是跟进,那同步推出的猎装版 Z7T 算是踩准了另一个风口。

今年年初,我们又提出了一个观察:曾经无人问津的旅行车和猎装车,成了中国车企的必争之地。

看近期的终端数据就知道,蔚来 ET5T、极氪 007 GT、享界 S9T 这些带着大尾巴的旅行版本,卖得都比同平台的三厢版更好。曾经小众的情怀车,现在几乎快成了刚需。

把这事全归结为汽车文化觉醒有些苍白,预算才是最实际的考量。

以前,合资品牌把旅行车捧得极高。买台进口的沃尔沃 V60 或奥迪 A4 Avant,要比国产的三厢版多掏大几万甚至十几万。为一个大后备箱承担这么离谱的差价,绝大多数人在刷卡前都会犹豫。

国产新能源品牌可不会跟你这么玩,主打一个把溢价的水分挤干。

同配置的轿车和猎装车,基本被钉在同一个价位。花同样的钱,能换来更修长优雅的比例和更大的装载空间,试问谁能不心动呢。

再者来说,纯电车为了续航,底盘必须塞进一块十几厘米厚的电池,地台被抬高后,设计师如果还死守三厢轿车那种快速下溜的车顶,后排乘客就只能憋屈地缩着脖子。把车顶线条往后平滑拉长,做成猎装形态,刚好化解底盘变厚带来的空间难题。

Z7T 借着这个形态释放后排头部空间,顺便给出一个极度宽敞的后备箱。周末往车里塞满折叠推车、单板滑雪板、宠物狗,才是他们真实的生活状态。传统轿车装不下这些零碎,SUV 又给不了精准的贴地转向手感,猎装车刚好卡在中间,好处两头占。

华为把高阶智驾塞进 Z7T,顺手抹平长途旅行的痛点,上百公里高速被算法接管,驾驶员不用再把精力耗费在无聊巡航上,到了目的地照样有充沛体力去搭帐篷。

配置严重同质化的今天,换一张牌桌往往是最有效的打法。尚界用 Z7 守住轿跑基本盘,再用 Z7T 网住那些愿意为户外生活方式买单的年轻人。

剩下的,就看上市时的价格够不够狠了。

9 车连发,896 线激光雷达全系标配

最后来看看这次发布会上的其它「界」字辈。

这次发布会最明显的信号,其实是华为把高阶辅助驾驶的天花板再次拔高了。

不论是主打行政的享界,还是面向年轻人的智界,亦或是销量担当问界,它们都同步换上了最新的 896 线的激光雷达。

在华为 ADS 4 的加持下,鸿蒙智行全家族的感知能力已经完成了新一轮的合围。何刚在台上提到,这种「图像级」的激光雷达不仅看得更远,避障的响应速度也提升了一个台阶。

在这种全员智驾平权的前提下,各品牌的焕新重点开始向细分需求倾斜。

享界 S9 和它的旅行版 S9T 拿出了更感性的配色,新增的星玫粉和月绒白,配上同色的轮毂,给这款行政级轿车增加一些生活的底色。该系列的起售价定在 31.98 万元。

智界 R7 和智界 S7 的重点则放在了座舱健康上。

除了新增暗夜紫和活力橙配色,这两款车引入了 9 系旗舰同款的「阿尔卑斯健康座舱」。何刚专门介绍了 MOFs 这种新材料——它不仅能吸附甲醛,还能主动将其降解。对于智界这种主打年轻家庭的品牌来说,这种看不见的增配也许比参数更有说服力。智界 R7 的起售价为 25.9 万元,同样做到了发布即交付。

问界家族的动作则加针对辅助驾驶。

问界 M7 焕新后,起售价来到了 30.98 万元。最关键的变化是,这个价格已经直接标配了 896 线激光雷达。

至于之前那些不带顶置雷达的 Pro+ 版本,何刚也带去了一个惊喜:经过大模型训练,这些老车主将在 4 月份迎来城区 NCA 的全量推送。华为用这种方式,给过去的纯视觉方案做了一次补课。

问界 M8 则更进一步,把传感器规格堆到了天花板。

除了车顶那颗 896 线激光雷达,M8 还额外增加了两个侧向的固态激光雷达。全车 38 个传感器配合全面升级调校的双腔空悬,让这台车的行驶质感和避障冗余度都更接近老大哥 M9。这次新增的 Max 后驱长航版,CLTC 综合续航更是跑到了 1590 公里,它的起售价为 36.98 万元。

最后压轴登场的是问界 M6。

作为问界家族最年轻的中大型 SUV,M6 并没有因为定位稍低就缩减硬件,896 线激光雷达依然是标配。这台车最大的不同是副驾前方的 DIY 设计,包括可以手机碰一碰换照片的水墨屏、能够放入各种手办的「移动橱窗」等系列配件。

此外,问界 M6 全系标配图灵平台,涉水深度达到了 700 毫米。这对于一台体态优雅的城市 SUV 来说,确实给足了出游的底气。它的预售价定在 26.98 万元起。

发布会临近尾声时,何刚还留了一个伏笔——鸿蒙智行的首款旗舰 MPV 智界 V9 将在四月下旬正式进店,同样会搭载这套顶配的 896 线激光雷达。

一下午连发 9 款新车,华为把这种「全系标配即顶配」的压迫感,传导给了每一个细分市场的对手。

在车型保鲜期越来越短的当下,这种恨不得把所有缝隙都填满的推新速度,确实让友商们很难接招。

除了造车,华为的消费电子也没闲着

整场发布会看下来,汽车抢足了风头,但华为消电的成绩单依然够硬。目前鸿蒙终端的设备数量已经突破了 5000 万,每天还在以 15 万的速度往上增。

稳住基本盘后,华为开始在细分硬件上切蛋糕了。

最先登场的是华为 Mate 80 Pro Max 风驰版。

何刚表示,这台手机是为了性能和重载场景准备的。为了压住麒麟 9030 Pro 芯片的满载发热,华为撤掉了一颗超长焦镜头,把位置腾出来塞进了一套「风驰散热模组」,里面用上了仿生羽翼涡扇和超导热弯流翅片。

软件层面,这台手机首发了 HyperSpace Memory 超空间内存技术。可以通过极高的压缩率,让 16G 的内存跑出 20G 的后台保活体验。软硬结合下来,整机性能比 Mate 70 Pro+ 提升了 45%。

这台用来打游戏和长时间直播的性能机,定价 8499 元起。

高端机秀肌肉,走量机型畅享 90 系列则负责把门槛踩实。

这次畅享 90 系列全系标配了 Wi-Fi 7。把最新的通信技术直接下放到一两千元的档位,给同价位产品上了一点强度。

杯型最大的畅享 90 Pro Max 塞进了一块 8500mAh 的巨鲸大电池,主打一个跨天级别的重度续航。中间定位的畅享 90 Plus 增加了一个非常实用的痛点功能——端侧智能识别诈骗风险,并支持家属远程挂断电话。

穿戴设备方面,华为更新了两块表和一个手环。

定位旗舰的 WATCH Ultimate 2 拿出了全新的纳米微晶陶瓷表圈和非晶锆合金表体,支持 150 米专业潜水和果岭视图升级,依然是冲着极限户外群体去的。

相比之下,WATCH GT Runner 2 的定位更纯粹,完全为跑步爱好者服务。

表体重量压到了 34.5 克,厚度只有 10.7 毫米。正面覆盖第二代昆仑玻璃,表盘峰值亮度达到 3000nit,大太阳下跑步也能一眼看清配速。在开启双频高精度定位的情况下,续航依然能撑 32 个小时。

至于手环 11 系列,Pro 版升级了独立 GNSS 定位,标准版则把重点放在了情绪健康和日常便携交互上。

办公和家居生态也顺带刷了一波存在感。

MatePad Pro 12.2 英寸和 MatePad mini 悦读版同步更新了幻影紫配色。

许久没动静的显示器产品线推出了 MateView GT。27 英寸的全面屏支持 160Hz 高刷新率,底座内置了 26W 大功率的 4.1 声道音响系统,连外接音箱的钱都省了。

最后压轴的是 Vision 6 智慧屏。面板换上了华为 Super MiniLED 黑晶屏,外层加了双层纳米低反镀膜,把屏幕反射率压到了 0.5%,大白天看电视基本不用拉窗帘了。更有意思的是,这块电视屏幕现在支持触控,配合灵犀手写笔,客厅的大屏变成了一块巨大的画板。

带轮子的都关注,欢迎交流。 邮箱:tanjiewen@ifanr.com

#欢迎关注爱范儿官方微信公众号:爱范儿(微信号:ifanr),更多精彩内容第一时间为您奉上。

昨天 — 2026年3月24日首页

科氪 | 性能之上,圆满之作:一加 15T 深度评测

2026年3月24日 22:51

小屏直板旗舰的“终极形态”

在移动影像和超大电池日益占据手机内部空间的今天,“小屏”与“旗舰”的兼容性始终是行业的终极课题。上一代一加 13T 的出现,已经打破了“小屏必弱性能”的魔咒,其强悍的调度和长续航让市场看到了小屏机的上限。然而,对于极致追求完美的玩家来说,影像上的克制始终是 13T 留下的遗憾。

现在,一加 15T 正式登场。它不仅仅是性能的延续,更是对“全能”二字的重新定义。如果说 13T 是一位偏科的性能天才,那么一加 15T 则补齐了最后一块影像短板,成为了一款真正没有槽点的小屏直板新王。

一、 颜值与触感:在“松弛”中寻找精致

一加 15T 的外观设计,第一眼看上去是“内敛”,上手后则是“惊艳”。

外观设计

独一无二的“松弛抹茶”:本次拿到的是最具代表性的“松弛抹茶”配色。这是一种低饱和度的绿色,如同在安静的午后泡开的一碗茶,给人一种宁静、解压的视觉观感。更难得的是,背板虽然采用了玻璃材质,却通过复杂的AG工艺处理,实现了极佳的抗指纹特性。即便在不带壳的情况下重度使用,背板依然能保持如玉般的干爽与纯净,指纹残留几乎可以忽略不计。

外观设计

视觉的“消失术”:正面是一块 6.32 英寸的超美小直屏。一加这次将边框控制到了极致的 1.1mm这个厚度,仅仅相当于你手中一张标准银行卡侧边的宽度。当你点亮屏幕,那种四边几乎等宽、画面直接延展到中框边缘的视觉冲击力,是目前市面上绝大多数大屏手机都无法给予的精致感。

边框厚度对比

黄金配重与握持:整机宽度 71.82mm,重量约 194g。一加工程师在内部精密堆叠,实现了 50:50 的天平配重。握在手里时,重心稳稳地落在掌心,不会有任何偏向感。配合黄金曲率 R 角,单手操控时非常顺滑,大拇指可以轻松滑过屏幕的每一个角落。

握持舒适

二、 影像大跃进:补齐唯一的遗憾

影像曾是一加 13T 唯一的“软肋”,而一加 15T 这次选择“暴力补齐”。

Deco 的精工细作:背部的“金属魔方”Deco 依然极具家族辨识度。由于引入了更强的光学模组,凸起在所难免,但一加将其优化得非常克制。整个摄像头模组的凸起高度,大约仅相当于一枚一元硬币的厚度。这种厚度处理,让它在装入兜里时不会产生明显的剐蹭感,放在桌面上也显得十分优雅。

摄像头厚度与硬币对比

潜望长焦的回归:这是最令人兴奋的升级。15T 塞入了一颗 5000 万像素的 3.5 倍潜望长焦镜头。85mm 的黄金焦段在拍摄人像时具有天然的优势。配合 OPPO 家族顶级的 LUMO 凝光影像算法,它在处理复杂光影时展现出了旗舰级的宽容度

人像摄影

在实际测试中,在这里,我们直接给他除了个难题,暗光人像。一加 15T 的出片质感都非常稳健。它不再仅仅是“能拍到”,而是做到了“拍得高级”,彻底撕掉了小屏手机影像平平的标签。

超暗光人像

三、 性能参数:小屏里的“怪兽”内核

在性能这个一加的传统强项上,15T 依然保持了令人窒息的竞争力。

第五代骁龙 8 至尊版:

作为核心心脏,这颗 3nm 工艺的芯片拥有恐怖的算力。配合 16GB LPDDR5X Ultra Pro,它的响应速度快如闪电。在安兔兔测试中,一加 15T 跑出了惊人的 3983248万分如果说市面上普通的手机运行起来像是在平原慢跑,那么 15T 就像是在磁悬浮轨道上贴地飞行。

安兔兔跑分测试

安兔兔跑分测试

冰河散热系统:小空间内的散热一直是难点。一加在 15T 内部塞入了 5150mm² 的巨型 VC 均热板这块均热板的覆盖面积,几乎占到了机身正面投影面积的 80%。无论是连续下载数十个大型应用,还是长时间视频导出,热量都能被迅速均匀地排散,避免了热点聚集。

四、 游戏体验:行业唯一的 165Hz 高刷屏

一加 15T 再次用硬实力证明了:它不仅是旗舰,更是顶级电竞设备。

原生 165Hz 的快感:它是目前行业内唯一搭载 165Hz 超高刷屏的小屏机型。这种刷新率在游玩 FPS 类手游时简直是“物理外挂”。每一帧画面的流转,都如同流水滑过丝绸般顺滑,没有任何视觉上的拖影或延迟。

风驰游戏内核:

游戏测试

依托自研内核,15T 能够实现全局流畅度的智能分配。在实战《和平精英》时,面对复杂的激战场景,帧率图几乎是一条水平直线。

电竞级触控:3200Hz 的瞬时触控采样率,意味着当你大脑下达指令的一瞬间,手机已经完成了开镜和射击。配合灵犀触控芯,哪怕是手指尖最细微的抖动,系统都能精准识别并做出反馈。

风驰游戏内核模式

无忧续航:它的电池容量之大,让手机内部仿佛内置了一个隐形的微型移动电源。即使是重度用户,在 5G 联网、高亮度环境下高强度使用,7500mAh的大电池也能让15T 也能轻松撑过一整天。你再也不需要在出门时时刻关注电量百分比。

闪充全家桶:100W 有线 + 50W 无线闪充早起刷牙洗脸的 10 分钟,就能充入近 30% 的电量。即便前一晚忘记充电,短暂的碎片时间也足够让你在通勤路上毫无焦虑。

超级闪充100瓦

ColorOS 16 的智慧:系统层面的流畅度无需多言。更贴心的是它的 AI 影像功能,一键消除路人、一键去反光,让拍摄后的后期处理变得极为简单。对于双持党,它与 iOS 之间的互联共享功能,也让数据迁移和文件传输变得前所未有的方便。

一加 15T 在我们看来是一款“不讲道理”的产品。它没有因为“小屏”而牺牲任何一项旗舰体验,反而是在 13T 已经足够强大的基础上,通过影像和屏幕刷新率的暴力升级,补齐了最后一块拼图。

我们体验到的这台松弛抹茶的优雅、不占指纹的清爽、银行卡边框般的极致窄边,以及两张卡厚度的长焦 Deco,共同构成了一部目前市面上最值得入手的小屏全能旗舰。它证明了:极致的性能与顶级的影像,在精致的小屏世界里,完全可以共存。如果你追求握持手感,同时又不愿在拍照和游戏上妥协,一加 15T 就是你唯一的选择。

从 Token 到中转站:一文讲清大模型计费、缓存与倍率

2026年3月24日 22:00

从 Token 到中转站:一文讲清大模型计费、缓存与倍率

这篇文章想回答的,其实只有一个核心问题:为什么同样是调用一次大模型,有的平台按美元计费,有的平台显示的是“点数”“余额”“倍率”,而且开启缓存、开启 thinking 之后,扣费逻辑还会明显变化?

要把这件事讲明白,最好的顺序不是直接从“中转站倍率”讲起,而是先回到最底层:Token 是什么,模型到底按什么计费。只有先把官方的计费结构看清楚,后面再理解中转站为什么要引入倍率、配额和折算系数,才不会混淆。


一、Token 的定义与基本内涵

在大模型的世界里,模型并不是按“字数”“句子数”或者“消息条数”来计费,而是按 Token 来计费。

你可以把 Token 理解为:模型处理信息时使用的最小计量单位之一。在最常见的文本场景里,它既不是严格意义上的一个汉字,也不一定等于一个英文单词,而是模型在内部切分文本后得到的一段段片段。

举个直观的例子:

  • 一段中文文本,通常会被拆成若干个 Token;
  • 一段英文文本,可能一个单词对应一个 Token,也可能一个单词被拆成多个 Token;
  • 标点、空格、换行、代码符号,很多时候也都会占用 Token。

所以,Token 更像是模型的“计算字节”。你给模型输入的内容,要先变成 Token;模型生成的回答,也会以 Token 的形式逐步输出。

这也是为什么大模型的价格表几乎都不是写“每千字多少钱”,而是写“每百万 Token 多少钱”。因为对模型厂商来说,真正稳定、可计算、可计费的单位是 Token,而不是自然语言里的“字”或“词”。

1. Token 与字数、词数的区别

Token 不是字数,而是模型处理单位

这是最容易误解的一点。

很多人会下意识地认为:

  • 中文 1 个字 = 1 个 Token;
  • 英文 1 个单词 = 1 个 Token。

但真实情况通常没有这么简单。

因为模型使用的是分词器(tokenizer)来切分内容,而不是按照自然语言语法来数数。于是:

  • 常见短词可能就是 1 个 Token;
  • 生僻词、很长的单词,可能被拆成多个 Token;
  • 数字串、URL、JSON、代码、表格,往往会产生比想象中更多的 Token;
  • 同样一段内容,在不同模型上,Token 数也可能不完全一样。

所以,Token 更准确的理解方式不是“文字长度”,而是模型内部处理内容时的离散单位

2. Token 数差异的形成原因

Token 数并不是只由“内容长度”决定,还和内容形态有关。

比如下面几类内容,通常都会让 Token 结构发生明显变化:

  • 代码:符号多、结构碎,Token 往往增长得很快;
  • 表格 / JSON:键名、标点、引号、缩进都会占用 Token;
  • 中英混合文本:切分粒度更复杂;
  • 长上下文对话:历史消息会被反复带入输入侧;
  • 工具调用 / 函数调用描述:参数定义、schema、返回结构也都要算 Token。

这也是为什么很多人实际使用时会发现:看起来字数不多,但账单并不低。因为模型看到的不是“字数”,而是经过切分后的 Token 序列。

3. 多模态场景下 Token 的扩展含义

当模型进入多模态场景之后,Token 的概念并没有消失,只是它不再只对应“文本片段”。

更准确地说:多模态模型会把图片、音频、视频等输入,先转换成模型可以处理的内部表示,再映射到可计费的 Token 或 Token 等价单位。

因此,多模态里的 Token 可以粗略分成几类理解:

  • 文本 Token:提示词、系统消息、OCR 文本、工具返回文本;
  • 图像 Token:图片经过切块、缩放、编码后形成的视觉计算单位;
  • 音频 Token:音频片段经过声学编码后形成的时间序列单位;
  • 视频 Token:通常是“抽帧后的图像单位 + 音频单位 + 可能的文本上下文”的综合消耗。

这里最关键的一点是:多模态并不是不按 Token 计费,而是把非文本信息也折算成了模型可处理的 Token 结构。

4. 图像 Token 的常见计量方式

图片 Token 的计算方式,不同厂商差异很大,但底层思路通常相似:

先把图片标准化,再按视觉块(patch / tile / region)或分辨率等级折算成若干视觉 Token。

常见的影响因素包括:

  • 图片分辨率;
  • 图片是否会被缩放;
  • 是低清模式还是高精细模式;
  • 是否需要 OCR、表格理解、图表理解;
  • 厂商是否按固定档位计费,而不是按原始像素逐点计费。

所以在很多视觉模型里,并不存在一个简单通用的公式说“1 张图 = 固定多少 Token”。更常见的情况是:

  • 一张小图,可能被折算成较少的视觉 Token;
  • 一张高分辨率图片,可能会先缩放后再按块计费;
  • 同一张图在 low detailhigh detail 模式下,Token 消耗可能差很多。

也就是说,图片真正影响的不是‘张数’,而是图片经过模型预处理之后,需要多少视觉计算单元。

5. 音频 Token 的常见计量方式

音频场景和图片类似,也不是简单按“文件个数”收费,而更接近按时间长度 × 编码粒度来折算。

常见逻辑是:

  • 音频会被切成连续的小时间片;
  • 每个时间片会被编码成模型可处理的声学表示;
  • 最终再转换成音频 Token 或等价计费单位。

所以音频成本通常主要受这些因素影响:

  • 音频时长;
  • 采样率和编码方式;
  • 是否要做实时处理;
  • 是否同时输出逐字转写、说话人分离、时间戳等增强结果。

很多时候你看到“语音模型更贵”或“实时语音特别耗费”,本质上并不是平台在乱加价,而是模型需要持续处理高密度时间序列数据。

6. 视频 Token 的计量复杂性

视频往往是多模态里最复杂的一种,因为它通常不是单一输入,而是三部分叠加:

  • 帧图像;
  • 音频轨道;
  • 提示词 / 上下文文本。

所以一个视频请求的消耗,很多时候可以近似理解为:

视频成本 ≈ 抽帧后的图像成本 + 音频成本 + 文本上下文成本

如果平台对视频做的是“定时抽帧”而不是逐帧分析,那么成本会和:

  • 视频时长;
  • 每秒抽多少帧;
  • 每帧按什么分辨率处理;
  • 是否同步分析音轨;

直接相关。

因此,视频不是“一个文件一次计费”这么简单,而是一个组合型的 Token 消耗体。

7. 多模态 Token 难以横向比较的原因

到了多模态阶段,Token 更不能简单横向比较了。原因在于:

  • 不同厂商的视觉编码方式不同;
  • 不同模型的预处理策略不同;
  • 有的平台按 patch 数计,有的平台按档位计;
  • 有的平台会把图片 / 音频先折算成文本等价 Token,再统一结算;
  • 有的平台则直接给出独立的 image/audio pricing。

所以,当你看多模态价格表时,最稳妥的理解方式不是强行追问“1 张图到底等于多少 Token”,而是先看厂商到底公布的是哪一种计费口径:

  • 文本 Token 单价;
  • 图像输入单价;
  • 音频输入 / 输出单价;
  • 视频或实时流式单价;
  • 是否存在 detail mode、cache、reasoning 等附加维度。

8. 面向用户的实用理解框架

如果只想留下一句最实用的话,那么可以这样记:

文本模型里的 Token,是文本被切分后的处理单位;多模态模型里的 Token,则是文本、图像、音频、视频等信息被模型编码后形成的统一计算单位或等价计费单位。

所以,无论是纯文本还是多模态,厂商真正计费的都不是“你发了几句话、几张图、几个文件”,而是:模型为了理解这些输入、并生成输出,实际消耗了多少可计算的内部单位。


二、大模型采用 Token 计费的原因

从厂商视角看,Token 是最适合做计费单位的,因为它直接对应了模型推理时的实际消耗。

一次调用模型,至少会发生两件事:

  1. 模型读取你输入的内容;
  2. 模型生成它输出的内容。

这两部分都会消耗算力,因此绝大多数模型厂商都会把账单拆成两类:

  • 输入 Token(Input Tokens):你发给模型的内容;
  • 输出 Token(Output Tokens):模型返回给你的内容。

于是,最基础的计费逻辑就成立了:

Cost = 输入成本 + 输出成本

进一步写成标准公式,就是:

Cost = Tin / 1,000,000 × Pin + Tout / 1,000,000 × Pout

其中:

  • Tin:输入 Token 数量
  • Tout:输出 Token 数量
  • Pin:输入单价(每百万 Token)
  • Pout:输出单价(每百万 Token)

这就是大模型最原始、最通用的官方计费框架。


三、大模型计费规则的基本结构

理解计费时,有三个结论必须先记住。

1. 输入与输出价格的差异

大多数厂商都会把输入价格和输出价格分开,而且输出往往比输入更贵。原因很简单:生成内容比单纯读取内容更消耗推理资源。

所以,同样是 1 万个 Token:

  • 如果它们主要出现在输入侧,费用可能较低;
  • 如果它们主要出现在输出侧,费用通常更高。

这也是为什么很多人会误以为“我明明只问了一个简单问题,为什么扣费不低”——因为真正贵的,可能不是你发出去的那段提示词,而是模型生成出来的大段回答。

2. 计费依据是 Token 数而非消息条数

不是说你只发了一条消息,费用就一定低;也不是说多轮对话就一定更贵。真正决定成本的,是每一轮累计消耗了多少 Token。

如果你的提示词很长、上下文很多、模型输出很长,那么哪怕只调用一次,也可能比多轮短对话更贵。

3. 历史上下文对输入成本的影响

在多轮对话中,模型并不是“记住了你上一次说过的话”这么简单。更准确地说,系统通常会把前面的消息重新整理后再传给模型,于是这些历史内容也会继续占用输入 Token。

因此,对话越长,上下文越大,输入成本往往也会越来越高。这也是后面谈缓存和中转站时必须关注的前提。


四、缓存机制下的计费变化

当模型厂商支持缓存之后,输入侧就不再只有一种价格了。

缓存的核心思路是:如果你每次请求里都有一大段重复的前缀内容,比如系统提示词、固定知识库上下文、工具定义、统一模板等,那么这些内容没必要每次都按完整成本重复处理。于是厂商会把其中命中的部分,按更低的价格计费。

这时,输入 Token 通常要拆成两部分:

  • 未命中缓存的输入 Token
  • 命中缓存的输入 Token

对应的公式也会变成:

Cost = Tuncached / 1,000,000 × Pin
     + Tcached / 1,000,000 × Pcache
     + Tout / 1,000,000 × Pout

其中:

  • Tuncached:未命中缓存的输入 Token
  • Tcached:命中缓存的输入 Token
  • Pcache:缓存命中部分的输入单价

这里最重要的一点是:缓存优化的是输入侧成本,不是整次请求的全部成本

也就是说:

  • 命中缓存的输入会变便宜;
  • 没命中的输入仍按原价计算;
  • 输出 Token 依然按输出价格计算。

所以,缓存命中不等于“这次调用几乎不要钱”,它只是让重复输入这部分更便宜了。


五、Thinking / Reasoning 模式下的成本变化

除了缓存,另一个经常让人困惑的变量,是 thinking / reasoning 模式。

它本质上意味着:模型在输出最终答案之前,可能会先生成一部分用于推理、规划、分析的中间 Token。这些 Token 有时对用户可见,有时部分可见,有时只体现在统计口径里,但它们通常都会带来额外成本。

因此,thinking 模式和普通模式的差别,可以先粗略理解为:

普通模式:

Cost_normal = 输入成本 + 输出成本 + 缓存相关成本

thinking 模式:

Cost_thinking = 输入成本 + 输出成本 + 缓存相关成本 + 思考 Token 成本

更直白地说,thinking 模式之所以更贵,往往不是因为“模型换了一套完全不同的收费体系”,而是因为它在原本的输入/输出结构之外,又额外产生了更多需要计费的 Token。

在实际产品里,这些思考 Token 往往更接近输出侧开销;而在多轮对话中,如果上一轮的思考内容被完整回传到下一轮,它又可能再次进入输入侧成本。

所以,thinking 模式的本质不是“神秘加价”,而是 Token 结构更复杂了


六、官方计费结构的核心要点

到这里,其实可以先把官方计费逻辑浓缩成一句最实用的话:

大模型官方计费,本质上就是在计算三类东西:未缓存输入、缓存命中输入、输出;如果开启 thinking,再额外考虑思考 Token 带来的成本。

也就是说,官方世界关心的核心变量始终是:

  • 输入多少;
  • 其中多少命中了缓存;
  • 输出多少;
  • thinking 额外增加了多少 Token。

只要这一层搞清楚,后面看中转站的“倍率”“点数”“配额”,就会顺很多。因为中转站并没有发明一套脱离官方规则的物理定律,它只是把这些官方成本,重新包装成了自己的结算体系。


七、中转站的角色与功能定位

讲完 Token 和官方计费,再来看“中转站”就容易多了。

所谓中转站,通常可以理解为:位于用户和上游模型厂商之间的一层聚合与转发服务

它一般会做几类事情:

  • 统一接入不同模型厂商的接口;
  • 提供兼容层,让不同模型尽量用相似的调用方式访问;
  • 管理密钥、额度、分组、渠道、限流、日志等运营能力;
  • 把上游按美元或人民币计费的模型成本,转换成平台自己的余额、点数或配额系统。

所以,中转站并不等于模型本身,它更像是一个“流量分发与结算层”。

从用户角度看,中转站的价值往往在于:

  • 可以在一个面板里切换多个模型;
  • 可以用更统一的方式管理不同渠道;
  • 可以把费用、倍率、权限、配额统一配置。

但也正因为它处于“中间层”,所以它展示出来的扣费方式,未必和上游厂商价格表一模一样。


八、中转站倍率机制的来源

很多人第一次看中转站面板时,最困惑的并不是价格本身,而是“倍率”这个概念。

因为在 OpenAI、Anthropic、Google 这类上游厂商的价格页里,更常见的是:

  • Input
  • Cached input / Cache read
  • Output
  • Reasoning / thinking 相关统计

它们描述的,本质上都是每百万 Token 的官方单价

而到了中转站里,界面语言往往会变成:

  • 模型倍率
  • 分组倍率
  • 补全倍率
  • 缓存倍率
  • 扣费倍率

这说明一件事:倍率通常不是上游厂商的原生计费单位,而是中转站为了把官方成本折算成平台内部余额、点数或配额,而人为引入的一层结算抽象。

说得更直接一点:

官方世界在算货币成本,中转站世界在算平台额度;倍率,就是连接这两套计量体系的换算系数。

因此,中转站并不是创造了一套脱离官方价格的全新物理定律,而是把官方的输入、缓存输入、输出、thinking 成本,重新包装成了自己的扣费语言。


九、倍率机制的折算逻辑

如果再往深一层看,所谓“倍率”,本质上是在回答下面这个问题:

同样消耗 1 个 Token,不同模型、不同渠道、不同用户组,应该从平台余额里扣掉多少“内部单位”?

于是,中转站通常不会直接把“美元价格”原样展示给用户,而是会先选定一个内部计费基准,再把不同成本映射进去。

你可以把它理解成下面这种抽象:

平台内部单价 = 官方单价 × 平台折算系数

如果进一步写成输入 / 输出分离的形式,就是:

内部输入单价 = 官方输入单价 × 折算系数
内部输出单价 = 官方输出单价 × 折算系数

但很多中转站并不直接展示“内部输入单价”和“内部输出单价”,而是把它继续拆成几个更方便运营配置的变量:

  • 模型倍率:决定这个模型整体贵不贵;
  • 补全倍率:决定输出 Token 按输入 Token 的多少倍折算;
  • 分组倍率:决定不同用户等级是否加价或打折;
  • 缓存倍率:决定缓存命中的输入是否按更低权重结算。

所以,倍率真正折算的并不是一个抽象标签,而是不同 Token 类型在平台内部的结算权重


十、同一模型倍率差异的形成原因

很多人看到某个平台的 GPT-4o 倍率是 10,另一个平台是 3,第一反应是“前者更贵”。但这其实未必成立。

因为倍率本身不是统一货币单位,它至少会受到四层因素共同影响。

1. 渠道来源差异

同样是某个模型,平台接入的可能是:

  • 官方直连渠道;
  • Azure / AWS / GCP 等云渠道;
  • 区域代理或企业采购渠道;
  • 非官方逆向或代充渠道。

这些渠道的真实成本、稳定性和可持续性都不一样,因此倍率自然不会一样。

2. 服务质量差异

有些平台卖的不只是“能不能调用”,还包括:

  • 更高的并发上限;
  • 更稳定的可用性;
  • 更低的延迟;
  • 更少的限流和封禁风险。

于是你看到某些模型后面带 -official-fast-stable 之类的标记,本质上往往是在告诉你:这不仅是模型名差异,更是服务等级差异。 服务质量越高,倍率通常也越高。

3. 平台定价策略差异

中转站不是单纯的“成本搬运工”,它还会做运营策略:

  • 对热门模型加价;
  • 对新模型补贴引流;
  • 用低倍率吸引注册;
  • 用高倍率覆盖售后、风控、坏账和带宽成本。

因此,倍率里通常不只有“技术成本”,还包含平台自己的商业策略。

4. 充值汇率与货币结算差异

如果平台是人民币充值、美元成本,那么它还要处理:

  • 汇率波动;
  • 支付手续费;
  • 提现或结算风险;
  • 余额单位与真实货币之间的映射关系。

这就是为什么有些平台会出现一种表面上看起来很奇怪的现象:

充值 1 元,却给你记 1 美元口径的余额;为了把这个差额补回来,就会把模型倍率整体抬高。

所以,倍率不是纯技术参数,而是“上游成本 + 服务质量 + 运营策略 + 货币体系”共同叠加后的结果。


十一、中转站倍率体系的主要类型

这一节最容易混淆的地方在于:补全倍率、缓存倍率,和分组倍率并不是同一个层级的概念。

很多中转站会把这些词都统一写成“倍率”,再配合站内余额、点数、额度这些内部单位一起展示,于是用户很容易误以为:它们全都是平台自己发明出来的收费规则。

但更准确地说,这里至少要分成两层:

  • 上游大模型原生计费维度:Input、Output、Cache;
  • 中转站平台运营维度:模型倍率、分组倍率、余额折算。

也就是说,补全和缓存首先是上游模型本身就存在的计费方式;而分组倍率,才是平台为了统一调价而额外叠加的一层运营参数。

1. 上游原生计费项:输入、补全、缓存

先把最底层说清楚。

对绝大多数主流大模型来说,官方计费本来就会区分:

  • 输入(Input):你发给模型的 Token;
  • 补全 / 输出(Completion / Output):模型生成给你的 Token;
  • 缓存(Cache):命中缓存的输入 Token,按更低价格计费。

所以,很多中转站面板里所谓的“补全倍率”“缓存倍率”,本质上并不是平台凭空创造出来的新概念,而是在映射上游 input / output / cache 的价格差异

换句话说:

  • 输入就是大模型官方的 input;
  • 补全就是大模型官方的 output;
  • 缓存就是命中缓存后的 input 计费口径。

在绝大多数模型里,缓存命中通常大约按普通输入价格的 1/10 结算;但也有少数模型会进一步细分成:

  • **缓存写入(cache write)**价格;
  • **缓存读取(cache read)**价格。

因此,如果一个中转站把“补全倍率”“缓存倍率”单独拿出来强调,很多时候它讲的并不是站内独创规则,而只是把上游大模型原本就有的计费结构,用站内配额语言重新包装了一遍。

2. 模型倍率:把上游成本折算成站内单位

真正进入中转站自己的体系后,才会出现“模型倍率”这类平台侧参数。

模型倍率决定的是:同样一组 input / output / cache 消耗,在这个站里最终按多高的站内权重结算。

它本质上承接的是:

  • 上游真实采购成本;
  • 站内余额单位被放大或缩小后的折算关系;
  • 平台自己的利润、汇率和风控策略。

这也是为什么很多中转站会先把站内金额单位调大,再在倍率层面做文章。表面上看倍率很多、结构很复杂,但其中有一部分其实只是把上游官方成本重新折算成站内内部单位

所以,模型倍率更接近平台折算系数,而不是上游模型的原生价格字段。

3. 分组倍率:给一组统一调倍率

分组倍率的定位要单独拎出来,因为它和补全、缓存不是一个概念。

分组倍率决定的是:平台要不要对某一组用户、某一类套餐、某一个渠道分组做统一加价或打折。

例如:

  • 普通用户组:1.0
  • VIP 用户组:0.8
  • 企业用户组:0.95

这类倍率并不对应 input、output 或 cache 的物理成本差异,而是平台运营层面对一整组流量做统一调整。

所以它的本质不是“模型怎么收费”,而是:平台准备让哪一组用户按什么系数结算。

4. 更准确的理解方式:先分层,再看扣费

如果把这些概念放在一起看,更准确的理解顺序应该是:

  1. 先看上游模型怎么收费:input、output、cache,必要时再看 cache read / cache write;
  2. 再看中转站怎么折算:是否放大了站内金额单位,是否设置了模型倍率;
  3. 最后看平台怎么统一调价:是否对某个分组额外乘上分组倍率。

一句话总结就是:

补全和缓存,首先是上游大模型的计费维度;模型倍率和分组倍率,才是中转站在这些上游成本之上额外叠加的站内折算与运营参数。

十二、中转站扣费公式的完整表达

有了上面的定义后,就可以把中转站的扣费逻辑写得更完整。

1. 基础输入输出计费公式

如果先不考虑缓存和 thinking,只保留最常见的输入/输出结构,那么可以写成:

Quota_basic = (Tin + Tout × Rout) × Rmodel × Rgroup

其中:

  • Tin:输入 Token
  • Tout:输出 Token
  • Rout:补全倍率 / 输出倍率
  • Rmodel:模型倍率
  • Rgroup:分组倍率

这正对应很多 OneAPI / NewAPI 系统里最常见的基础扣费表达。

2. 纳入缓存后的计费公式

如果平台支持缓存命中折算,那么更准确的形式应该写成:

Quota_cache = (Tuncached + Tcached × Rcache + Tout × Rout) × Rmodel × Rgroup

其中:

  • Tuncached:未命中缓存的输入 Token
  • Tcached:命中缓存的输入 Token
  • Rcache:缓存倍率

这条公式比“输入 + 输出 × 补全倍率”更完整,因为它能解释:为什么同样是 10 万输入 Token,有的人扣得很多,有的人扣得很少——差别往往就在缓存命中率。

3. 纳入 Thinking 的计费公式

如果模型开启了 thinking / reasoning,那么输出侧通常还会多出一部分推理 Token,于是可以进一步写成:

Quota_thinking = (Tuncached + Tcached × Rcache + (Tvisible + Tthink) × Rout) × Rmodel × Rgroup

其中:

  • Tvisible:用户可见输出 Token
  • Tthink:thinking / reasoning 额外产生的 Token

这条式子能够解释一个很常见的现象:

为什么有些问题看起来不复杂,但一开 reasoning,平台消耗会立刻明显上升。

因为从平台视角看,它并不关心这些 Token 是“用户看见的回答”还是“模型内部思考过程”,只要上游按 Token 收费,平台就必须把它折算进去。


十三、仅比较倍率数字的局限性

这一点其实是中转站里最容易踩坑的地方。

很多用户会把不同平台的倍率数字直接横向比较,比如:

  • A 站某模型倍率 = 1
  • B 站某模型倍率 = 10

于是就得出“B 站贵了 10 倍”的结论。

但这个结论常常并不成立,因为你忽略了另一个变量:平台余额单位本身是什么。

真正应该比较的,不是“倍率的绝对值”,而是单位 Token 最终折合成了多少真实货币成本

可以把它抽象成:

实际输入单价 ≈ 余额单位价值 × Rmodel × Rgroup
实际输出单价 ≈ 余额单位价值 × Rout × Rmodel × Rgroup

如果再把充值口径算进去,那么跨平台比较时,更接近现实的判断方式是:

实际人民币成本 ≈ 充值汇率 × 平台倍率体系 × Token 消耗结构

这也就是为什么会出现这样一种情况:

  • 平台 A 的倍率数字小;
  • 但平台 A 的“每 1 元可兑换余额”也更少;
  • 最终折算下来,反而并不便宜。

4. 缓存率对跨平台比较的影响

很多人在跨平台比较价格时,还会漏掉一个非常关键的变量:缓存率(或缓存命中率)

因为平台展示给你的往往只是:

  • 充值汇率;
  • 倍率;
  • 标称 Token 额度。

但你真正“花出去”的有效成本,还取决于请求里有多少输入命中了缓存。

在编程场景里,如果是固定账号持续使用,例如自己用 Max 或稳定拼车,常见会出现 90% ~ 95% 的输入 Token 走缓存。换句话说,缓存 Token 数可能达到写入 Token 数的 10 ~ 20 倍。这时,实际费用往往不会等于“全部按普通输入 Token 原价结算”,而更接近 按标称 Token 价格的 80% ~ 85% 来理解。

反过来说,如果某个中转站表面倍率不高、兑换比例也不差,但因为号池轮询、账号频繁切换或缓存技术做得一般,导致你的缓存率明显偏低,那么你的实际单位成本就会上升。于是就会出现一种常见感受:

不是平台给的 Token 数是假的,而是因为缓存率低,同样的 Token 更“不抗用”。

从实践上看,可以把常见模式粗略分成三类:

  • 固定账号 / 固定会话型:缓存率理论上最接近官方,适合长期连续编程。
  • 按次数限额型产品:例如部分 IDE / 工具订阅,通常不展示缓存 Token,也就很难直接谈缓存率。
  • 号池轮询反代型:用户缓存率波动最大,是否能做到 80% 以上,很大程度取决于中转站自己的缓存与路由技术。

所以,跨平台比较时,更接近真实的判断方式应该是:

实际人民币成本 ≈ 充值汇率 × 平台倍率体系 × Token 消耗结构 × 缓存率修正

或者换句话说:

比较价格,不能只看“¥多少 = $1” 或倍率数字,还要看这个平台能不能把你的高重复上下文真正缓存住。

所以,倍率只能在同一平台内部比较模型相对贵贱,不能脱离充值规则和缓存率去跨平台直接比较。


十四、官方成本与平台配额的对照示例

假设某次请求中:

  • 未缓存输入 Tuncached = 20,000
  • 缓存输入 Tcached = 80,000
  • 可见输出 Tvisible = 5,000
  • thinking Token Tthink = 3,000

再假设上游官方价格是:

  • 输入 Pin = 2.50 / 1M
  • 缓存输入 Pcache = 0.25 / 1M
  • 输出 Pout = 15 / 1M

那么按官方计费估算:

Cost = 20000/1,000,000 × 2.50
     + 80000/1,000,000 × 0.25
     + (5000 + 3000)/1,000,000 × 15

计算后得到:

Cost = 0.05 + 0.02 + 0.12 = 0.19 美元

现在假设某个中转站进一步定义:

  • Rcache = 0.1
  • Rout = 6
  • Rmodel = 1.2
  • Rgroup = 1

那么它的配额消耗就可能写成:

Quota = (20000 + 80000 × 0.1 + (5000 + 3000) × 6) × 1.2
      = (20000 + 8000 + 48000) × 1.2
      = 76000 × 1.2
      = 91200

这时你在平台面板里看到的,可能就不是“0.19 美元”,而是“扣除了 91200 点额度”。

单位虽然变了,但底层逻辑没有变:

  • 官方在算货币成本;
  • 中转站在算平台额度;
  • 倍率就是两者之间的折算桥梁。

十五、倍率体系的可靠性判断

如果把“怎么理解倍率”进一步落到实践层面,那么判断一个平台是否靠谱,至少要看三件事。

1. 是否对应官方成本结构

一个靠谱的平台,哪怕不用“美元单价”直接展示,也至少应该能让你看出:

  • 输入怎么算;
  • 输出怎么算;
  • 缓存是否单独折算;
  • thinking 是否有额外消耗。

如果这些都说不清,只给一个笼统倍率数字,那透明度通常不够。

2. 是否公开模型计费明细

正规的中转站,通常会公开:

  • 模型倍率;
  • 补全倍率;
  • 分组倍率;
  • 余额兑换关系;
  • 渠道说明或模型说明。

如果平台只有一个模糊的“倍率很低”,却没有明细页、模型页或计费页,那么风险通常更高。

3. 低价是否具备合理性

如果某个平台价格长期明显低于官方理论成本,就要提高警惕。因为这往往意味着它可能依赖:

  • 逆向网页接口;
  • 不稳定代充渠道;
  • 混合池或不透明转发;
  • 随时可能失效的临时资源。

这种平台也许适合测试或体验,但未必适合生产环境。


十六、常见误区辨析

为了避免混淆,最后把几个最常见的误区集中说清楚。

1. 缓存命中并不意味着整体成本显著下降

缓存只会降低命中的输入部分,不会把未命中的输入和输出一起变便宜。真正昂贵的部分,很多时候依然是输出和 reasoning。

2. 补全倍率并非任意设定的参数

它通常对应的是官方“输出比输入更贵”的现实,只不过平台把这种差异,用一个更容易运营配置的比例表达出来。

3. Thinking 并非凭空增加的收费项

thinking 本质上仍然是 Token 消耗,只不过这些 Token 来自模型的推理过程,因此会额外抬高输出侧成本。

4. 同名模型倍率差异不必然意味着不合理收费

也可能是渠道不同、QoS 不同、汇率不同、补贴策略不同。倍率差异本身并不自动等于平台不正规。

5. 跨平台比较不能脱离充值规则

跨平台比较时,真正重要的是“最终单位 Token 折合多少钱”,而不是后台写了一个多大的倍率数字。


十七、可直接使用的四条核心公式

如果你只想留下最有用的结论,那么记住下面四条就够了。

1. 官方普通模式公式

Cost_normal = 未缓存输入 / 1,000,000 × 输入单价
            + 缓存命中输入 / 1,000,000 × 缓存单价
            + 可见输出 / 1,000,000 × 输出单价

2. 官方 Thinking / Reasoning 模式公式

Cost_thinking = 未缓存输入 / 1,000,000 × 输入单价
              + 缓存命中输入 / 1,000,000 × 缓存单价
              + (可见输出 + 思考 Token) / 1,000,000 × 输出单价

3. 中转站基础倍率公式

Quota_basic = (输入 Token + 输出 Token × 补全倍率)
            × 模型倍率 × 分组倍率

4. 中转站完整配额公式

Quota_full = (未缓存输入 + 缓存输入 × 缓存倍率 + (可见输出 + 思考 Token) × 输出倍率)
           × 模型倍率 × 分组倍率

这四条公式,基本就能把“官方怎么计费”和“中转站为什么这么扣费”完整串起来。


十八、结论:从 Token 到中转站的理解路径

整件事最值得记住的,其实就是一句话:

官方计费看的是 Token 结构——输入、缓存输入、输出,以及 thinking 带来的额外 Token;中转站做的,则是在这套结构之上,再叠加模型倍率、补全倍率、分组倍率和缓存倍率,把官方成本映射成自己的余额与配额规则。

所以,理解大模型计费最好的路径永远是:先理解 Token,再理解官方价格,再理解中转站倍率。顺序一旦反过来,很多概念就很容易越看越乱。

写在最后🧪

这里是言萧凡的 AI 编程实验室。 我会在这里持续记录和分享 AI 工具、编程实践,以及那些值得沉淀下来的高效工作方法。 不只聊概念,也尽量分享能直接上手、能够复用的经验。 希望这间小小的实验室,能陪你一起探索、实践和成长。 2026 年,一起进步。

为什么要做一个 iOS bug 自动修复的 agent 程序

作者 wyanassert
2026年3月24日 16:07

为什么要做一个 iOS Bug 自动修复的 Agent 程序

一、为什么不直接做 IDE 插件

如果目标只是”在 IDE 里更方便地写代码”,那直接基于 CodeBuddy 这类 Agent IDE 做插件,通常更快、更省成本。

但我的目标不止于此:

  • 把”修复/分析/定位/验证”沉淀成可复用能力
  • 让 Agent 不依赖某个 IDE 才能工作
  • 把人的经验流程产品化、平台化、自动化
  • 围绕 iOS 问题定位、日志分析、修复建议形成领域能力

这些目标决定了我需要一套自建的 Agent 架构,而不是一个 IDE 插件。


二、自建 Agent 架构的核心优势

1. 掌握的是”工作流”,不是”某个 IDE 的扩展点”

基于 Agent IDE 做插件,本质上是在它既有能力上”加一层”。而自建 Agent 架构,本质上是在定义:

  • 任务如何拆解
  • 上下文如何收集
  • 工具如何选择
  • 失败如何回退
  • 结果如何验证
  • 多轮推理如何收敛

这意味着我拥有的是流程控制权

这个差别很大:

  • 插件模式:在别人的操作系统上写 App
  • Agent 架构模式:在定义自己的操作系统

未来我想做的事情——自动读取崩溃日志、自动定位可疑代码、自动生成 patch、自动跑校验、自动输出修复报告、自动接入 CI / 工单 / IM / 代码平台——自建 Agent 架构会比 IDE 插件自然得多。

2. 沉淀的是”领域智能”,不是通用编程助手能力

CodeBuddy 这类 Agent IDE 的强项是通用编码协作:补全、重构、对话式改代码、搜索代码、生成测试。

而我的系统围绕 iOS Bug Auto Fix 在做,重点是:

  • 崩溃堆栈理解
  • 符号/模块/调用链关联
  • Objective-C / Swift / Pod 生态理解
  • 特定业务代码结构的定位
  • 历史问题模式复用
  • 修复策略模板化

这些能力,通用 Agent IDE 不会天然替我做好。我做 Agent 架构的真正价值不是”我也能调用 LLM 了”,而是:把特定领域的高价值决策流程封装成了 Agent。 这会形成自己的护城河。

3. 能做”非交互式自动化”,而不只是”人在 IDE 里点来点去”

IDE 插件天然偏向人在本地、打开工程、交互式提问、临场辅助。而自建 Agent 更容易扩展到命令行、批处理、服务化、CI/CD、机器人触发、定时任务、工单驱动修复。

未来完全可以做成这种链路:

1
崩溃日志/工单 → 问题归类 Agent → 代码定位 Agent → 修复策略 Agent → 生成 Patch → 验证 Agent → 提交 PR / 输出报告

这类能力,不是 IDE 插件的主战场。

4. 更强的”可解释性”和”可观测性”

自建 Agent 架构时,可以记录每一步:

  • 为什么选这个工具
  • 为什么判定这个文件相关
  • 哪一步检索到了关键证据
  • 哪次修复失败了
  • 哪种策略成功率最高
  • 每种 Bug 类型平均耗时多久

这带来几个重要价值:便于调试 Agent、便于持续优化 prompt / 工具策略、便于做质量评估、便于做企业内部合规审计。而很多 Agent IDE 内部流程只能”感觉它这么做了”,但很难完整掌控它的决策细节。

5. 模型、工具、供应商解耦

基于某个 Agent IDE 插件体系开发,通常会受到模型支持、上下文拼装方式、工具协议、权限边界、升级兼容性等限制。而自建 Agent 架构,可以自由决定用哪个模型、不同子任务切哪个模型、怎么做路由、缓存、检索、工具编排、降级和兜底。获得的是架构主导权,而不是平台适配权

6. 能把”经验”复用到 IDE 之外

如果只是写成 IDE 插件,很多价值会被锁死在 IDE 内。但做成独立 Agent 能力,以后这些东西都能复用到 Web 界面、命令行、VSCode / JetBrains / 自研 IDE、Slack / 飞书 / 企业微信机器人、服务端 API、测试平台、发布平台、缺陷平台。投入更像是在建设能力中台,而不是做一个单点入口。

7. 更适合做多 Agent 分工

当任务复杂到需要角色分工时,自建架构优势更明显。可以拆成:

Agent 职责
Planner Agent 任务拆解
Retriever Agent 找代码和上下文
Diagnoser Agent 判断根因
Patch Agent 生成修复代码
Verifier Agent 运行验证
Reporter Agent 输出报告

IDE 插件当然也能”伪多 Agent”,但一般都会受限于宿主产品的交互模型。自建则可以真正把分工、状态、上下文边界、交接协议做清楚。


三、这条路的代价

1. 在重复造很多”基础设施轮子”

包括上下文管理、工具调用协议、提示词编排、重试/超时/回退、文件读写安全、结果验证、token 成本控制、观测和日志、会话状态管理。这些在成熟 Agent IDE 里很多已经做好了。短期看,肯定更慢、更贵、更累。

2. 需要自己为”效果稳定性”负责

自建后,要自己解决:为什么这次检索不到、为什么上下文污染了、为什么选错工具、为什么 patch 不可执行、为什么修复建议不稳定、为什么不同仓库表现差异大。获得自由的同时,也接管了复杂性。

3. 如果场景主要是”本地编码辅助”,ROI 未必更高

如果用户核心诉求只是在 IDE 里聊天、改改代码、顺手做点搜索、生成一些 patch,那自建 Agent 架构带来的收益可能并不明显。可能出现架构先进了,但用户体感未必更强的情况。


四、与通用 Agent IDE 的差异化定位

一句话定位

不是”更会写代码的 IDE 助手”,而是”面向 iOS Bug 定位、诊断、修复与验证的专用智能执行系统”。

差异对比表

维度 我的 Agent 架构 CodeBuddy / Cursor / Copilot Workspace
核心目标 解决特定领域问题(iOS bug 定位、分析、修复、验证) 提升通用编码效率
核心对象 问题处理流程 代码编辑过程
工作单元 一次完整的缺陷处理链路 一次对话、一段代码修改
触发方式 日志、崩溃堆栈、工单、CI、命令行、服务调用 IDE 内交互、选中代码、对话输入
能力重点 诊断、定位、决策、修复策略、验证闭环 补全、解释、生成、搜索、重构
领域知识密度 很高,内置 iOS/Crash/工程结构知识 偏通用,领域知识较浅
自动化深度 半自动甚至全自动链路 多数以人机协作为主
可观测性 记录每一步证据、推理、工具调用、成功率 通常黑盒程度更高
可扩展性 可接日志系统、工单系统、测试系统、CI、PR 流程 主要受限于 IDE 插件边界
平台依赖 独立能力层,不依赖单一 IDE 依赖宿主 IDE/平台生态
长期资产 沉淀为组织级问题处理能力 沉淀为某 IDE 内的使用体验
护城河来源 领域流程、知识、验证闭环、历史反馈 产品体验、模型集成、编辑器生态

五、哪些是真壁垒,哪些是在重复造轮子

判断标准

这个模块如果明天被一个成熟框架替换掉,我的核心价值会不会下降?

  • 不会明显下降:大概率是基础设施
  • 会明显下降:可能是壁垒层

真正值得重点投入的壁垒层

1. iOS 问题理解与归因知识

崩溃堆栈解析、符号/模块/类/调用链映射、OC/Swift 混编上下文理解、生命周期/线程/内存/KVO/通知/Block/主线程 UI 更新等问题模式、常见崩溃类型到修复策略的映射。这类能力沉淀好了,不是通用 IDE 随便能替代的。强壁垒。

2. 问题处理 SOP

稳定的处理链路:读取错误信号 → 归类问题类型 → 缩小嫌疑范围 → 关联代码上下文 → 选择修复策略 → 生成 patch → 执行验证 → 输出结论与风险。这个流程代表了团队如何排查问题、如何做决策分层、如何降低误修概率。强壁垒。

3. 修复策略库 / 模式库

沉淀 CrashType → RootCauseCandidates → VerificationSteps → PatchTemplate → RiskHints 这种结构。覆盖数组越界、空指针、野指针、线程竞争、主线程违规调用、通知/KVO 生命周期遗漏、容器并发修改、异步回调释放时序问题等。每一类问题对应典型特征、定位信号、修复范式、验证点。可复利的核心资产。

4. 验证闭环

改完代码后做静态检查、跑定向测试、检查编译影响范围、输出风险说明、对修复结果做置信度评估。从”助手”进入”执行系统”。关键护城河。

5. 历史案例反馈系统

积累哪类问题最常见、哪类修复策略成功率最高、哪些模块最容易出问题、哪种上下文组合最容易定位成功、哪类 patch 最容易被 reject。系统会越来越像”会学习的故障处理平台”。长期壁垒。

有价值但不要过度自研的中间层

模块 建议
任务拆解器 / Planner 可以做,但必须领域化,否则容易沦为通用壳子
多 Agent 分工 多 Agent 本身不是壁垒,领域化分工才是壁垒
上下文组装系统 保留策略,少造基础设施

大概率属于”重复造轮子”的部分

模块 建议
通用聊天壳 / UI 壳 够用就行
通用代码读写工具封装 稳定优先,不要过度精雕
通用 ReAct / Agent Loop 不要把”有 loop”误认为”有壁垒”
通用记忆系统 通用 memory 尽量轻,重点做 case memory
通用 Prompt 编排器 prompt 系统化可以有,但别把它当主产品

六、系统架构收敛

我把整个系统收敛成三层:

1
2
3
4
5
6
7
8
9
10
11
12
┌─────────────────────────────────────────┐
│ 入口层(做薄) │
│ IDE / CLI / CI工单 / 服务API │
├─────────────────────────────────────────┤
│ 领域决策层(持续加厚) │
│ iOS缺陷分类 / 上下文选择策略 / 根因分析 │
│ 修复策略选择 / 风险评估 │
├─────────────────────────────────────────┤
│ 执行与验证层(够稳就行) │
│ 代码检索编辑 / Patch生成 / 构建测试 │
│ 结果验证 / 报告输出 │
└─────────────────────────────────────────┘
  • 入口层:不要重投太多
  • 执行与验证层:够稳就行
  • 领域决策层:最该持续加厚的地方

七、最容易出现的风险

把大量精力花在让 Agent 看起来更像 Agent,而不是让它更会解决 iOS 问题。

典型表现:角色越来越多、prompt 越来越复杂、tool 越来越多、框架越来越完整,但定位成功率没上升、修复成功率没上升、验证能力没增强、真实用户价值不明显。

判断功能优先级时,统一用三个指标:

  1. 定位准确率是否提升
  2. 修复成功率是否提升
  3. 端到端处理时间是否下降

只要不能提升这三项之一,就谨慎做。


八、投入优先级

优先级 方向
第一优先级 iOS bug 分类 → 根因 → 修复策略 → 验证 做成稳定闭环
第二优先级 把历史案例沉淀成可复用知识
第三优先级 把入口做薄,支持 IDE / CLI / CI 复用
第四优先级 尽量复用通用 Agent 基础设施,不要在壳层卷复杂度

九、结论

我不是在做另一个通用 AI 编码助手,而是在做 iOS 缺陷处理的领域执行系统。

真正的壁垒不在 Agent 外壳,而在领域知识、决策流程、修复策略和验证闭环。

通用的对话、工具调用、Planner、Memory 更多是基础设施,应尽量复用而非重造。

后续投入应聚焦提升定位准确率、修复成功率和端到端效率,而不是继续增加通用 Agent 复杂度。

分水岭在于:我的系统是在”帮助程序员在 IDE 里更快操作”,还是在”替程序员执行一整套 iOS 问题处理流程”。答案是后者,所以自建 Agent 架构是正确的选择。

一加 15T 发布:顶配性能加长续航,小屏旗舰的新模板

作者 梁梦麟
2026年3月24日 21:14

3 月 24 日,一加发布了新一代小屏旗舰一加 15T,定价 4299 元起。

和上一代 T 系列机型一样,一加 15T 可算是一款同定位性能配置的小屏版一加 15,拥有标准的旗舰芯片组和储存组合,这次官方还加上更大容量的 7500mAh,补足小屏性能机在续航方面的短板,让它的体验更加完整。

先来看看外观,一加 15T 沿用了和一加 15 相近的设计。

金属 DECO 沿用了 15 系列的方块化圆润造型,DECO 内的摄像头和补光灯用大小长条形椭圆设计包裹,左侧是「主摄+ 3.5x 潜望式长焦」双摄结构,右侧是补光灯。

一加给 15T 提供了三款新配色,分别是低饱和抹茶绿的「松弛抹茶」,深棕色的「纯粹可可」,还有以冷白色调为主,用微弧氧化工艺+哑光白金属中框实现手机全新一百到底的「治愈白巧」,三款配色都用上了巧克力做主体。

屏幕尺寸压缩到 6.32 英寸,机身尺寸为 150.56mm x 71.82mm 8.35mm,机身比一加 15 短一些,厚度几乎一致,重量则从一加 15 的 211g(原色沙丘)-215g(绝对黑、雾光紫)下降到 194g,对于一款能塞下旗舰配置和 7500mAh 大电池的手机来说,真的很克制。

手机缩短了之后,15T 单手操作的感觉很舒服。微弧氧化工艺制作的后盖,一加 15T 的触感非常丝滑,裸机上手和原色沙丘配色的一加 15 一样舒适。

整机支持 IP66 & IP68 & IP68 & IP69K 防尘防水认证,日常裸机使用基本没问题。但考虑到保护机身外观质感的一体性,包装内也配备了同色软壳,耐用度几乎不需要担心了。

屏幕方面,一加 15T 搭载了一块 6.32 英寸 1.5K 165Hz LTPS 旗舰小直屏。屏幕采用四边等宽 1mm 超窄边框设计,点亮时手机正面几乎都是屏幕。

这块旗舰小直屏用上了新一代发光材质,正常状态下普通的最高亮度为 800nits,HBM 亮度为 1800nits,局部峰值亮度能达到 3600nits。屏幕支持硬件级的 1nit 暗夜显示和太阳显示,还有明眸护眼模式,配备 3840Hz 超高频 PWM 调光、全亮度低频闪+经典低频闪模式,可以满足用户在大阳光户外和夜间的使用需求。

屏幕支持 1-120Hz 自适应刷新率,在部分游戏中最高支持 165Hz 显示刷新率。手机内还有灵犀触控芯片,最高支持 3200Hz 瞬时触控采样和 330Hz多指触控率,对触控响应需求高的 FPS 游戏来说,还是很有必要的。

开镜更加迅速,关键时刻少点漏触漏发的情况了,就能有更好的游戏体验。

性能配置部分,同样旗舰定位的一加 15T 表现几乎和一加 15 一样。

一加 15T 搭载了第五代高通骁龙 8 至尊版移动平台,用了 LPDDR5X+UFS 4.1 的储存组合,常温状态下安兔兔的跑分成绩为:3755635。在储存芯片飞速涨价的这段时间,一加还是提供了最高 16GB+1TB 的储存版本。

此外,15T 配备了新一代风驰游戏内核,可适配游戏的 165 超高帧模式,配合刚刚提到的灵犀触控芯,可以实现响应速度更快的操作,操控节奏更加紧凑的 MOBA 和 FPS 游戏中更实用。

电池的升级比较大,一加 15T 的电池容量从上一代的 6260mAh 升级到 7500mAh,是目前同屏幕尺寸的手机中电池容量最大的一款。日常使用,15T 可以稳定坚持 2 天到 2.5 天,不需要担心续航问题,也不用长时间挂着充电宝。

充电部分,一加 15T 给到了 100W 超级闪充和 50W 无线闪充充电组合,配上磁吸配件,回到家中充电会更加随手方便。它也支持全局旁路供电,游戏时充电能够直接供电到系统,减低边用边充电池的影响。

通用快充的部分,我们用 AI 小电拼 Ultra 搭配细雳线进行实测,一加 15T 实际录得最高充电功率为 48W,0-100 充满耗时 71 分钟。

相机的部分,一加 15T 延续一加小屏系列的「主摄+长焦」模式:

  • 主摄:5000 万像素 1/1.56 英寸索尼 IMX906 CMOS,F1.8 光圈,支持光学防抖
  • 长焦:5000 万像素传感器,3.5x 光学变焦,F2.0 光圈,支持光学防抖

双 5000 万像素的组合对日常拍摄来说很不错,长焦镜头来到 3.5x 的焦段拍人像更舒服,高像素也方便用户做更大幅度的裁切,拍远一点的东西也方便。

但如果,如果一定要用双摄搭配,主摄保留着方便裁切的高像素传感器,然后长焦替换成同规格的超广角,那焦段的搭配上会更完整。

最后看看价格,一加 15T 合共提供了五个储存版本:

  • 12GB+256GB 4299 元
  • 12GB+512GB 4899 元
  • 16GB+256GB 4599 元
  • 16GB+512GB 5199 元
  • 16GB+1TB 5699 元
「买吧,不贵。」

#欢迎关注爱范儿官方微信公众号:爱范儿(微信号:ifanr),更多精彩内容第一时间为您奉上。

腾讯挖来多位字节Seed骨干,向姚顺雨汇报

2026年3月24日 20:58
36氪获悉,据接近腾讯混元团队的知情人士透露,原字节Seed视觉AI平台团队负责人肖学锋,Infra团队张弛于近期低调入职腾讯,负责大模型Infra相关工作,向腾讯首席AI科学家姚顺雨汇报。2025年年底,腾讯升级大模型研发架构,新成立AI Infra部,由姚顺雨担任部门负责人。据了解,肖学锋入职后,直接担任该部门的助理负责人,协助姚顺雨负责该部门管理工作。同时,该部门内的训练Infra组负责人黄启,也来自字节seed团队。

腾讯挖来多位字节Seed骨干,向姚顺雨汇报丨智能涌现独家

2026年3月24日 20:51

文|周鑫雨

编辑|苏建勋

自2025年9月姚顺雨加入腾讯以来,被视为腾讯重注基础模型的持续信号,事实上,在整个2025年,腾讯都在疯狂向业界招揽大模型基础设施领域人才,当中,出现了多位“字节系”技术骨干的身影。

据接近腾讯混元团队的知情人士透露,原字节Seed视觉AI平台团队负责人肖学锋,Infra团队张弛于近期低调入职腾讯,负责大模型Infra相关工作,向腾讯首席AI科学家姚顺雨汇报。

2025年年底,腾讯升级大模型研发架构,新成立AI Infra部,由姚顺雨担任部门负责人。据了解,肖学锋入职后,直接担任该部门的助理负责人,协助姚顺雨负责该部门管理工作。

同时,该部门内的训练Infra组负责人黄启,也来自字节seed团队。

肖学锋。

此外,与AI Infra部并列的腾讯大语言模型部,也有来自字节的核心开发人员。如新晋加盟的RL Infra组负责人Nick,实际是来自原字节Seed团队的张弛。

张弛曾就读于东南大学与南加州大学,2025 年底从Seed离职后加入腾讯,该组整合了原机器学习平台的RL Infra团队,目标是追上字节等头部公司的RL框架效率。目前张弛也直接汇报给姚顺雨。大语言模型部的RL算法组负责人,也是从字节Seed挖来的袁钰峰。

截至发稿前,腾讯官方暂未对上述信息做出回复。

2025年以来,随着姚顺雨、薄列锋(前阿里通义视觉负责人)等AI顶级人才的加盟,腾讯也加大了对AI人才的招募力度。《智能涌现》得知,2025年下半年,混元快速吸引了字节、阿里、月之暗面等企业的数位核心员工。

字节Seed团队的AI Infra能力,被业内公认为国内领先水平,其开源的veRL框架,是最主流的强化学习训练框架,而腾讯集中挖角Seed的Infra人才,核心目的是对自身AI Infra能力进行定向补强。

而腾讯从Seed团队集中引入AI Infra人才的指向性十分明确:补齐训练平台、推理系统、强化学习框架等核心底层能力,提升混元大模型的研发效率,以及模型能力对产品端的承接能力。

3月18日,腾讯高管在财报业绩沟通会上明确提及,2025年下半年以来,混元团队已全面启动组织架构与研发流程重组,除重点提升数据质量外,也已“重建了用于预训练和强化学习的基础设施”。

从2025年至今,腾讯AI业务经历了不少变化,人员也面临“新旧轮替”。《智能涌现》曾独家报道,2025年底,腾讯AI Lab副主任俞栋因个人原因提出离职,随后,其负责的AI Lab语音团队,全线并入了薄列峰领导的混元多模态部门。

更标志性的新旧交替时刻,发生在2026年3月20日。腾讯内部宣布,撤销AI Lab,原团队部分人员调整至大语言模型部,转向姚顺雨汇报;部分人员调整至腾讯技术工程事业群(TEG)下属的产学研合作中心。腾讯公司副总裁、原AI Lab主任蒋杰不再管理AI Lab,其他职责不变。

3月19日,在内部答疑会上,姚顺雨解释了调整的原因:打破部门墙,让AI基础模型的研发架构变得更年轻、更直接。

2025年以来持续的组织调整、人员变动,将腾讯在AI时代稳住巨头身位的野心,摆到了明面上。

不久前,腾讯公司总裁刘炽平在3月18日的财报电话会上提到,2025年腾讯在AI新产品上的投入是180亿元,2026年至少会翻倍。

无论是春节期间大模型应用“元宝”豪掷10亿元发红包,还是近期对“龙虾(当下最火的开源Agent框架)”近乎狂热的响应,腾讯的目的,都是建立用户的心智,把握AI时代的流量入口。

当然,让基础模型能力快速赶上第一梯队,依然是当下腾讯最重要的命题。《智能涌现》得知,2026年4月,腾讯即将发布的新一代混元模型,目标是在中等模型尺寸领域,追平Qwen、DeepSeek、豆包等第一梯队模型。

随着人才之争打响,巨头之间的AI较量将愈发白热化。

封面来源|AI生成

欢迎交流!

欢迎交流!

科泰电源:股东新疆荣旭泰拟减持不超1%公司股份

2026年3月24日 20:41
36氪获悉,科泰电源公告,持股5%以上股东新疆荣旭泰投资有限合伙企业计划在2026年4月16日至2026年7月15日期间,以集中竞价方式减持不超过320万股公司股份,占公司总股本比例不超过1%。减持原因为满足自身资金需求,股份来源为公司首次公开发行前已发行的股份。

泰嘉股份:股东中联重科拟合计减持不超3%股份

2026年3月24日 20:36
36氪获悉,泰嘉股份公告,持股5%以上股东中联重科计划自公告披露之日起15个交易日后的3个月内,以集中竞价交易方式减持不超过251.74万股(占总股本1%),以大宗交易方式减持不超过503.48万股(占总股本2%),合计拟减持不超过755.21万股(占总股本3%)。减持原因为股东自身经营决策,股份来源为首次公开发行前持有的股份及资本公积金转增股份,减持价格视市场价格确定。

纽交所宣布与数字资产公司Securitize合作开发24小时交易的代币化证券平台

2026年3月24日 20:35
据报道,纽约证券交易所宣布与数字资产公司Securitize合作开发24小时交易的代币化证券平台。根据计划,Securitize将成为NYSE的首个数字化股权登记机构(digital transfer agent),可在区块链上将股票和ETF份额发行成数字代币进行交易。此举是华尔街推动证券资产上链、实现全天候交易和更高效结算的重要一步。(财联社)

大千生态:股东速源科技拟减持不超3%公司股份

2026年3月24日 20:22
36氪获悉,大千生态公告,持股5%以上股东深圳市速源科技发展有限公司因经营发展需要,计划通过集中竞价和大宗交易方式合计减持不超过407.16万股(占公司总股本3%),其中集中竞价减持不超过135.72万股(1%)、大宗交易减持不超过271.44万股(2%)。减持期间为公告披露之日起15个交易日后的3个月内,即2026年4月16日至2026年7月15日。减持股份来源为协议转让取得。
❌
❌