戴在眼前的议程管家:基于 Rokid AR 眼镜的会议纪要助手开发实录

戴在眼前的议程管家:基于 Rokid AR 眼镜的会议纪要助手开发实录

戴在眼前的议程管家:基于 Rokid AR 眼镜的会议纪要助手开发实录

“李总,需求评审环节已经超时12分钟了,后面的自由讨论时间不够了……”

相信每个经常主持或参与会议的人都经历过这样的尴尬:一个议题讨论过于热烈,时间悄然流逝,等到发现时,整个会议日程已经被打乱。手机上的计时器?太容易被忽略。电脑上的提醒?开会时你根本不会盯着屏幕看。

如果能在眼前实时看到当前议题、已用时间、超时警告呢?这就是我开发这款会议纪要助手的初衷——把议程管理"戴"在眼前。

本文将从零开始,完整记录基于 Rokid CXR-M SDK 开发这款 AR 会议助手的全过程,涵盖技术选型、架构设计、核心代码实现与踩坑经验。


一、为什么是 AR 眼镜?

1.1 传统方案的困境

在正式开发之前,我调研了市面上常见的会议管理工具:

方案问题
手机计时 App需要频繁解锁查看,打断会议节奏
电脑倒计时主持人注意力在屏幕,而非与会者
人工报时需要专人负责,且容易忘记
投影时钟只有演讲者能看到,主持人无法兼顾

这些方案的共同问题是:信息获取需要主动动作。主持人要么低头看手机,要么转头看屏幕,这在某种程度上都会分散注意力,影响会议的流畅性。

1.2 AR 眼镜的优势

AR 眼镜提供了一个独特的交互场景:抬眼即见,无需分心

  • 被动信息获取:信息直接出现在视野中,不需要主动去"找"
  • 自然交互:主持人可以保持与与会者的眼神交流
  • 实时提醒:时间节点可以通过语音或视觉主动推送
  • 专注主持:不被设备操作打断会议节奏

这正是 Rokid CXR-M SDK 提供的"提词器场景"的天然应用——把会议议程像提词器一样展示在眼前。


二、系统架构设计

2.1 整体架构

系统采用经典的手机端控制 + 眼镜端显示的架构:

2.2 技术选型

  • 开发语言:Kotlin(简洁、安全、与 Android 深度集成)
  • 最低 SDK:Android 9 (API 28),支持绝大多数现代设备
  • 核心依赖:Rokid CXR-M SDK 1.0.1
  • UI 框架:传统 ViewBinding + XML 布局(简单直接)

三、从零开始:项目配置

3.1 依赖配置

首先,在项目级 settings.gradle.kts 中添加 Rokid Maven 仓库:

repositories { maven { url = uri("https://maven.rokid.com/repository/maven-public/") } google() mavenCentral() } 

然后在 app/build.gradle.kts 中添加 SDK 依赖:

