移动开发:美团外卖Android Lint代码检查实践

概述

Lint是Google提供的Android静态代码检查工具,可以扫描并发现代码中潜在的问题,提醒开发人员及早修正,提高代码质量。除了Android原生提供的几百个Lint规则,还可以开发自定义Lint规则以满足实际需要。

为什么要使用Lint

在美团外卖Android App的迭代过程中,线上问题频繁发生。开发时很容易写出一些问题代码,例如Serializable的使用:实现了Serializable接口的类,如果其成员变量引用的对象没有实现Serializable接口,序列化时就会Crash。我们对一些常见问题的原因和解决方法做分析总结,并在开发人员组内或跟测试人员一起分享交流,帮助相关人员主动避免这些问题。

为了进一步减少问题发生,我们逐步完善了一些规范,包括制定代码规范,加强代码Review,完善测试流程等。但这些措施仍然存在各种不足,包括代码规范难以实施,沟通成本高,特别是开发人员变动频繁导致反复沟通等,因此其效果有限,相似问题仍然不时发生。另一方面,越来越多的总结、规范文档,对于组内新人也产生了不小的学习压力。

有没有办法从技术角度减少或减轻上述问题呢?

我们调研发现,静态代码检查是一个很好的思路。静态代码检查框架有很多种,例如FindBugs、PMD、Coverity,主要用于检查Java源文件或class文件;再例如Checkstyle,主要关注代码风格;但我们最终选择从Lint框架入手,因为它有诸多优势:

  1. 功能强大,Lint支持Java源文件、class文件、资源文件、Gradle等文件的检查。
  2. 扩展性强,支持开发自定义Lint规则。
  3. 配套工具完善,Android Studio、Android Gradle插件原生支持Lint工具。
  4. Lint专为Android设计,原生提供了几百个实用的Android相关检查规则。
  5. 有Google官方的支持,会和Android开发工具一起升级完善。

在对Lint进行了充分的技术调研后,我们根据实际遇到的问题,又做了一些更深入的思考,包括应该用Lint解决哪些问题,怎么样更好的推广实施等,逐步形成了一套较为全面有效的方案。

Lint API简介

为了方便后文的理解,我们先简单看一下Lint提供的主要API。

主要API

Lint规则通过调用Lint API实现,其中最主要的几个API如下。

  1. Issue:表示一个Lint规则。

  2. Detector:用于检测并报告代码中的Issue,每个Issue都要指定Detector。

  3. Scope:声明Detector要扫描的代码范围,例如JAVA_FILE_SCOPE、CLASS_FILE_SCOPE、RESOURCE_FILE_SCOPE、GRADLE_SCOPE等,一个Issue可包含一到多个Scope。

  4. Scanner:用于扫描并发现代码中的Issue,每个Detector可以实现一到多个Scanner。

  5. IssueRegistry:Lint规则加载的入口,提供要检查的Issue列表。

举例来说,原生的ShowToast就是一个Issue,该规则检查调用Toast.makeText()方法后是否漏掉了Toast.show()的调用。其Detector为ToastDetector,要检查的Scope为JAVA_FILE_SCOPE,ToastDetector实现了JavaPsiScanner,示意代码如下。

public class ToastDetector extends Detector implements JavaPsiScanner {
    public static final Issue ISSUE = Issue.create(
            "ShowToast",
            "Toast created but not shown",
            "...",
            Category.CORRECTNESS,
            6,
            Severity.WARNING,
            new Implementation(
                    ToastDetector.class,
                    Scope.JAVA_FILE_SCOPE));
    // ...
}

IssueRegistry的示意代码如下。

public class MyIssueRegistry extends IssueRegistry {

    @Override
    public List<Issue> getIssues() {
        return Arrays.asList(
                ToastDetector.ISSUE,
                LogDetector.ISSUE,
                // ...
        );
    }
}

Scanner

Lint开发过程中最主要的工作就是实现Scanner。Lint中包括多种类型的Scanner如下,其中最常用的是扫描Java源文件和XML文件的Scanner。

  • JavaScanner / JavaPsiScanner / UastScanner:扫描Java源文件
  • XmlScanner:扫描XML文件
  • ClassScanner:扫描class文件
  • BinaryResourceScanner:扫描二进制资源文件
  • ResourceFolderScanner:扫描资源文件夹
  • GradleScanner:扫描Gradle脚本
  • OtherFileScanner:扫描其他类型文件

值得注意的是,扫描Java源文件的Scanner先后经历了三个版本。

  1. 最开始使用的是JavaScanner,Lint通过Lombok库将Java源码解析成AST(抽象语法树),然后由JavaScanner扫描。

  2. 在Android Studio 2.2和lint-api 25.2.0版本中,Lint工具将Lombok AST替换为PSI,同时弃用JavaScanner,推荐使用JavaPsiScanner。

    PSI是JetBrains在IDEA中解析Java源码生成语法树后提供的API。相比之前的Lombok AST,PSI可以支持Java 1.8、类型解析等。使用JavaPsiScanner实现的自定义Lint规则,可以被加载到Android Studio 2.2+版本中,在编写Android代码时实时执行。

  3. 在Android Studio 3.0和lint-api 25.4.0版本中,Lint工具将PSI替换为UAST,同时推荐使用新的UastScanner。

    UAST是JetBrains在IDEA新版本中用于替换PSI的API。UAST更加语言无关,除了支持Java,还可以支持Kotlin。

本文目前仍然基于PsiJavaScanner做介绍。根据UastScanner源码中的注释,可以很容易的从PsiJavaScanner迁移到UastScanner。

Lint规则

我们需要用Lint检查代码中的哪些问题呢?

开发过程中,我们比较关注App的Crash、Bug率等指标。通过长期的整理总结发现,有不少发生频率很高的代码问题,其原理和解决方案都很明确,但是在写代码时却很容易遗漏且难以发现;而Lint恰好很容易检查出这些问题。

Crash预防

Crash率是App最重要的指标之一,避免Crash也一直是开发过程中比较头疼的一个问题,Lint可以很好的检查出一些潜在的Crash。例如:

  • 原生的NewApi,用于检查代码中是否调用了Android高版本才提供的API。在低版本设备中调用高版本API会导致Crash。

  • 自定义的SerializableCheck。实现了Serializable接口的类,如果其成员变量引用的对象没有实现Serializable接口,序列化时就会Crash。我们制定了一条代码规范,要求实现了Serializable接口的类,其成员变量(包括从父类继承的)所声明的类型都要实现Serializable接口。

  • 自定义的ParseColorCheck。调用Color.parseColor()方法解析后台下发的颜色时,颜色字符串格式不正确会导致IllegalArgumentException,我们要求调用这个方法时必须处理该异常。

Bug预防

有些Bug可以通过Lint检查来预防。例如:

  • SpUsage:要求所有SharedPrefrence读写操作使用基础工具类,工具类中会做各种异常处理;同时定义SPConstants常量类,所有SP的Key都要在这个类定义,避免在代码中分散定义的Key之间冲突。

  • ImageViewUsage:检查ImageView有没有设置ScaleType,加载时有没有设置Placeholder。

  • TodoCheck:检查代码中是否还有TODO没完成。例如开发时可能会在代码中写一些假数据,但最终上线时要确保删除这些代码。这种检查项比较特殊,通常在开发完成后提测阶段才检查。

性能/安全问题

一些性能、安全相关问题可以使用Lint分析。例如:

  • ThreadConstruction:禁止直接使用new Thread()创建线程(线程池除外),而需要使用统一的工具类在公用线程池执行后台操作。

  • LogUsage:禁止直接使用android.util.Log,必须使用统一工具类。工具类中可以控制Release包不输出Log,提高性能,也避免发生安全问题。

代码规范

除了代码风格方面的约束,代码规范更多的是用于减少或防止发生Bug、Crash、性能、安全等问题。很多问题在技术上难以直接检查,我们通过封装统一的基础库、制定代码规范的方式间接解决,而Lint检查则用于减少组内沟通成本、新人学习成本,并确保代码规范的落实。例如:

  • 前面提到的SpUsage、ThreadConstruction、LogUsage等。

  • ResourceNaming:资源文件命名规范,防止不同模块之间的资源文件名冲突。

代码检查的实施

当检查出代码问题时,如何提醒开发者及时修正呢?

早期我们将静态代码检查配置在Jenkins上,打包发布AAR/APK时,检查代码中的问题并生成报告。后来发现虽然静态代码检查能找出来不少问题,但是很少有人主动去看报告,特别是报告中还有过多无关紧要的、优先级很低的问题(例如过于严格的代码风格约束)。

因此,一方面要确定检查哪些问题,另一方面,何时、通过什么样的技术手段来执行代码检查也很重要。我们结合技术实现,对此做了更多思考,确定了静态代码检查实施过程中的主要目标:

  1. 重点关注高优先级问题,屏蔽低优先级问题。正如前面所说,如果代码检查报告中夹杂了大量无关紧要的问题,反而影响了关键问题的发现。

  2. 高优问题的解决,要有一定的强制性。当检查发现高优先级的代码问题时,给开发者明确直接的报错,并通过技术手段约束,强制要求开发者修复。

  3. 某些问题尽可能做到在第一时间发现,从而减少风险或损失。有些问题发现的越早越好,例如业务功能开发中使用了Android高版本API,通过Lint原生的NewApi可以检查出来。如果在开发期间发现,当时就可以考虑其他技术方案,实现困难时可以及时和产品、设计人员沟通;而如果到提代码、提测,甚至发版、上线时才发现,可能为时已晚。

优先级定义

每个Lint规则都可以配置Sevirity(优先级),包括Fatal、Error、Warning、Information等,我们主要使用Error和Warning,如下。

  • Error级别:明确需要解决的问题,包括Crash、明确的Bug、严重性能问题、不符合代码规范等,必须修复。
  • Warning级别:包括代码编写建议、可能存在的Bug、一些性能优化等,适当放松要求。

执行时机

Lint检查可以在多个阶段执行,包括在本地手动检查、编码实时检查、编译时检查、commit检查,以及在CI系统中提Pull Request时检查、打包发版时检查等,下面分别介绍。

手动执行

在Android Studio中,自定义Lint可以通过Inspections功能(Analyze - Inspect Code)手动运行。

在Gradle命令行环境下,可直接用./gradlew lint执行Lint检查。

手动执行简单易用,但缺乏强制性,容易被开发者遗漏。

编码阶段实时检查

编码时检查即在Android Studio中写代码时在代码窗口实时报错。其好处很明显,开发者可以第一时间发现代码问题。但受限于Android Studio对自定义Lint的支持不完善,开发人员IDE的配置不同,需要开发者主动关注报错并修复,这种方式不能完全保证效果。

IDEA提供了Inspections功能和相应的API来实现代码检查,Android原生Lint就是通过Inspections集成到了Android Studio中。对于自定义Lint规则,官方似乎没有给出明确说明,但实际研究发现,在Android Studio 2.2+版本和基于JavaPsiScanner开发的条件下(或Android Studio 3.0+和JavaPsiScanner/UastScanner),IDE会尝试加载并实时执行自定义Lint规则。

技术细节:

  1. 在Android Studio 2.x版本中,菜单Preferences - Editor - Inspections - Android - Lint - Correctness - Error from Custom Lint Check(avaliable for Analyze|Inspect Code)中指出,自定义Lint只支持命令行或手动运行,不支持实时检查。

    Error from Custom Rule When custom (third-party) lint rules are integrated in the IDE, they are not available as native IDE inspections, so the explanation text (which must be statically registered by a plugin) is not available. As a workaround, run the lint target in Gradle instead; the HTML report will include full explanations.

  2. 在Android Studio 3.x版本中,打开Android工程源码后,IDE会加载工程中的自定义Lint规则,在设置菜单的Inspections列表里可以查看,和原生Lint效果相同(Android Studio会在打开源文件时触发对该文件的代码检查)。

  3. 分析自定义Lint的IssueRegistry.getIssues()方法调用堆栈,可以看到Android Studio环境下,是由org.jetbrains.android.inspections.lint.AndroidLintExternalAnnotator调用LintDriver加载执行自定义Lint规则。

    参考代码: https://github.com/JetBrains/android/tree/master/android/src/org/jetbrains/android/inspections/lint

在Android Studio中的实际效果如图:
这里写图片描述

本地编译时自动检查

配置Gradle脚本可实现编译Android工程时执行Lint检查。好处是既可以尽早发现问题,又可以有强制性;缺点是对编译速度有一定的影响。

编译Android工程执行的是assemble任务,让assemble依赖lint任务,即可在编译时执行Lint检查;同时配置LintOptions,发现Error级别问题时中断编译。

