戴在眼前的议程管家:基于 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

什么是Agentic AI?Agentic AI 与传统 AIGC 有什么区别?

什么是Agentic AI?Agentic AI 与传统 AIGC 有什么区别?

什么是 Agentic AI?Agentic AI 与传统 AIGC 有什么区别? 1. 引言 近年来,人工智能(AI)技术飞速发展,其中以生成式 AI(AIGC,Artificial Intelligence Generated Content)和 Agentic AI(智能代理 AI)最为热门。AIGC 通过深度学习模型生成文本、图像、视频等内容,而 Agentic AI 则更进一步,能够自主感知、决策并执行任务。那么,Agentic AI 究竟是什么?它与传统的 AIGC 有何不同?在本文中,我们将深入探讨 Agentic AI 的概念、技术原理、

FLUX.1-dev FP8完整部署教程:让6GB显存显卡也能玩转AI绘画

FLUX.1-dev FP8完整部署教程:让6GB显存显卡也能玩转AI绘画 【免费下载链接】flux1-dev 项目地址: https://ai.gitcode.com/hf_mirrors/Comfy-Org/flux1-dev 还在为显卡配置不够而苦恼吗?🤔 FLUX.1-dev FP8版本的出现彻底改变了游戏规则!这款革命性的量化模型将显存需求从16GB大幅降低至仅6GB,让RTX 3060、4060等主流显卡也能流畅运行专业级AI绘画,为普通用户打开了无限创意的大门。 🎯 为什么选择FLUX.1-dev FP8版本? 突破性的量化技术让中端显卡也能享受顶级AI绘画体验!通过智能分层量化策略,在保持核心功能精度的同时,实现了显著的性能提升。无论你是设计师、内容创作者还是AI爱好者,这款模型都能满足你的创作需求。 核心优势一览 * 显存需求降低60%:从16GB降至6GB * 兼容性全面提升:支持RTX 3060、4060等主流显卡 * 画质几乎无损:智能量化确保关键组件精度 * 部署简单快捷:完整教程带你从零开始 🛠️ 环境准备与项目获取 第一步

二次元AI绘画工具实战指南:从入门到进阶

本文面向想要使用AI工具生成二次元风格图像的开发者和创作者,从工具选择、环境配置、提示词工程到进阶技巧,提供一份完整的实战指南。 一、主流工具技术栈对比 目前二次元AI绘画主要有以下几种技术路线: 1.1 Stable Diffusion 本地部署 技术架构:基于Latent Diffusion Model,开源可本地运行 硬件要求: * GPU:NVIDIA显卡,8GB+显存(推荐12GB+) * 内存:16GB+ * 存储:50GB+(模型文件较大) 常用界面: * WebUI(AUTOMATIC1111):功能全面,插件生态丰富 * ComfyUI:节点式工作流,适合复杂流程编排 二次元常用模型: * Anything系列:经典二次元模型 * Counterfeit:高质量动漫风格 * MeinaMix:细节丰富的二次元模型 优势:可高度定制,隐私性好,技术上限高 劣势:配置门槛高,

基于腾讯云云服务器搭建一个Clawdbot,实现Telegram机器人自动回复

基于腾讯云云服务器搭建一个Clawdbot,实现Telegram机器人自动回复

哈咯大家好,这里依然是码农的搬运工!! 从25年开始,全球都开始走向AI,拥抱AI。 最近博主,也就是我,发现一个国外作者,【Peter Steinberger】在本月推出了一个新的智能体【Clawdbot】,首先我们可以先去官网看一下这个东西是什么:Clawdbot  那么我也是研究了一把,但是这个文档实在是差点把我这个大专生劝退,纯英文,废了九牛二虎之力,我才差不多看懂了。肯定有小伙伴比较好奇,那么文档给你们放出来你们也可以看看:https://docs.molt.bot/start/getting-started OK!话不多说,那我们开始实操一下: 首先呢,看了一下这个文档,安装环境还是不错的,macOS/Linux、Windows【Powershell/CMD】 而且作者还贴心的给了安装命令,这样就省了好大一部分精力。不需要费劲去git拉取代码编译了。【这里需要注意一点,macos系统得14+,作者只有13的系统,所以是没有办法弄mac的】 当然,如果有小伙伴就是头铁,还是想从git上拉代码,那我也给你贴一下这个文档,你来安装: