首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Android AI 开发中的 Rules 与 Specificity:有论文支撑的工程实践

Android AI 开发中的 Rules 与 Specificity:有论文支撑的工程实践

作者头像
陆业聪
发布2026-04-02 12:45:42
发布2026-04-02 12:45:42
1540
举报

📰 科技要闻

• daVinci-Env(arXiv 2603.13023):最大规模 SWE Agent 训练框架,45,320 个可执行 Docker 环境,发现 Agent 在专业化仓库任务中性能显著优于通用任务

• QUARE(arXiv 2603.11890):多 Agent 协作需求工程研究,证明「单一 LLM 难以同时平衡多个质量属性」,专职化 Agent 分工效果更优

• Princeton 研究:Hierarchical verification + iterative agent-assisted repair 模式,在软件工程 Agent 任务中比 flat prompt 成功率高出 40%+

我之前那篇《用 AI 写 Android 需求》里提到了 Skills 和 Rules 的概念,有读者问:「这些东西背后有没有更扎实的理论依据,还是纯粹实践总结?」

这篇就认真回答这个问题——聊清楚 Rules(规则约束)Specificity(专职化) 在 Android AI 开发中的工程实践,并把近期相关论文的结论对应上来。

一、从研究结论出发:为什么通用 Prompt 不够用

先说学术界的共识。

arXiv 今年(2026)发布的 daVinci-Env 研究(论文编号 2603.13023)训练了迄今最大规模的 SWE(软件工程)Agent,在 45,320 个真实 Python 仓库上做评测。他们发现了一个关键现象:Agent 在「领域特征鲜明」的仓库上的表现,显著优于领域特征模糊的通用仓库——不是因为模型变聪明了,而是因为任务约束更清晰时,Agent 的搜索空间大幅缩小,犯错的机会也随之减少。

另一篇 QUARE(2603.11890)则在需求工程领域证明了另一个结论:当多个质量属性(性能、安全、可维护性)同时出现在一个 Agent 的任务目标里时,LLM 的优化会发生「属性冲突」——它很难同时把所有维度都做好。分配给专职 Agent 处理单一质量属性,最终产出的综合质量反而更高。

这两个结论合在一起,给了工程实践一个很清晰的方向:

• 缩小任务边界(Specificity)

• 显式约束行为(Rules / Guardrails)

翻译成 Android 开发者能用的语言就是:不要用一个什么都懂的通用 AI 助手写你的项目代码,而是为不同的开发场景配置专门的约束规则集

二、Rules 在工程里的三个层次

「Rules」这个词在 AI 工程实践里对应的是 System Prompt Constraints(系统提示约束)和 Guardrails(护栏)。业界主流工具(Claude、GPT-4、Gemini)都支持通过 System Prompt 植入约束规则,控制模型在特定任务里的行为边界。

在 Android 开发里,这些规则可以分三个层次来设计:

层次一:平台约束规则(Platform Constraints)

Android 平台本身的强制约束,违反即 Crash。LLM 不是不知道这些规则,而是在上下文较长或任务较复杂时「遗忘」概率会上升——这是 Transformer 架构的 attention 衰减特性决定的,跟模型能力没有直接关系。

把这类规则显式写入 System Prompt,相当于在每次推理时强制「唤醒」这部分知识。典型规则:

代码语言:javascript
复制
// [Platform Constraint] 线程规则
// 网络/文件 IO → Dispatchers.IO
// UI 更新 → Dispatchers.Main 或 lifecycleScope
// 禁止在主线程调用任何阻塞 API
suspend fun loadData() = withContext(Dispatchers.IO) {
repo.fetch()
}// [Platform Constraint] 生命周期规则
// 所有异步回调执行前必须检查组件存活状态
fun onCallback(result: Result) {
if (isFinishing() || isDestroyed()) return
updateUI(result)
}

层次二:项目约定规则(Project Conventions)

这类规则是团队历史决策的结晶,LLM 无从得知,必须显式告知。这对应论文里的 Domain-specific Context Injection(领域特定上下文注入)概念——研究表明,相比长篇自然语言描述,以「约束示例 + 反例 + 原因」三段式注入的规则,LLM 遵从率比纯自然语言描述高约 30%(来自 Microsoft Research 的 Prompt Engineering 研究)。

代码语言:javascript
复制
// [Project Convention] 日志规则
// ✅ 正确:项目统一日志工具,支持线上脱敏
WwLog.i(TAG, "user loaded: $userId")
// ❌ 禁止:标准 Log 输出不受脱敏控制
Log.d("TAG", "user loaded: $userId")// [Project Convention] 组件规则
// ✅ 正确:继承统一 Dialog 基类
class ConfirmDialog : BaseWwDialog()
// ❌ 禁止:直接 new AlertDialog(绕过主题和埋点)
AlertDialog.Builder(context).create()

层次三:误报豁免规则(False-Positive Exemptions)

这是最容易被忽视的一层,但对落地效果至关重要。LLM 在 Code Review 场景里的误报,很大程度来自于它用「通用最佳实践」去判断「项目特有约定」。

daVinci-Env 论文里有个细节值得关注:他们的多 Agent 修复管道(iterative agent-assisted repair)发现,没有 false-positive 过滤机制的 Agent 会在「已经正确的代码」上反复修改,产生退化。豁免规则正是这个过滤机制的工程实现。

豁免规则示例:

• 我们的 XxxService 回调由框架层保证在主线程执行,不要报「缺少 runOnUiThread」

WwSingletonHolder 内部已做双重检查锁,不要报「单例懒初始化线程不安全」

notifyDataSetChanged() 在首次加载时可接受,只在增量更新时要求 DiffUtil

三、Specificity(专职化):为什么一个 Agent 只做一件事

「Specificity」这个词在 AI 工程领域对应的是 Task Decomposition(任务拆解)和 Role Specialization(角色专职化)。Anthropic 在其 Agent 最佳实践文档里明确指出:「将大任务分解为多个专职子 Agent,每个子 Agent 专注于一个定义清晰的子任务,比单个全能 Agent 更可靠」

从工程角度理解,专职化的好处有三个:

1. 上下文窗口利用率更高:128K token 的窗口,塞进一个通用 Agent 的所有规则,不如只塞「这个场景需要的规则」,相关规则的权重更高,遵从率更好

2. 验证更容易:专职 Agent 的输出范围可预期,可以用自动化测试验证(daVinci-Env 论文核心做法之一)

3. 迭代成本低:某个场景的规则更新,只改那个 Agent,不影响其他场景

Android 开发里,以下几个场景天然适合专职化:

场景 A:RecyclerView 组件开发(Adapter Specialist)

RecyclerView Adapter 有固定的「正确模式」和「高频错误模式」,非常适合规则化。核心规则只需要三条,但每条必须有代码示范:

代码语言:javascript
复制
// Rule A-1: onBindViewHolder 必须重置所有状态
// 包含「有值」和「无值」两种分支,防止复用残留
override fun onBindViewHolder(
holder: ViewHolder, pos: Int
) {
val item = items[pos]
if (item.hasAvatar) {
holder.ivAvatar.setImageUrl(item.avatar)
} else {
holder.ivAvatar.setImageResource(  // ✅ 显式重置
R.drawable.ic_default_avatar
)
}
}// Rule A-2: 数据更新用 DiffUtil,禁止 notifyDataSetChanged
fun submitList(newList: List<Item>) {
val diff = DiffUtil.calculateDiff(
ItemDiffCallback(items, newList)
)
items = newList
diff.dispatchUpdatesTo(this)
}// Rule A-3: 点击事件在 onCreateViewHolder 设置
// 而非 onBindViewHolder(避免重复创建 Lambda)
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int
): ViewHolder {
val holder = ViewHolder(
inflater.inflate(R.layout.item, parent, false)
)
holder.itemView.setOnClickListener {
val pos = holder.adapterPosition
if (pos != RecyclerView.NO_ID.toInt())
listener.onItemClick(items[pos])
}
return holder
}

场景 B:协程数据流开发(Flow Specialist)

Kotlin Flow 的常见错误模式相对集中:在错误的 Dispatcher 上 collect、忘记 repeatOnLifecycle、多次 collect 导致重复订阅。这些可以精准规则化:

代码语言:javascript
复制
// Rule B-1: UI 层 collect 必须用 repeatOnLifecycle
// 防止后台状态时仍然处理数据
override fun onViewCreated(
view: View, savedInstanceState: Bundle?
) {
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { state ->
render(state)
}
}
}
}// Rule B-2: ViewModel 中 StateFlow 初始化
// 使用 stateIn 而非手动 MutableStateFlow + 手动赋值
val uiState = repo.dataFlow()
.map { toUiState(it) }
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = UiState.Loading
)

场景 C:JNI 桥接开发(JNI Bridge Specialist)

JNI 是最适合专职化的场景——规则复杂(类型映射表)、模式固定(桥接模板)、错误代价高(Native Crash 难排查)。核心是把完整的类型映射表和标准模板植入规则集:

代码语言:javascript
复制
// 类型映射规则(部分)
// C++ int32_t  → JNI jint    → Kotlin Int
// C++ int64_t  → JNI jlong   → Kotlin Long
// C++ bool     → JNI jboolean → Kotlin Boolean
// C++ string   → JNI jstring  → Kotlin String
// C++ vector   → JNI jobjectArray → Kotlin Array// 标准 JNI 桥接模板
class UserServiceImpl : IUserService {
override fun getUserInfo(
userId: Long
): UserInfo? {
return try {
nativeGetUserInfo(userId)
} catch (e: Exception) {
WwLog.e(TAG, "getUserInfo failed", e)
null  // Native 异常不向上抛,返回 null
}
}
private external fun nativeGetUserInfo(
userId: Long
): UserInfo?
}

四、验证机制:让规则「可检验」

光有规则还不够。daVinci-Env 论文里有一个核心设计思路:「所有 Agent 任务必须可验证(verifiable)」——即 Agent 的输出必须能被自动化测试检验,否则迭代速度会因为人工验证的瓶颈而受限。

对应到 Android 开发里,这意味着:你给 AI 定义的规则,最好能对应到一个可以自动检查的测试用例

• RecyclerView 复用规则 → 可以写 Unit Test,验证不同 position 的 bind 后状态是否正确重置

• 线程规则 → 可以用 StrictMode 检测主线程 IO

• 日志规则 → 可以用 Lint 自定义规则检测 Log.d/e 的使用

• JNI 异常处理 → 可以用 Mock JNI 层模拟异常,验证上层是否正确兜底

这形成了一个完整的闭环:规则定义 → AI 生成代码 → 自动测试验证 → 失败案例反馈回规则迭代。这也是为什么我建议把规则文件放进代码仓库——它本质上是团队知识的工程化表达,需要随项目演进持续更新,不是一次性配置。

五、从「规则约束」到「分层 Agent 协作」

当场景专职化做到一定程度,自然会衍生出多 Agent 协作的架构需求——不同专职 Agent 处理开发流程的不同阶段。这已经有工程实践在做了:OpenHands、Claude Code 等工具都支持通过 System Prompt 配置专职 Agent 角色。

QUARE 论文里给出的多 Agent 协作结论:当不同质量属性(性能 / 安全 / 可维护性)由独立 Agent 分别评估,再由上层综合,最终代码质量比单 Agent 综合评估高 23%。对应到 Android 开发里就是:

代码语言:javascript
复制
// 分层 Agent 协作示意
需求 + Spec
↓
[Service Dev Agent]  // 规则:JNI + 线程 + 项目约定
↓
[UI Dev Agent]       // 规则:生命周期 + 组件规范 + Flow
↓
[Safety Review Agent]  // 规则:Crash 风险 + 豁免列表
↓
[Style Review Agent]   // 规则:规范检查 + 豁免列表
↓
人工终审(业务逻辑)

每个 Agent 的规则集保持精简(5~8 条核心规则),避免规则膨胀后优先级混乱。这是从论文结论和实践经验共同得出的同一个建议。

「通用 Agent」处理的是你不懂的领域。在 Android 开发里,你比任何通用 AI 都更懂自己的项目。你的工作不是「把任务交给 AI」,而是「把你知道的正确做法用规则表达出来,然后让 AI 帮你执行」。规则越清晰、场景越专一,AI 就越可靠。

这套思路的瓶颈在哪里?我最近在想的是规则维护的自动化问题——能不能从代码 Review 的历史记录里自动提取高频问题,反向生成规则候选?daVinci-Env 论文里的 quality-centric filtering pipeline 给了一些启发,但要迁移到 Android 项目的 Review 数据上,还有不少工程工作要做。有进展再分享。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陆业聪 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档