plugins { id("com.android.application") id("org.jetbrains.kotlin.android") } android { namespace = "com.rokid.meeting" compileSdk = 34 defaultConfig { applicationId = "com.rokid.meetinghelper" minSdk = 28 targetSdk = 34 versionCode = 1 versionName = "1.0.0" } buildTypes { release { isMinifyEnabled = false } } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = "17" } } dependencies { // Rokid CXR-M SDK implementation("com.rokid.cxr:client-m:1.0.1-20250812.080117-2") // Android 基础库 implementation("androidx.core:core-ktx:1.12.0") implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.11.0") implementation("androidx.constraintlayout:constraintlayout:2.1.4") implementation("androidx.cardview:cardview:1.0.0") } 

3.2 权限配置

眼镜通过蓝牙连接,需要声明相应的蓝牙权限。在 AndroidManifest.xml 中:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <!-- 蓝牙基础权限 --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- Android 12+ 蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" tools:targetApi="s" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <application ...> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

注意BLUETOOTH_SCAN 添加了 neverForLocation 标志,因为我们只需要扫描蓝牙设备,不需要获取位置信息。这样可以简化权限申请流程。


四、核心模块一:数据模型

好的数据模型是清晰代码的基础。我们定义两个核心数据类:Meeting(会议)和 AgendaItem(议程项)。

4.1 数据类定义

// Meeting.kt package com.rokid.meeting.data /** * 会议数据模型 * @param id 会议唯一标识 * @param title 会议标题 * @param startTime 会议开始时间戳 * @param totalTime 预计总时长(分钟) * @param agenda 议程项列表 */ data class Meeting( val id: Int, val title: String, val startTime: Long, val totalTime: Int, val agenda: List<AgendaItem> ) /** * 议程项数据模型 * @param index 议程序号(用于排序显示) * @param title 议题标题 * @param speaker 主讲人(可为空,表示自由讨论环节) * @param duration 预计时长(分钟) * @param notes 备注(如"需提前准备文档") */ data class AgendaItem( val index: Int, val title: String, val speaker: String?, val duration: Int, var notes: String? = null ) 

4.2 预设会议数据

为了演示方便,我预设了一个典型的产品周会模板:

object MeetingData { val meetings = listOf( Meeting( id = 1, title = "产品周会", startTime = System.currentTimeMillis(), totalTime = 60, agenda = listOf( AgendaItem(1, "上周工作回顾", "张三", 10, null), AgendaItem(2, "本周计划", "李四", 15, null), AgendaItem(3, "需求评审", "王五", 20, "需提前准备文档"), AgendaItem(4, "自由讨论", null, 15, null) ) ) ) } 

这个数据结构的设计考虑了几个实际场景:

  • speaker 可为空,支持"自由讨论"这类没有固定主讲人的环节
  • notes 字段用于记录提醒事项,比如"需提前准备文档"
  • index 与列表位置分离,方便后续扩展议程排序功能

五、核心模块二:SDK 封装与眼镜通信

这是整个项目最核心的部分——如何与 Rokid 眼镜建立连接并发送数据。我将 CXR-M SDK 的功能封装成 RokidGlassesManager 单例对象。

5.1 SDK 初始化与连接

// RokidGlassesManager.kt package com.rokid.meeting.sdk import android.Manifest import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice import android.content.Context import android.content.pm.PackageManager import androidx.core.app.ActivityCompat import com.rokid.cxr.api.CxrApi import com.rokid.cxr.callback.BluetoothStatusCallback import com.rokid.cxr.util.ValueUtil object RokidGlassesManager { // CXR-M API 实例,懒加载 private val cxrApi: CxrApi by lazy { CxrApi.getInstance() } // 连接状态回调 private var connectionCallback: ConnectionCallback? = null // 连接状态回调接口 interface ConnectionCallback { fun onConnecting() fun onConnected() fun onDisconnected() fun onFailed(errorMsg: String) } // 数据发送回调接口 interface SendCallback { fun onSuccess() fun onFailed(errorMsg: String) } // 当前连接状态 val isConnected: Boolean get() = cxrApi.isBluetoothConnected } 

5.2 查找并连接眼镜

/** * 从已配对设备中查找 Rokid 眼镜 * 注意:眼镜需要先在系统蓝牙设置中配对 */ fun findRokidGlasses(bluetoothAdapter: BluetoothAdapter): BluetoothDevice? { if (ActivityCompat.checkSelfPermission( bluetoothAdapter.javaClass, Manifest.permission.BLUETOOTH_CONNECT ) != PackageManager.PERMISSION_GRANTED ) { return null } return bluetoothAdapter.bondedDevices.find { it.name?.contains("Rokid", ignoreCase = true) || it.name?.contains("Glasses", ignoreCase = true) } } /** * 连接眼镜 * 连接过程分两步: * 1. initBluetooth() 初始化蓝牙连接,获取连接信息 * 2. connectBluetooth() 使用连接信息完成最终连接 */ fun connectGlasses(context: Context, device: BluetoothDevice) { connectionCallback?.onConnecting() cxrApi.initBluetooth(context, device, object : BluetoothStatusCallback() { // 获取到连接信息后,进行正式连接 override fun onConnectionInfo( socketUuid: String?, mac: String?, rokidAccount: String?, glassesType: Int ) { if (!socketUuid.isNullOrEmpty() && !mac.isNullOrEmpty()) { // 成功获取连接信息,发起正式连接 connectBluetooth(context, socketUuid, mac) } else { connectionCallback?.onFailed("获取连接信息失败") } } override fun onConnected() { connectionCallback?.onConnected() } override fun onDisconnected() { connectionCallback?.onDisconnected() } override fun onFailed(errorCode: ValueUtil.CxrBluetoothErrorCode?) { connectionCallback?.onFailed(errorCode?.name ?: "连接失败") } }) } // 内部方法:完成蓝牙连接 private fun connectBluetooth(context: Context, socketUuid: String, macAddress: String) { cxrApi.connectBluetooth(context, socketUuid, macAddress, object : BluetoothStatusCallback() { override fun onConnected() { Log.d("RokidGlassesManager", "蓝牙连接确认成功") } override fun onDisconnected() { connectionCallback?.onDisconnected() } override fun onFailed(errorCode: ValueUtil.CxrBluetoothErrorCode?) { connectionCallback?.onFailed(errorCode?.name ?: "连接失败") } override fun onConnectionInfo( socketUuid: String?, macAddress: String?, rokidAccount: String?, glassesType: Int ) { // 此回调在 connectBluetooth 中不会触发 } }) } 

踩坑经验:CXR-M SDK 的蓝牙连接分为两阶段——先通过 initBluetooth() 初始化并获取连接参数(socketUuid 和 macAddress),再通过 connectBluetooth() 完成真正的连接。直接调用 initBluetooth() 后以为连接成功,结果发送数据时一直失败,就是这个原因。

5.3 发送议程到眼镜

/** * 发送当前议程到眼镜 * 使用 CXR-M SDK 的提词器场景(WORD_TIPS) */ fun sendAgenda(meeting: Meeting, currentIndex: Int, callback: SendCallback? = null): Boolean { if (!isConnected) { callback?.onFailed("眼镜未连接") return false } val item = meeting.agenda.getOrNull(currentIndex) ?: return false val text = buildDisplayText(meeting, item, currentIndex) // 1. 激活提词器场景 cxrApi.controlScene(ValueUtil.CxrSceneType.WORD_TIPS, true, null) // 2. 发送文本内容 val status = cxrApi.sendStream( type = ValueUtil.CxrStreamType.WORD_TIPS, stream = text.toByteArray(Charsets.UTF_8), fileName = "agenda.txt", cb = object : SendStatusCallback() { override fun onSendSucceed() { callback?.onSuccess() } override fun onSendFailed(errorCode: ValueUtil.CxrSendErrorCode?) { callback?.onFailed(errorCode?.name ?: "发送失败") } } ) return status == ValueUtil.CxrStatus.REQUEST_SUCCEED } /** * 断开眼镜连接 */ fun disconnect() { cxrApi.deinitBluetooth() } 

5.4 构建显示文本

眼镜端显示的内容需要精心设计——信息要全面,但不能过于拥挤:

private fun buildDisplayText(meeting: Meeting, item: AgendaItem, currentIndex: Int): String { return buildString { appendLine("📋 ${meeting.title}") appendLine() appendLine("────── 当前议题 ──────") appendLine() appendLine("${currentIndex + 1}. ${item.title}") appendLine() item.speaker?.let { appendLine("主讲:$it") } appendLine("预计:${item.duration}分钟") // 如果有备注,显示备注 item.notes?.let { appendLine() appendLine("📝 $it") } } } 

眼镜端的显示效果:

┌──────────────────────────────┐ │ 📋 产品周会 │ │ │ │ ────── 当前议题 ────── │ │ │ │ 3. 需求评审 │ │ │ │ 主讲:王五 │ │ 预计:20分钟 │ │ │ │ 📝 需提前准备文档 │ └──────────────────────────────┘ 

六、核心模块三:主界面与业务逻辑

6.1 Activity 结构

主界面是整个应用的控制中心,负责会议流程的管理和眼镜通信的触发:

// MainActivity.kt package com.rokid.meeting class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding private var currentMeeting: Meeting? = null private var currentAgendaIndex = 0 private var startTime: Long = 0 private var timer: java.util.Timer? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) setSupportActionBar(binding.toolbar) supportActionBar?.title = "会议纪要助手" checkPermissions() setupButtons() observeConnection() } } 

6.2 按钮事件绑定

private fun setupButtons() { // 连接/断开眼镜 binding.btnConnect.setOnClickListener { if (RokidGlassesManager.isConnected) { RokidGlassesManager.disconnect() updateConnectionStatus() } else { connectGlasses() } } // 开始会议 binding.btnStart.setOnClickListener { startMeeting() } // 上一个议题 binding.btnPrev.setOnClickListener { previousAgenda() } // 下一个议题 binding.btnNext.setOnClickListener { nextAgenda() } // 发送到眼镜 binding.btnSend.setOnClickListener { sendToGlasses() } } 

6.3 计时器实现

计时是会议管理的核心功能。这里采用基于系统时间计算的方式,避免定时器累积误差:

private fun startMeeting() { currentMeeting = MeetingData.meetings[0] currentAgendaIndex = 0 startTime = System.currentTimeMillis() startTimer() updateDisplay() } private fun startTimer() { val meeting = currentMeeting ?: return timer?.cancel() timer = java.util.Timer() timer?.scheduleAtFixedRate(object : TimerTask() { override fun run() { val elapsed = (System.currentTimeMillis() - startTime) / 1000 val minutes = elapsed / 60 val seconds = (elapsed % 60).toInt() runOnUiThread { binding.tvElapsed.text = "已进行 ${minutes}分${seconds}秒" } } }, 0, 1000) } 

为什么不用累加计时?

很多初学者会这样实现计时器:

// 错误示范:累加计时 var seconds = 0 timer.scheduleAtFixedRate({ seconds++ updateDisplay(seconds) }, 1000) 

这种实现的问题是:如果手机进入低电量模式或后台运行,定时器可能会被系统暂停或变慢,导致计时不准确。而基于 System.currentTimeMillis() 的计算,无论定时器是否精确,显示的时间永远是准确的。

6.4 议程切换

private fun previousAgenda() { currentMeeting?.let { meeting -> if (currentAgendaIndex > 0) { currentAgendaIndex-- startTime = System.currentTimeMillis() timer?.cancel() startTimer() updateDisplay() } } } private fun nextAgenda() { currentMeeting?.let { meeting -> if (currentAgendaIndex < meeting.agenda.size - 1) { currentAgendaIndex++ startTime = System.currentTimeMillis() timer?.cancel() startTimer() updateDisplay() } } } private fun updateDisplay() { val meeting = currentMeeting ?: return val item = meeting.agenda.getOrNull(currentAgendaIndex) ?: return binding.apply { tvTitle.text = meeting.title tvCurrentAgenda.text = item.title item.speaker?.let { binding.tvSpeaker.text = "发言人:$it" } binding.tvDuration.text = "预计 ${item.duration} 分钟" binding.tvPage.text = "议题 ${currentAgendaIndex + 1}/${meeting.agenda.size}" } } 

6.5 发送到眼镜

private fun sendToGlasses() { if (!RokidGlassesManager.isConnected) { Toast.makeText(this, "请先连接眼镜", Toast.LENGTH_SHORT).show() return } val meeting = currentMeeting ?: return RokidGlassesManager.sendAgenda(meeting, currentAgendaIndex, object : RokidGlassesManager.SendCallback { override fun onSuccess() { runOnUiThread { Toast.makeText(this@MainActivity, "已发送到眼镜", Toast.LENGTH_SHORT).show() } } override fun onFailed(errorMsg: String) { runOnUiThread { Toast.makeText(this@MainActivity, errorMsg, Toast.LENGTH_SHORT).show() } } }) } 

6.6 蓝牙连接处理

private fun connectGlasses() { val adapter = BluetoothAdapter.getDefaultAdapter if (adapter == null || !adapter.isEnabled) { Toast.makeText(this, "请开启蓝牙", Toast.LENGTH_SHORT).show() return } val device = RokidGlassesManager.findRokidGlasses(adapter) if (device == null) { Toast.makeText(this, "未找到眼镜,请先配对", Toast.LENGTH_SHORT).show() return } RokidGlassesManager.connectGlasses(this, device) } private fun observeConnection() { RokidGlassesManager.setConnectionCallback( object : RokidGlassesManager.ConnectionCallback { override fun onConnecting() { runOnUiThread { binding.btnConnect.text = "连接中..." } } override fun onConnected() { runOnUiThread { binding.btnConnect.text = "断开连接" Toast.makeText(this@MainActivity, "眼镜已连接", Toast.LENGTH_SHORT).show() } } override fun onDisconnected() { runOnUiThread { binding.btnConnect.text = "连接眼镜" } } override fun onFailed(errorMsg: String) { runOnUiThread { binding.btnConnect.text = "连接眼镜" Toast.makeText(this@MainActivity, errorMsg, Toast.LENGTH_SHORT).show() } } }) } 

6.7 权限检查

Android 12+ 对蓝牙权限做了细分,需要动态申请:

private fun checkPermissions() { val permissions = mutableListOf<String>() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { permissions.add(Manifest.permission.BLUETOOTH_SCAN) permissions.add(Manifest.permission.BLUETOOTH_CONNECT) } val notGranted = permissions.filter { ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED } if (notGranted.isNotEmpty()) { ActivityCompat.requestPermissions(this, notGranted.toTypedArray(), 100) } } 

七、开发中的踩坑与解决方案

7.1 问题一:连接成功但发送失败

现象initBluetooth() 回调了 onConnected(),但调用 sendStream() 时返回失败。

原因:SDK 的蓝牙连接是两阶段的,initBluetooth() 只是初始化阶段,还需要调用 connectBluetooth() 完成真正的连接。

解决:在 onConnectionInfo() 回调中获取 socketUuid 和 macAddress,然后调用 connectBluetooth()

7.2 问题二:计时器在后台不准确

现象:手机锁屏后再打开,计时器显示的时间明显偏少。

原因:系统为了省电会限制后台应用的定时器执行频率。

解决:使用 System.currentTimeMillis() 计算已用时间,而不是累加计数器。这样即使定时器不精确,显示的时间也是准确的。

7.3 问题三:眼镜显示中文乱码

现象:发送的中文在眼镜端显示为乱码。

原因:发送数据时没有指定正确的字符编码。

解决:明确使用 UTF-8 编码:

stream = text.toByteArray(Charsets.UTF_8) 

7.4 问题四:蓝牙权限被拒绝

现象:在 Android 12+ 设备上,应用启动时直接崩溃。

原因:Android 12 新增了 BLUETOOTH_SCANBLUETOOTH_CONNECT 权限,需要动态申请。

解决:在 onCreate() 中检查并申请权限,同时在 AndroidManifest.xml 中声明。


八、功能演示

8.1 功能清单

功能说明状态
蓝牙连接查找并连接 Rokid 眼镜
会议管理预设会议模板
议程控制上一个/下一个切换
实时计时精确到秒的计时显示
眼镜同步议程内容发送到眼镜
超时提醒TTS 语音提醒🔜
会议纪要AI 自动生成🔜

8.2 使用流程

  1. 准备阶段:在手机蓝牙设置中配对 Rokid 眼镜
  2. 启动应用:打开会议纪要助手,授予蓝牙权限
  3. 连接眼镜:点击"连接眼镜"按钮
  4. 开始会议:点击"开始会议",计时自动开始
  5. 切换议题:使用"上一个""下一个"按钮切换议程
  6. 同步眼镜:点击"发送到眼镜",当前议程显示在眼镜上
  7. 会议结束:断开眼镜连接,退出应用

九、总结与展望

9.1 项目总结

这个项目虽然功能相对简单,但完整地展示了 AR 眼镜应用的开发流程:

  1. 理解场景:从用户痛点出发,找到 AR 眼镜的真正价值点
  2. SDK 集成:学习 CXR-M SDK 的 API,理解其设计思想
  3. 架构设计:合理分层,将 SDK 封装与业务逻辑解耦
  4. 细节打磨:处理好权限、编码、计时等细节问题

9.2 后续规划

当前版本还只是一个 MVP(最小可行产品),后续计划增加以下功能:

  • 超时语音提醒:当议题超时时,通过眼镜 TTS 发出语音提醒
  • 会议纪要生成:接入语音识别,自动生成会议纪要
  • 云端同步:会议记录上传云端,支持多设备查看
  • 多人协作:支持多副眼镜同时连接,参会者都能看到议程

9.3 关于 AR 办公的思考

AR 眼镜在办公场景有着巨大的想象空间。会议管理只是一个小切口,类似的场景还有:

  • 演讲提词器:演讲者眼前实时显示台词
  • 培训指导:操作步骤直接叠加在视野中
  • 远程协作:专家远程标注,本地实时可见
  • 信息展示:会议室、工位的信息卡片

期待更多开发者加入 AR 生态,一起探索这个新的人机交互边界。


项目源码MeetingHelper/

参考资源

Read more

从Prompt到成片仅需2.3秒,Seedance 2.0如何重构AIGC工作流?——头部客户实测ROI提升340%,但90%团队尚未启用映射热更新模式

第一章:Seedance 2.0语义理解与视频生成映射的技术本质 Seedance 2.0 的核心突破在于将自然语言语义空间与高保真视频表征空间建立可微、对齐且可泛化的双向映射。该映射并非简单地将文本嵌入向量输入扩散模型,而是通过分层语义解耦机制,在动词时态、空间关系、主体属性、镜头运动四个正交维度上构建结构化语义图谱,并驱动时空潜在变量的协同演化。 语义解析的层级化建模 系统首先调用轻量级语义角色标注(SRL)模块提取谓词-论元结构,继而通过多头跨模态注意力对齐视觉先验知识库(如 Kinetics-700 动作本体与 COCO-Spatial 关系图谱)。该过程确保“她缓缓旋转并伸展手臂”被分解为: * 主语:“她” → 对应人体姿态关键点拓扑约束 * 动作序列:“旋转”(轴向角速度)、“伸展”(关节角度增量)→ 驱动运动轨迹生成器 * 副词修饰:“缓缓” → 映射至帧间光流平滑度损失权重 视频生成的隐空间对齐策略 Seedance 2.0 引入语义-视觉对比学习(SVCL)损失,强制文本编码器输出与视频潜在码(来自

Stable Diffusion模型下载器中文版终极使用指南

在AI绘画创作的世界中,获取高质量的模型是决定作品效果的关键因素。传统的模型下载方式往往面临网络限制和复杂的配置流程,让很多创作者望而却步。今天我要为大家介绍的这款Stable Diffusion模型下载器中文版,正是为了解决这些痛点而生的强大工具。 【免费下载链接】sd-webui-model-downloader-cn 项目地址: https://gitcode.com/gh_mirrors/sd/sd-webui-model-downloader-cn 为什么选择这个AI绘画工具 作为一名AI绘画爱好者,你是否曾遇到过以下困扰: * 访问国外模型网站速度缓慢甚至无法连接 * 下载过程中频繁中断需要重新开始 * 不知道不同类型的模型应该存放在哪个目录 * 需要手动复制粘贴复杂的下载链接 这款模型下载器中文版专为国内用户设计,提供了便捷的高速下载体验,让你能够专注于创意表达而非技术细节。 快速上手三步曲 第一步:获取模型链接 打开Civitai网站,找到你感兴趣的模型页面,复制浏览器地址栏中的完整URL地址。请确保复制的是模型展示页面地址,而不是直接的下载

老码农和你一起学AI系列:LLaMA衍生模型

老码农和你一起学AI系列:LLaMA衍生模型

LLaMA衍生模型指的是基于Meta发布的LLaMA基础模型,通过微调、优化或扩展而产生的各类变体模型。就像LLaMA是一个强大的“通用大脑”,而衍生模型则是针对不同语言、不同任务、不同应用场景进行“专业培训”后的“专家”。根据衍生方式的不同,可以分为两大类:LLaMA衍生模型、官方演进版本 一、官方演进版本 LLaMA系列本身就在持续演进,每一代都是前一代的“官方衍生版”: 版本核心升级技术亮点LLaMA 1开源奠基13B参数超越GPT-3,验证“小模型+大数据”路线LLaMA 2可商用、GQA上下文翻倍至4K,引入分组查询注意力,70B版本逼近GPT-3.5LLaMA 315T数据、128K上下文405B旗舰版性能比肩GPT-4,代码占比提升至25%LLaMA 4MoE稀疏架构、多模态17B激活参数达400B总参数效果,原生支持图像/视频理解,1000万上下文窗口 二、社区微调衍生模型 Alpaca(斯坦福):LLaMA衍生模型的“鼻祖”。斯坦福团队用52K条指令数据对7B LLaMA进行微调,仅花费不到600美元就训练出媲美GPT-3.5的对话模型。

VSCode Copilot 终极魔改:以智谱 GLM-5.1 为例,一文搞定任意大模型接入

VSCode Copilot 终极魔改:以智谱 GLM-5.1 为例,一文搞定任意大模型接入

VSCode Copilot 终极魔改:以智谱 GLM-5.1 为例,一文搞定任意大模型接入 前言:为何你的 Copilot 需要一次“魔改”? 本文旨在帮助所有希望突破 VSCode Copilot 模型限制、追求更高代码效率和性价比的开发者。如果你也曾面临以下困境,那么这篇文章就是为你量身打造的: * Copilot 官方模型不够用:想尝试最新、最强的国产模型(如智谱 GLM、文心一言、Kimi)却无从下手。 * API 订阅成本高:官方或其他国外模型的订阅费和按量计费(通常以美元结算)让个人开发者望而却步。 * 替代品体验有瑕疵:其他辅助插件在某些场景下不如原生的 Copilot 轻便、流畅。 本文将提供一个终极解决方案:通过一个 VSCode 插件,无缝接入任何支持 OpenAI 兼容接口的大模型。我将以当前备受瞩目的国产模型智谱 GLM-5.1 为例,