- AI 应用
- 大模型
- 交互助手
- RAG
【免费下载链接】jev-chat-jarvis
装在手机上的对话副驾:在 QQ / X / 飞书里读懂对方、给出候选回复、一键填入输入框,发不发由你。非侵入,只读屏幕,不 hook 不改包。
本文基于仓库内 docs/v1.3-plan.md 总方案文档,结合 docs/v1.3-morning-checklist.md 与当前仓库源码(
app/src/main/java/com/jev/probe/)展开。Jev Assistant 是一款"只读屏幕、绝不自动发送"的 Android 对话副驾:它在 QQ / X / 飞书里读懂对方、给出候选回复、由用户一键填入输入框。v1.3 版本的核心命题有三:把判断 / 回复 / 视觉三路模型接口全部做成可配置并带连通测试、引入本地知识库与联系人关联上下文、为读不到控件树的 App 提供截屏 + OCR 采集通道。读完本文,你将完整掌握 v1.3 的配置契约、知识库数据模型与检索规则、OCR 分层与截屏防连射机制,以及每一阶段的验收标准。
一、v1.3 要解决什么问题:四大目标与阶段编排
v1.3 总方案为一次多阶段升级,目标拆为四条(原文逐条保留):
- API 自定义:判断 / 回复 / 视觉三路接口的地址、密钥、模型全部可配,带预设与各自连通测试。
- 知识库 + 关联上下文:用户可维护本地知识库(笔记 + 联系人档案);每次分析自动带上对该联系人的历史记录与相关知识,回复与知识库一致;联系人跨 App 关联(别名)。
- OCR 采集:读不到控件树的 App(飞书正文、任意未适配 App)走截屏 + OCR;已适配 App 树读空时 OCR 兜底。
- 版本与发布:版本号升到 1.3,出 release 包,README 更新。
阶段顺序与依赖被严格固定为A(API)→ D(知识库 / 上下文)→ B(OCR)→ C(文档 / 发布),每个阶段由一个执行 agent 顺序做完、构建通过再进下一阶段;方案文档特别强调同一时间只有一个 agent 改代码(gradle 与文件都会冲突)。每阶段结束后需写_reports/v13_<阶段>_report.md,内容固定为:改了什么(逐文件)→ 构建输出末尾原文 → 装机结果 →自验缺口。
二、硬约束:隐私与兼容的红线
v1.3 沿袭项目既有约束并新增三条(方案原文):
- 绝不自动发送、不碰钱、密钥不落盘不进日志不进 git、UTF-8、禁 git commit/push。
- 所有用户数据(知识库、联系人、历史记录)只存 App 私有目录,提供"清空"按钮;聊天正文不进 logcat。
- 旧配置必须自动迁移:升级后原来的 OpenRouter 密钥、回复模型、关系描述、白名单、透明度、开关全部保留可用。
- 技术栈约束:传统 View + XML,不引 Compose;不引 Room(用 JSON 文件 + 内存缓存即可);ML Kit 只在 B 阶段引入。
从源码看这些约束是真实落地的:KbStore.clearAll()只删除filesDir/kb目录(源码注释明确"API keys, whitelist and every other SharedPreferences value are untouched"),聊天正文从不进日志——ChatCaptureService.kt 中连调试日志都只打印"side + 文本长度"。
三、公共契约:Prefs 配置字段全表
v1.3 的第一份公共契约是Prefs 新字段(A 阶段建、后续阶段只读)。以下字段、默认值与说明均继承自方案文档,并已对照源码 Prefs.kt 逐一核实:
3.1 判断接口(Jev)
| 字段 | 类型 | 默认值 / 说明 |
|---|---|---|
judgeProvider | String | "openrouter" \| "typesafe" \| "custom",默认openrouter。从当前仓库源码看,实际取值集合已扩展为bocha / openrouter / typesafe / vercel / zen / custom(Prefs.PROVIDER_*常量) |
judgeBaseUrl | String | openrouter 默认https://openrouter.ai/api;typesafe 默认https://api.typesafe.ai |
judgeKey | String | 迁移:老openRouterKey→judgeKey |
judgeModel | String | openrouter 默认typesafe/jev-1.13;typesafe 默认jev-latest |
判断接口的请求路径规则(方案原文 + Prefs.kt 的judgeEndpoint()实现一致):
openrouter → {judgeBaseUrl}/alpha/decisions typesafe → {judgeBaseUrl}/v1/systemone custom → 用户填完整 URL 到 judgeBaseUrl,原样 POST请求体三者相同:{model, state, questions}。源码中还加入了同为 TypeSafe 兼容协议的bocha / vercel / zen三个网关(均走/v1/systemone),它们的 base/model 预设也在 Prefs.kt 的 companion 常量中。
3.2 回复接口(任何 OpenAI 兼容 chat completions)
| 字段 | 类型 | 默认值 / 说明 |
|---|---|---|
replyBaseUrl | String | 默认https://openrouter.ai/api/v1;填到/v1为止,客户端自己拼/chat/completions(源码replyEndpoint()正是如此拼接) |
replyKey | String | 留空 = 用 judgeKey(源码effectiveReplyKey():replyKey.ifBlank { judgeKey }) |
replyModel | String | 老字段沿用,默认deepseek/deepseek-chat-v3.1 |
3.3 视觉接口(OCR 用,OpenAI 兼容,支持 image_url)
| 字段 | 类型 | 默认值 / 说明 |
|---|---|---|
visionBaseUrl | String | 默认同 replyBaseUrl |
visionKey | String | 留空 = 用 replyKey → judgeKey(源码effectiveVisionKey():visionKey.ifBlank { effectiveReplyKey() }) |
visionModel | String | 默认qwen/qwen2.5-vl-72b-instruct(OpenRouter 区域可用;用户可改) |
3.4 上下文与 OCR 开关(后续阶段写入)
| 字段 | 类型 | 默认值 / 说明 |
|---|---|---|
contextEnabled | Boolean | 记录历史并注入。修订后默认 false(隐私优先,不落盘除非用户主动开) |
contextHistoryCount | Int | 注入最近多少条历史,默认30(源码注入时coerceIn(0, 100)) |
autoSummary | Boolean | 联系人自动摘要,默认true;修订后功能推迟,ReplyClient.summarize()保留但不接线 |
ocrEngine | String | "mlkit" \| "vision",默认mlkit |
ocrForUnknownApps | Boolean | 未适配 App 走通用 OCR,默认true |
ocrFallback | Boolean | 已适配 App 树读空时 OCR 兜底,默认true |
ocrAutoAnalyze | Boolean | OCR 模式自动分析,默认false(手动点) |
3.5 旧配置自动迁移:一次性、可复现
方案修订明确三条迁移纪律(A 阶段补充):迁移只做一次、judgeKey被用户清空不得复活、旧存储名一个不改。源码 Prefs.kt 的migrateIfNeeded()精确实现:
- 以
prefs_migrated_v13=true布尔标记为闸门,写过标记后不再读openrouter_key; - 仅当
judgeKey为空且老openrouter_key非空时,才把老密钥拷到judgeKey,并打日志prefs migrated judgeKey.len=N(只记录长度,绝不记录密钥本身); replyModel沿用旧存储键,天然继承无需处理;- 老代码的
openRouterKey读写保留为judgeKey的兼容别名,旧调用点无需改动即可编译运行。
四、模型客户端拆分:一条链路上三个专职客户端
方案将原来臃肿的JevClient拆成四个文件(A 阶段),职责如下(与源码逐一对应):
jev/JudgeClient.kt // 只管 Jev:judge(snapshot, context) / rank(candidates) jev/ReplyClient.kt // 只管生成:draft(snapshot, context) → 3 条;summarize(text) → 摘要(D 用) jev/VisionClient.kt // 只管视觉:extractDialog(bitmap) / ocrLines(bitmap)(B 用,A 阶段只建壳) jev/HttpJson.kt // 共用的 POST JSON + 退避 + 错误归类(把现在 JevClient 里的 postJson 抽出来)旧JevClient删除或改成薄门面,调用方(ChatCaptureService、SettingsActivity 连通测试)改用新类。
4.1 错误信息规范:一路一码一摘要
错误信息必须带"哪一路 + HTTP 状态码 + 前 120 字响应"。源码 HttpJson.kt 用三个要素落实:
Route常量区分三路:判断接口/回复接口/视觉接口;ApiException(route, status, snippet)的buildMessage()生成"$route HTTP $status:${snippet.take(120)}"(无状态码则为"$route 请求失败:…");- 传输层错误被
describe()翻译成人话:网络超时、域名解析失败、无法连接、HTTPS 证书校验失败等,且密钥材料绝不进入任何错误文本。
4.2 重试策略
HttpJson.post()最多 3 次尝试:仅对429 / 529(服务繁忙)做指数退避(500ms * (1L shl attempt));其他 4xx 客户端错误一律不重试,直接抛出;读响应体前先分支状态码,保证 401 这类错误绝不会因为读 body 异常而丢失状态码被误判成传输失败。
4.3 视觉请求的坑位(方案修订 + 源码注释双重印证)
方案修订与 VisionClient.kt 源码注释共同列出的三个"真花过调试时间"的细节:
- 图片用
data:image/jpeg;base64,前缀(Bitmap → JPEG,Base64.NO_WRAP避免换行破坏 data URL;选 JPEG 而非 PNG,截图 PNG 的 base64 体积会大数倍); - 图片 part 必须放在文本 part 之前——通义 DashScope compatible-mode 对相反顺序会直接拒绝;
- DeepSeek 官方不支持 image_url,
VisionClient.supportsVision()对api.deepseek.com返回 false,测试时要提示"该接口不支持视觉"。同时视觉 baseUrl 固定走 OpenRouter 默认、不跟随回复接口(回复接口切到 DeepSeek 会静默弄坏 OCR,故故意不继承)。
4.4background/history字段的兼容策略
D 阶段要给 Jev 的 state 新增background(背景知识)与history(历史消息)字段,但方案不确定线上alpha/decisions是忽略新字段还是返回 400。因此 JudgeClient.kt 实现了降级重试:带背景/历史请求若收到 4xx,去掉这两个字段原样重发一次,保证"新字段可以拖累质量,但绝不能打断分析"。题目英文 instructions 还补了一句 "facts in background are given context, not off-topic",排序题同理,防止模型把背景事实误判为跑题。
五、知识库与关联上下文(D 阶段)
5.1 数据模型
存放位置(方案原文):context.filesDir/kb/notes.json、kb/contacts.json、kb/logs/<contactId>.json。数据模型与源码 KbModels.kt 完全一致:
Note(id, title, content, tags: List<String>, alwaysOn: Boolean, enabled: Boolean, updatedAt) Contact(id, name, aliases: List<String>, apps: List<String>, relationship: String, notes: String, autoSummary: String, summaryAtCount: Int, updatedAt) LogEntry(side, text, ts, app) // 每联系人一个文件,最多保留 300 条,按 (side,text) 去重追加 ChatContext(contact: Contact?, history: List<LogEntry>, notes: List<Note>, budgetChars = 1500)要点:Contact.apps记录来源包名(如com.tencent.mm),aliases就是"跨 App 关联"的机制——同一个人在微信/QQ/飞书里标题不同,全部登记为别名即可命中;LogEntry每联系人最多300 条(源码KbStore.MAX_LOG = 300,超限从头部移除)。
5.2 存储实现:JSON 文件 + 原子写
方案修订要求:JSON 文件单写者(synchronized+ 原子写临时文件再 rename);"清空"只删filesDir/kb,不动密钥与白名单。源码 KbStore.kt 全部落实:
- 所有读写走同一个
lock对象(synchronized),单写者由构造保证; writeAtomic()先写*.tmp再renameTo目标文件——POSIX 同目录 rename 一步替换,进程被杀也不会留下半个 JSON;rename 失败才退化为原地覆盖并打日志说明"非原子";- 解析损坏的 JSON 文件时先改名备份再当作空库,绝不静默覆盖用户数据(
readJsonArray的trustworthy标记); - 内存缓存 + 落盘双份,写失败即清缓存强制下次回源;
- 序列化手写
org.json,不引 Gson/Moshi,呼应"不引 Room"的轻量约束。
5.3 名称规范化与联系人匹配
方案修订:去首尾空白、零宽字符、群名尾部(数字)、大小写不敏感后再匹配 name / aliases。源码KbStore.normalizeName()正是四步流水线:stripZeroWidth(正则剔除\u200B-\u200D与\uFEFF)→stripTrailingCount(正则剥掉半角/全角括号包裹的数字尾巴,如测试群(12)/测试群(12)都归一为测试群)→ trim → lowercase。findContact(title, app)命中规则:会话标题 == contact.name 或 ∈ aliases;多个联系人同时命中时优先选已记录过该包名的那个。联系人绝不自动建档(修订后):只由用户手建,或在悬浮窗菜单里"把当前会话存为联系人"一键建(源码KbStore.saveOrMergeContact(),已存在的同名联系人会并入包名与别名,不产生重复档案)。
5.4 笔记检索:只做两层
方案修订把初版"中文字符二元组重合度打分"收窄为两层朴素规则(源码 ContextBuilder.kt 原样实现):
alwaysOn笔记全带,单独占预算、不截断;- 其余笔记按「标签 / 标题 ∈ 会话标题或最近 6 条消息」的包含匹配,命中才带,最多 5 条(
MAX_HIT_NOTES = 5),新笔记优先。
总预算budgetChars = 1500:超预算时先丢弃最旧的历史、再丢最后命中的整条笔记(绝不截断半条笔记)。
5.5 历史记录与去重
- 历史只在
contextEnabled且命中联系人时记录(opt-in,默认关); - 每次采集把当屏消息追加进该联系人的日志文件,最多保留 300 条;
- 注入前去掉屏幕上已可见的副本:只删与当屏消息
(side, text)完全相同且长度 ≥ 4的副本(DEDUPE_MIN_LEN = 4,避免把"嗯""好"这类短文本误判为同一句); appendLog()以"整屏序列"为单位做增量去重:与上一屏完全相同则不写、日志尾部与当前屏前缀重叠则只追加新滚动出来的尾部、往回翻旧消息则整轮跳过——这是防止滚动采集把历史写重写的核心机制。
5.6 注入方式与提示词
- Jev 的 state 增加
background(关系 + 联系人备注 + 自动摘要 + 命中笔记)与history(去掉屏幕上已有的历史消息);二者皆空时不发送字段(ChatContext.isEmpty()); - 回复提示词固定追加:「以下是关于我和对方的背景与知识库,回复必须与之一致,可以直接引用其中事实,不要编造知识库里没有的事实」——源码 ReplyClient.kt 的
knowledgeBlock()原文; - 悬浮窗显示一行"知识库 N 条 · 历史 M 条"(
ChatCaptureService里overlay.setContextInfo(ctx.notes.size, ctx.history.size))。
5.7 一键自检
设置页的「自检」对应 KbSelfCheck.kt:用临时笔记 + 临时联系人 + 一次性 scratch Prefs(不碰用户真实配置)跑通六项检查——名称归一化(含全角括号群名)、联系人别名命中、笔记 tag 命中、当屏去重不回流、旧消息注入、contextEnabled=false时零注入——结束即清理,最后返回"自检通过:联系人匹配 / 笔记命中 / 历史去重 / 预算注入都正常"一行结论。
六、OCR 采集(B 阶段)
6.1 分层架构
方案原文的分层(与仓库实际文件结构一致):
capture/ocr/ScreenCapture.kt // AccessibilityService.takeScreenshot 封装:限频 ≥1s、失败原因枚举、Bitmap 回调 capture/ocr/OcrEngine.kt // interface: recognize(bitmap, region): List<OcrLine(text, bounds)> capture/ocr/MlKitOcr.kt // com.google.mlkit:text-recognition-chinese(bundled) capture/ocr/VisionOcr.kt // 走 VisionClient,可返回结构化对话 capture/ocr/BubbleGrouper.kt // OCR 行 → 气泡:按行距、左右对齐分组;side 按气泡贴左/贴右 capture/GenericOcrAdapter.kt // 任意包名:裁掉顶栏(有标题的)与输入区(有 EditText 的),中间区域 OCR capture/FeishuAdapter.kt 改造 // 树拿 bubble_content_container 矩形 + 已读容器判 me;每个矩形 OCR 正文v1.3 修订把 B 阶段收窄为只做两件事:① 飞书:树上bubble_content_container矩形 + 已读容器判 me,对每个矩形做 ML Kit OCR(结果里剥掉"已读");② 通用入口:悬浮窗菜单"截屏识别一次",对任意 App 手动截一次整屏 OCR 并分析——不自动、不按左右判 me/other(全部记为 other 并在面板标注"未分边")。视觉模型 OCR 不进采集主路径。注:当前仓库中VisionOcr.kt、BubbleGrouper.kt、GenericOcrAdapter.kt尚未落地为独立文件,通用整屏分组的实现内聚在 ChatCaptureService.kt 的groupOcrLines()中(按行距 > 1.2× 行高分组),面板备注为"OCR 未分边,把全部消息当作对方所说"。
6.2 适配器契约:三态返回值
方案修订把适配器契约拆成三种返回(源码 ChatAppAdapter.kt 注释一致):
extract返回null=不在聊天窗(列表页、动态页、设置页…),服务什么都不做;- 返回
ChatSnapshot(messages 为空)=在聊天窗但树里没正文——这是 OCR 兜底的唯一触发条件; - 返回非空 messages = 正常采集。
服务只对第二种走 OCR 兜底,且失败退避 1s → 2s → 4s,上限 30s,绝不每秒连射。当前已接入的适配器为 QQ、X、Feishu;微信(com.tencent.mm)因反截屏风险控制被完全禁用——不读树、不截屏、不 OCR、不填入,仅显示一次性提示(源码ChatCaptureService的PKG_WECHAT与WECHAT_DISABLED_MSG,并有专项注释说明)。
6.3 截屏实现:窗口优先、限频、退避、错误码人话
源码 ScreenCapture.kt 对方案修订逐条落地:
- API 34 优先
takeScreenshotOfWindow,回退takeScreenshot(DEFAULT_DISPLAY)——窗口截屏在分屏/排除状态栏时画面小于整屏且有偏移,因此Result.Ok携带scaleX/scaleY/originX/originY,节点矩形与 OCR 框按(screenX - originX) * scaleX双向换算; - 截前隐藏悬浮窗(
HIDE_SETTLE_MS = 120ms等一帧让悬浮球消失)、截后恢复; - 回调里
copy(ARGB_8888)后立刻close()HardwareBuffer——泄漏 HardwareBuffer 会让系统合成器几发之后饿死; - 全局限频 ≥ 1000ms(跨实例共享
lastAttemptAt,因为系统限流是按服务计的),连续失败退避1s → 2s → 4s …封顶 30s(MAX_STREAK = 6); - 回调有 3 秒看门狗超时(平台可能对受保护窗口干脆不回调,防止悬浮窗永远隐形、忙标志卡死);
- 错误码 1/2/3/4/6 各给一句人话(
humanMessage()):1=内部错误/系统拒绝;2=无障碍服务未声明截屏能力(去设置关掉再开);3=间隔太短;4=没有有效显示;6=窗口不可见或受保护(FLAG_SECURE),另有两个自有码 -1 截屏太频繁、-2 截屏超时。
6.4 无障碍配置与生效条件
无障碍 XML config_disguised.xml 增加android:canTakeScreenshot="true"(同时保留flagRetrieveInteractiveWindows等采集所需 flags)。关键生效条件(方案原文写入验收):加了该属性后必须把无障碍关掉再开启才生效——HyperOS 不热更新 meta-data;HyperOS 还可能单独拒绝无障碍服务截屏,方案明确"B 开工第一步先真机打一次takeScreenshot看 errorCode,被拒则另起一个截屏专用服务"。服务本身以伪装类名com.google.android.accessibility.selecttospeak.SelectToSpeakService注册(见 AndroidManifest.xml),让微信这类对常规无障碍服务隐藏节点树的应用暴露树——微信最终仍被主动禁用,是策略决定而非能力缺失。
6.5 飞书适配:矩形 + 已读容器判 me
飞书正文是绘制而非 View 布局(2026-09-21 真机验证),树里几乎永远没有正文文本。因此适配器是混合型(源码 ChatAppAdapter.kt):
- 树里收集
bubble_content_container的屏幕矩形(过滤顶栏/输入区带),collectFeishuBubbleRects()在截屏回调里重新读取——防抖 + 隐藏悬浮窗 + 拍摄之间隔了几百毫秒,列表可能已经滚动,必须重读避免裁错行; - 边判定不靠几何(飞书全员左对齐):只有自己的气泡挂"已读/发送回执条"(
…time_read_state_container_align_bubble),以此判 me,对方判 other(真机上"已读容器判 me"属推断项,写进了验收的核对点); - 每个矩形做一次 ML Kit OCR,
cleanBubbleText()剥掉气泡尾部粘着的"已读/未读"和时间戳。
6.6 通用入口"截屏识别一次"
任意未适配 App(钉钉、Telegram、微博私信等)长按悬浮球 → 「截屏识别一次」:整屏截一张,OCR 中间区域(顶部裁 12%、底部裁到 84%,避开标题栏与输入框),按行距分组为伪气泡,全部记为 other并在面板标注"未分边",随后照常跑分析。手动触发不受"最新消息来自对方"门槛限制,每次都重新分析;自动路径则依赖ocrSignature()(飞书用"标题 + 每个气泡矩形及边",其他用"包名 + 标题")做拍摄前去重——树空时飞书每个 content-changed 事件都会触发兜底,没有这道闸门,光标闪烁都能变成每秒一张截屏。
6.7 ML Kit:bundled 中文识别
MlKitOcr锁定com.google.mlkit:text-recognition-chinese的bundled(非 play-services)变体:模型打进 APK,无 GMS 的手机也能识别、永不联网下载。识别器单例化(TextRecognition.getClient(ChineseTextRecognizerOptions.Builder().build())),warmUp()在服务连接时于工作线程预载模型,避免第一次真识别在主线程(截屏回调线程)承担模型加载开销;坐标从 bitmap 空间经 scale/origin 换算回屏幕空间。方案还要求ndk.abiFilters = arm64-v8a、选支持 16KB 页对齐的版本,并把"包体增量"与"无 GMS 手机识别一次"写进验收项。
七、验收标准:每阶段构建 + 装机 + 真机
方案规定的每阶段验收(原文完整保留):
- A:设置页三组接口各自连通测试通过;把回复接口切到 DeepSeek 官方地址再切回,QQ 分析仍正常;老密钥升级后不用重填。
- D:在设置里建 1 条笔记(含一个虚构事实)+ 给某联系人设关系与别名;对该联系人分析时,候选回复体现该事实;日志显示"知识库 N 条 / 历史 M 条";清空按钮生效。
- B:飞书对话正文被 OCR 读到并分析;任选一个未适配 App(如钉钉 / Telegram / 微博私信)通用 OCR 出候选。
- C:README 平台表更新,版本 1.3,release 包签名校验通过。
配套的早间装机清单 docs/v1.3-morning-checklist.md 给出具体操作与预期:
adb install -r app/build/outputs/apk/debug/app-debug.apk adb shell appops set com.jev.probe SYSTEM_ALERT_WINDOW allow装机后手机上将无障碍关掉再打开(新增截屏能力,HyperOS 不热更新 meta-data),然后看adb logcat -s JEVASSIST是否出现capture service connected与prefs migrated judgeKey.len=N(N>0 = 旧密钥迁移成功)。真机核对项还包括:长按悬浮球「截屏识别一次」出候选(= 截屏被放行)还是"内部错误/系统拒绝"(= HyperOS 拒绝无障碍服务截屏,需另起截屏专用服务);飞书里我/对方是否判反;logcat 不应出现每秒一张截屏(签名去重生效)。发布门槛:versionCode 4 / versionName 1.3、targetSdk保持 35 不抬到 36、assembleRelease+ apksigner 校验、记录包体(清单预期约 27 MB)、以apk/jev-assistant-v1.3-release.apk替换 v1.2。
八、方案的设计取舍:三句话
对照 docs/v1.3-plan.md 全文与其修订记录,v1.3 的工程取向可以浓缩为三点,也是阅读源码时最值得记住的原则:
- 隐私是硬约束而非功能:密钥只存 App 私有 SharedPreferences、只记录长度不进日志;知识库默认不落盘、落盘只写
filesDir/kb、清空按钮只删该目录;聊天正文从不到 logcat。这解释了contextEnabled修订后默认 false、ocrAutoAnalyze默认 false 等所有"默认保守"的取值。 - 失败可诊断、降级不崩坏:三路错误统一为"路由 + 状态码 + 前 120 字";
background/history遇到 4xx 自动降级重发;OCR 失败退避封顶 30s 且错误码全部翻译成人话;损坏的 JSON 先备份再当空库。 - 能简单就不复杂:不引 Compose/Room/Gson,JSON 文件 + 内存缓存 + 手写 org.json;检索不做向量打分,只做 alwaysOn + 包含匹配;排序边判定能省则省(通用 OCR 一律 other)。方案文档中"Grok 4.7 评审后收窄"的每一处修订,几乎都在往"更简单、更保守、更可验证"的方向走。
以上内容以 docs/v1.3-plan.md 为主体骨架,源码实现细节均可在上述各文件路径中核对;未真机验证的推断项(如飞书"已读容器判 me"、HyperOS 截屏放行情况)在方案与验收清单中均已显式标注为"需真机确认",与本文保持一致。
- AI 应用
- 大模型
- 交互助手
- RAG
【免费下载链接】jev-chat-jarvis
装在手机上的对话副驾:在 QQ / X / 飞书里读懂对方、给出候选回复、一键填入输入框,发不发由你。非侵入,只读屏幕,不 hook 不改包。
相关推荐
GPT4All本地知识库构建与智能文档分析技术深度解析
GPT4All本地知识库构建与智能文档分析技术深度解析 GPT4All作为完全开源的本地大语言模型生态系统,在数据私密性和智能文档处理方面展现出卓越的技术优势。
人工智能大模型本地部署AI 应用交互助手RAGUmi-OCR中实现自定义文本识别区域的技术方案
Umi OCR中实现自定义文本识别区域的技术方案 在OCR应用开发中,自定义识别区域是一个较为小众但实用的需求。本文将探讨如何在Umi OCR项目中实现这一功能
OCR桌面应用上下文丰富技术:为RAG系统注入深度语义理解
上下文丰富技术:为RAG系统注入深度语义理解 本文详细探讨了RAG系统中的上下文增强技术,包括文档级和章节级上下文分块、相关片段提取、语义分块以及上下文压缩等关
示例工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考