在Android Application工程(APK)中配置如下,Android Library工程(AAR)把applicationVariants换成libraryVariants即可。

android.applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def lintTask = tasks["lint${variant.name.capitalize()}"]
        output.assemble.dependsOn lintTask
    }
}

LintOptions的配置:

android.lintOptions {
    abortOnError true
}
本地commit时检查

利用git pre-commit hook,可以在本地commit代码前执行Lint检查,检查不通过则无法提交代码。这种方式的优势在于不影响开发时的编译速度,但发现问题相对滞后。

技术实现方面,可以编写Gradle脚本,在每次同步工程时自动将hook脚本从工程拷贝到.git/hooks/文件夹下。

提代码时CI检查

作为代码提交流程规范的一部分,发Pull Request提代码时用CI系统检查Lint问题是一个常见、可行、有效的思路。可配置CI检查通过后代码才能被合并。

CI系统常用Jenkins,如果使用Stash做代码管理,可以在Stash上配置Pull Request Notifier for Stash插件,或在Jenkins上配置Stash Pull Request Builder插件,实现发Pull Request时触发Jenkins执行Lint检查的Job。

在本地编译和CI系统中做代码检查,都可以通过执行Gradle的Lint任务实现。可以在CI环境下给Gradle传递一个StartParameter,Gradle脚本中如果读取到这个参数,则配置LintOptions检查所有Lint问题;否则在本地编译环境下只检查部分高优先级Lint问题,减少对本地编译速度的影响。

Lint生成报告的效果如图所示:

这里写图片描述

这里写图片描述

打包发布时检查

即使每次提代码时用CI系统执行Lint检查,仍然不能保证所有人的代码合并后一定没有问题;另外对于一些特殊的Lint规则,例如前面提到的TodoCheck,还希望在更晚的时候检查。

于是在CI系统打包发布APK/AAR用于测试或发版时,还需要对所有代码再做一次Lint检查。

最终确定的检查时机

综合考虑多种检查方式的优缺点以及我们的目标,最终确定结合以下几种方式做代码检查:

  1. 编码阶段IDE实时检查,第一时间发现问题。
  2. 本地编译时,及时检查高优先级问题,检查通过才能编译。
  3. 提代码时,CI检查所有问题,检查通过才能合代码。
  4. 打包阶段,完整检查工程,确保万无一失。

配置文件支持

为了方便代码管理,我们给自定义Lint创建了一个独立的工程,该工程打包生成一个AAR发布到Maven仓库,而被检查的Android工程依赖这个AAR(具体开发过程可以参考文章末尾链接)。

自定义Lint虽然在独立工程中,但和被检查的Android工程中的代码规范、基础组件等存在较多耦合。

例如我们使用正则表达式检查Android工程的资源文件命名规范,每次业务逻辑变动要新增资源文件前缀时,都要修改Lint工程,发布新的AAR,再更新到Android工程中,非常繁琐。另一方面,我们的Lint工程除了在外卖C端Android工程中使用,也希望能直接用在其他端的其他Android工程中,而不同工程之间存在差异。

于是我们尝试使用配置文件来解决这一问题。以检查Log使用的LogUsage为例,不同工程封装了不同的Log工具类,报错时提示信息也应该不一样。定义配置文件名为custom-lint-config.json,放在被检查Android工程的模块目录下。在Android工程A中的配置文件是:

{
    "log-usage-message": "请勿使用android.util.Log,建议使用LogUtils工具类"
}

而Android工程B的配置文件是:

{
    "log-usage-message": "请勿使用android.util.Log,建议使用Logger工具类"
}

从Lint的Context对象可获取被检查工程目录从而读取配置文件,关键代码如下:

import com.android.tools.lint.detector.api.Context;

public final class LintConfig {

    private LintConfig(Context context) {
        File projectDir = context.getProject().getDir();
        File configFile = new File(projectDir, "custom-lint-config.json");
        if (configFile.exists() && configFile.isFile()) {
            // 读取配置文件...
        }
    }
}

配置文件的读取,可以在Detector的beforeCheckProject、beforeCheckLibraryProject回调方法中进行。LogUsage中检查到错误时,根据配置文件定义的信息报错。

public class LogUsageDetector extends Detector implements Detector.JavaPsiScanner {
    // ...

    private LintConfig mLintConfig;

    @Override
    public void beforeCheckProject(@NonNull Context context) {
        // 读取配置
        mLintConfig = new LintConfig(context);
    }

    @Override
    public void beforeCheckLibraryProject(@NonNull Context context) {
        // 读取配置
        mLintConfig = new LintConfig(context);
    }

    @Override
    public List<String> getApplicableMethodNames() {
        return Arrays.asList("v", "d", "i", "w", "e", "wtf");
    }

    @Override
    public void visitMethod(JavaContext context, JavaElementVisitor visitor, PsiMethodCallExpression call, PsiMethod method) {
        if (context.getEvaluator().isMemberInClass(method, "android.util.Log")) {
            // 从配置文件获取Message
            String msg = mLintConfig.getConfig("log-usage-message");
            context.report(ISSUE, call, context.getLocation(call.getMethodExpression()), msg);
        }
    }
}

模板Lint规则

Lint规则开发过程中,我们发现了一系列相似的需求:封装了基础工具类,希望大家都用起来;某个方法很容易抛出RuntimeException,有必要做处理,但Java语法上RuntimeException并不强制要求处理从而经常遗漏……

这些相似的需求,每次在Lint工程中开发同样会很繁琐。我们尝试实现了几个模板,可以直接在Android工程中通过配置文件配置Lint规则。

如下为一个配置文件示例:

{
  "lint-rules": {
    "deprecated-api": [{
      "method-regex": "android\\.content\\.Intent\\.get(IntExtra|StringExtra|BooleanExtra|LongExtra|LongArrayExtra|StringArrayListExtra|SerializableExtra|ParcelableArrayListExtra).*",
      "message": "避免直接调用Intent.getXx()方法,特殊机型可能发生Crash,建议使用IntentUtils",
      "severity": "error"
    },
    {
      "field": "java.lang.System.out",
      "message": "请勿直接使用System.out,应该使用LogUtils",
      "severity": "error"
    },
    {
      "construction": "java.lang.Thread",
      "message": "避免单独创建Thread执行后台任务,存在性能问题,建议使用AsyncTask",
      "severity": "warning"
    },
    {
      "super-class": "android.widget.BaseAdapter",
      "message": "避免直接使用BaseAdapter,应该使用统一封装的BaseListAdapter",
      "severity": "warning"
    }],
    "handle-exception": [{
      "method": "android.graphics.Color.parseColor",
      "exception": "java.lang.IllegalArgumentException",
      "message": "Color.parseColor需要加try-catch处理IllegalArgumentException异常",
      "severity": "error"
    }]
  }
}

示例配置中定义了两种类型的模板规则:

  • DeprecatedApi:禁止直接调用指定API
  • HandleException:调用指定API时,需要加try-catch处理指定类型的异常

问题API的匹配,包括方法调用(method)、成员变量引用(field)、构造函数(construction)、继承(super-class)等类型;匹配字符串支持glob语法或正则表达式(和lint.xml中ignore的配置语法一致)。

实现方面,主要是遍历Java语法树中特定类型的节点并转换成完整字符串(例如方法调用android.content.Intent.getIntExtra),然后检查是否有模板规则与其匹配。匹配成功后,DeprecatedApi规则直接输出message报错;HandleException规则会检查匹配到的节点是否处理了特定Exception(或Exception的父类),没有处理则报错。

按Git版本检查新增文件

随着Lint新规则的不断开发,我们又遇到了一个问题。Android工程中存在大量历史代码,不符合新增Lint规则的要求,但也没有导致明显问题,这时接入新增Lint规则要求修改所有历史代码,成本较高而且有一定风险。例如新增代码规范,要求使用统一的线程工具类而不允许直接用Handler以避免内存泄露等。

我们尝试了一个折中的方案:只检查指定git commit之后新增的文件。在配置文件中添加配置项,给Lint规则配置git-base属性,其值为commit ID,只检查此次commit之后新增的文件。

实现方面,执行git rev-parse --show-toplevel命令获取git工程根目录的路径;执行git ls-tree --full-tree --full-name --name-only -r <commit-id>命令获取指定commit时已有文件列表(相对git根目录的路径)。在Scanner回调方法中通过Context.getLocation(node).getFile()获取节点所在文件,结合git文件列表判断是否需要检查这个节点。需要注意的是,代码量较大时要考虑Lint检查对电脑的性能消耗。
这里写图片描述

总结

经过一段时间的实践发现,Lint静态代码检查在解决特定问题时的效果非常好,例如发现一些语言或API层面比较明确的低级错误、帮助进行代码规范的约束。使用Lint前,不少这类问题恰好对开发人员来说又很容易遗漏(例如原生的NewApi检查、自定义的SerializableCheck);相同问题反复出现;代码规范的执行,特别是有新人参与开发时,需要很高的学习和沟通成本,还经常出现新人提交代码时由于没有遵守代码规范反复被要求修改。而使用Lint后,这些问题都能在第一时间得到解决,节省了大量的人力,提高了代码质量和开发效率,也提高了App的使用体验。

参考资料与扩展阅读

参考资料:

Lint和Gradle相关技术细节还可以阅读我的个人博客:

作者简介

子健,Android高级工程师,2015年毕业于西安电子科技大学并校招加入美团外卖。前期先后负责过外卖App首页、商家容器、评价等核心业务模块的开发维护,目前重点负责参与外卖打包自动化、代码检查、平台化等技术工作。

招聘

美团外卖App团队诚招Android/iOS高级工程师/技术专家,工作地北京/上海可选,欢迎有兴趣的同学投递简历到wukai05#meituan.com。

这里写图片描述

相关推荐

美团正式发布 LongCat-2.5:面向智能体任务的原生多模态模型

美团正式发布 LongCat-2.5,这是一个面向长程智能体任务的原生多模态模型。模型总参数量为 1.6 万亿,每个 token 激活约 480 亿参数,在 LongCat-2.0 的基础上进一步强化了原生视觉理解与智能体编程能力。

美团技术团队 2375

如何在“不能出错”的系统里使用 AI Coding?分布式存储实践与边界

AI 能让代码写得更快,但在「不能出错」的分布式存储系统里,如何确保提效不变成风险?本文结合美团基础技术部在 AI 评审、问题排查和自动化开发中的真实实践,分享 AI 能帮上什么忙、容易在哪些地方犯错,以及哪些地方仍需要人来把关。比「多写代码」更重要的,是让代码和结论经得起验证。希望这些经验能为复杂系统中的 AI 应用提供参考,在享受效率提升的同时,守住质量与稳定性的底线。

美团技术团队 317

从 LOOP 到图探索 —— 算法模型的 AutoResearch 自进化系统架构演进之路

算法工程师的一天是“改代码—提交训练—等待—看日志—决定下一步”,过程中还经常被打断。我们团队从 Karpathy 的 AutoResearch 出发,经过三次架构重构,搭建出一套可在企业云端训练平台使用的算法研究自进化系统。本文分享这套系统的设计理念、架构演进与可信度设计,希望对大家有所帮助或启发。

美团技术团队 448

SLM 生成式高并发推理引擎:延迟约束下的有效吞吐优化

本文为SLM(Small Language Model, 小参数量语言模型0.5~1B)在搜推场景的大规模落地提供了一套高性能、可复用的工程实践。

美团技术团队 549

MTFM:美团统一推荐基座大模型在外卖多业务场景的落地实践

美团在 MTGR 基础上提出统一推荐基座大模型 MTFM,首次实现外卖多个主要业务的统一精排模型。围绕规模可扩展性、场景可延展性与架构高效性三大挑战,MTFM以异构 Tokenizer 与动态掩码实现多场景特征免对齐,通过混合注意力与 Target Scale-Up 提升模型 Scaling 能力,借鉴 LLM 优化实践提升深层网络训练效果,并以 User-Level 训练范式与定制算子保证系统开销可控。美团外卖多个业务订单量提升 2.06%~6.68% 不等,推理成本降低 24%。

美团技术团队 681

《Agent 评测白皮书》系列01:Agent 评测全览

我们推出了《Agent评测白皮书》系列博客,体系化地为大家讲解评测的落地指南,分为《评测全览》、《冷启动篇》、《扩量篇》、《自进化篇》等共4篇,本文为系列的第一篇。

美团技术团队 659

美团智播——数字人直播技术创新与实践

美团智播,是面向本地生活场景的AI数字人直播解决方案,融合大模型、数字人与多模态交互技术,提供丰富的行业专属数字人形象,支持真人1:1复刻与门店实景定制,30秒生成直播素材,3分钟完成开播配置,7×24小时稳定上播。过去一年,依托生成式AI技术,数字人直播月日均GTV同比增长82.12%,月日均观看人次同比增长163.44%,开播场次提升11倍,充分验证了AI数字人直播在本地生活商业闭环中的实际价值。

美团技术团队 902

GeoRA: 为RLVR设计的LoRA——ACL 2026杰出论文解析

本文介绍了一种专为 RLVR 设计的低秩训练方法,以及它在业务 Agentic RL 中的落地经验。

美团技术团队 671

美团搜索3.0:LLM 语义表征在排序模型的探索与应用

美团搜索团队正依托团垂融合新架构与生成式大模型新技术,全面重构本地生活搜索底座。本系列技术博客将持续介绍美团搜索 3.0 的技术探索,本文聚焦 LLM 语义表征在服务零售排序场景上的三期实践——从单点特征验证到系统性表征体系构建,再到跨场景迁移复用,探索语义匹配信号在搜索排序中的应用路径。

美团技术团队 907

KDD‘26 美团学术论文精选及KDD Cup‘26 DataAgents赛道冠军思路解读

本文精选了美团技术团队被 KDD 2026 收录的 8 篇论文进行分享,这些论文覆盖了推荐大模型、生成与奖励建模框架、智能体搜索、Transformer 框架、元泛化框架等技术领域。

美团技术团队 954

Agent评测漫谈 —— 由浅入深讲解Agent评测

本篇博客是一篇科普文章,由浅入深的介绍Agent评测。其中前两章系统介绍了评测是什么,以及如何建立评测体系;其中第二章是美团图灵Agent评测团队深入美团各业务团队BP总结出的实践经验,是我们在两年实践过程中逐步打磨出来的认知。第三章重点介绍了龙虾/爱马仕这类长程Agent框架的出现对评测带来的变化。

美团技术团队 1066

美团正式发布 CatPaw:全场景 AI Agent,从个人提效到企业智能化

搭载 LongCat 2.0 的美团全场景 AI Agent 平台 CatPaw 正式上线,将模型能力从“跑得动”推向“用得好”。CatPaw 提供开箱即用的 AI 智能工作台与企业级 Agent 开发托管能力。

美团技术团队 1015

让AI离开温室,走向动态世界:MineExplorer揭示顶级多模态大模型被忽视的能力断层

美团 LongCat 团队构建了MineExplorer——首个在开放世界中做到分钟级长程任务的评测基准,系统性地评测多模态大模型在需要长程规划、并包含隐藏前置条件的任务中的真实能力。

美团技术团队 862

下一代搜索智能体评测基准!美团开源LoHoSearch,用知识图谱校准AI能力认知

过去一年,我们见证了 Search Agent 能力的显著演进。在 BrowseComp 等评测上,顶尖模型准确率从最初的30%区间迅速攀升至90%以上。然而,当基准迅速饱和,其区分模型能力的价值也随之递减。

美团技术团队 910

直播回放·含 ACL‘26 杰出论文 | 美团 AI 顶会论文 32 篇精讲

2026 年,美团技术团队数十篇论文被 ACL、SIGIR、ICML、KDD 等顶会收录。我们精选 32 篇,进行了 5 大专场直播。

美团技术团队 898

正式开源!美团 LongCat-2.0 同步开放国产卡推理代码

美团 LongCat-2.0 总参数 1.6T,平均激活约 48B,为真实的 Agentic Coding 任务而生,架构上创新性引入 LongCat 稀疏注意力和 N-gram Embedding,提升长上下文处理效率与 Token 级表示能力的同时,结合动态激活进一步强化了代码理解、生成以及执行的表现。

美团技术团队 864

美团 LongCat-2.0 正式发布:在国产算力集群上完成全流程训练与推理的万亿参数模型

6月30日,美团正式发布新一代万亿参数大模型 LongCat-2.0,并将对外开源。

美团技术团队 1211

LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆

VitaBench 2.0 是首个真实生活场景下面向长期动态用户建模的智能体评测基准,它系统性地评测大语言模型在长期、真实、动态的用户互动中个性化与主动性的能力

美团技术团队 1115

ICML 2026 | 美团技术团队学术论文精选

ICML(International Conference on Machine Learning,国际机器学习大会)是机器学习领域最具影响力的国际顶级学术会议之一。

美团技术团队 849

美团海报生成 AIGC 技术创新与实践

美团智能创作团队围绕海报生成 AIGC 构建了完整技术体系,打造「生成-编辑-评判」技术闭环,目前已在美团外卖、品牌 IP 等场景落地,已全部开源。

美团技术团队 2060

从月球漫步到赛博都市,WBench 测出了世界模型的边界

美团 LongCat 团队提出了 WBench,它是首个面向交互式视频世界模型的系统性多轮评测基准。它就像一台“CT扫描仪”,能精准定位当前世界模型在从“被动观看”到“主动交互”的过程中,到底卡在了哪里。

美团技术团队 1241

报名|ACL‘26 美团中稿精选:从能力评测到推理优化,构建生成新范式

本文分享了美团技术团队被 ACL 顶会收录的其中 6 篇论文,技术方向覆盖大模型评测、复杂流程推理、竞赛级数学思维优化、强化学习优化、生成式推荐等领域。

美团技术团队 1515

从高拟真到真可用,LongCat-Video-Avatar 1.5 正式开源

LongCat-Video-Avatar 1.5 即便在复杂商业场景里,也能稳定、自然地输出高质量内容,让数字人视频生成从彩排室的完美演练,走向千人千面的真实舞台。

美团技术团队 1587

美团跑腿 Skill:一句话,骑手来帮忙

美团跑腿 Skill 支持所有 Claw 客户端,包括 OpenClaw 本地版、火山引擎等云部署版、QClaw 等第三方客户端。

美团技术团队 1854

美团 LongCat 开源 General 365:树立推理评测新标尺

General 365 将推理评测从专业知识依赖中剥离出来,让我们直观地看到了大模型在真实世界的通用推理任务上的短板。

美团技术团队 2079

用Agent评测思路管理AI Coding —— 31万行代码AI重构的实践

当团队 90% 以上的代码由 AI 生成,31 万行的复杂业务系统还在高速膨胀,你会发现一个反直觉的事实:AI Coding 不会自动收敛复杂度 —— 没有统一规范的约束,不同人用 AI 写出的代码风格各异,系统反而会加速腐化。本文记录了我们如何在不停止业务交付的前提下,完成这场重构。

美团技术团队 2426

LARYBench 发布:定义具身动作表征 ImageNet,首次度量从人类视频学习的泛化表征

LARYBench (Latent Action Representation Yielding Benchmark),一个指引从大规模的视觉数据学习到通用的隐式动作表征的系统化评测基准。实验结果表明:在动作泛化和控制精度上,通用视觉模型的表现均显著优于专门为具身智能设计的动作专家模型,具身动作表征可以从大规模人类视频数据中涌现。

美团技术团队 2201

突破零样本TTS音色克隆上限:LongCat-AudioDiT 的声音克隆艺术

能不能让 AI 直接学会声音本身的规律,跳过中间环节?为破解这一技术瓶颈,美团 LongCat 团队正式发布 LongCat-AudioDiT。在该模型中,我们彻底抛弃梅尔谱等中间表示,直接在波形潜空间进行基于扩散模型的文本转语音(Text-to-Speech, TTS),从根源阻断数据转换的级联误差。

美团技术团队 1599

LongCat-Flash-Prover:AI 攻克数学定理证明,不仅要“算得对”,更要“证得严”

如何让 AI 从“猜答案”走向“严谨证明”,成为复杂推理具有挑战的课题。我们开源了专门用于数学形式化与定理证明的模型 —— LongCat-Flash-Prover。

美团技术团队 1799

美团发布原生多模态 LongCat-Next:当视觉和语音成为AI的母语

LongCat-Next 是我们在通往物理世界 AI 道路上的一次探索。我们把研究思路的核心——LongCat-Next 模型和它的离散分词器全部开源,希望更多开发者能基于它,构建真正能感知、理解并作用于真实世界的AI。

美团技术团队 2130
上一篇: 工程师如何在工作中提升自己?
下一篇: 工作中如何做好技术积累
美团技术团队
美团技术团队 企业官方账号 企业官方账号
博客等级 码龄10年 3万+粉丝 753原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值