飞书AI Agent集成实战:larksuite/cli工具与26个预置Skills详解

📅 2026/7/21 2:45:07
飞书AI Agent集成实战:larksuite/cli工具与26个预置Skills详解
要让 AI Agent 真正融入飞书工作流光有基础 API 调用能力远远不够。实际项目中Agent 需要理解飞书的多维表格结构、处理日历事件冲突、按权限发送消息、管理文档版本这些复杂操作如果每个都从零调用 OpenAPI不仅开发效率低错误处理也更复杂。飞书官方推出的 larksuite/cli 工具正是为解决这个问题而生。它不只是传统命令行工具而是专门为 AI Agent 设计的技能库包含 26 个预置 Skill覆盖消息、文档、日历、任务等 18 个核心业务域。当你的 Agent 集成了这些 Skill就相当于获得了飞书原生的操作能力无需再手动处理认证、参数组装和错误重试。本文面向正在开发飞书集成 Agent 的工程师将带你完成从环境准备到生产部署的全流程。通过具体的代码示例和排错案例你会掌握如何让 Agent 安全、高效地操作飞书资源并了解在实际项目中容易遇到的权限、限流和数据一致性问题的解决方案。1. 理解 larksuite/cli 的三层架构设计传统飞书集成方案通常直接调用 OpenAPI但这种方式对 AI Agent 来说存在几个明显问题参数结构复杂、错误处理不统一、需要手动管理认证令牌。larksuite/cli 通过三层命令结构解决了这些问题让 Agent 可以用最适合的抽象层级进行操作。1.1 Shortcuts 层为 AI Agent 优化的高阶操作Shortcuts 是专门为人类和 AI Agent 设计的高阶命令以前缀标识。这类命令隐藏了底层 API 的复杂性提供智能默认值和表格式输出支持干运行预览。# 查看今日议程 lark-cli calendar agenda # 发送消息到指定群聊 lark-cli im messages-send --chat-id oc_xxx --text 项目周会将在10分钟后开始 # 创建Markdown文档 lark-cli docs create --doc-format markdown --content $# 项目周报\n## 本周进展\n- 完成了用户认证模块Shortcuts 的优势在于参数简洁输出格式友好。对于 AI Agent 来说不需要理解复杂的 API 参数结构只需要关注业务语义。每个 Shortcut 都经过真实 Agent 测试确保提示词到执行的转换成功率。1.2 API Commands 层与平台同步的标准操作API Commands 是从飞书 OpenAPI 元数据自动生成的经过质量门控筛选提供 100 与平台端点 1:1 映射的命令。这一层适合需要精确控制 API 调用的场景。# 列出所有日历 lark-cli calendar calendars list # 获取特定时间范围内的事件实例视图 lark-cli calendar events instance_view --params { calendar_id: primary, start_time: 1700000000, end_time: 1700086400 }这一层的命令参数与官方 API 文档完全一致适合已经从飞书文档熟悉了 API 结构的开发者使用。输出为结构化 JSON便于程序化处理。1.3 Raw API 层全覆盖的底层调用当预置命令无法满足特殊需求时可以直接调用任意飞书 Open Platform 端点覆盖 2500 APIs。# 直接调用日历API lark-cli api GET /open-apis/calendar/v4/calendars # 直接发送消息 lark-cli api POST /open-apis/im/v1/messages \ --params {receive_id_type:chat_id} \ --data { receive_id: oc_xxx, msg_type: text, content: {\text\:\Hello\} }Raw API 层提供了最大的灵活性但需要开发者对飞书 API 有深入了解。在生产环境中建议优先使用 Shortcuts 和 API Commands只有在必要时才使用 Raw API。1.4 输出格式选择与错误处理larksuite/cli 提供多种输出格式适应不同使用场景# JSON格式适合程序处理 lark-cli calendar agenda --format json # 人性化格式适合命令行查看 lark-cli calendar agenda --format pretty # 表格格式适合数据展示 lark-cli calendar agenda --format table # NDJSON格式适合流水线处理 lark-cli calendar agenda --format ndjson # CSV格式适合导入电子表格 lark-cli calendar agenda --format csv错误处理采用明确的契约模式。成功响应输出到 stdout退出码为 0{ ok: true, identity: user, data: { guid: ... }, meta: { count: 1 } }错误响应输出到 stderr退出码非零{ ok: false, identity: user, error: { type: api, subtype: ..., code: 99991679, message: 无权限访问该资源, hint: 请检查应用权限配置 } }这种设计让 AI Agent 可以很容易地判断操作是否成功而不需要解析复杂的 HTTP 状态码和错误消息格式。2. 环境准备与依赖配置要让 larksuite/cli 正常工作需要先完成飞书应用创建、权限配置和本地环境初始化。这个过程中最容易出错的是权限范围选择和认证流程下面会详细说明每个步骤的注意事项。2.1 飞书应用创建与权限配置首先在飞书开放平台创建应用这一步需要明确应用类型和权限范围访问飞书开放平台登录 开发者后台 选择创建应用选择应用类型根据使用场景选择企业自建应用或商店应用配置权限范围这是最关键的一步权限过少会导致功能受限过多可能带来安全风险以下是常见场景的权限配置建议使用场景必需权限可选权限风险等级消息通知机器人im:message、im:chatim:message:readonly低日历管理助手calendar:calendar、calendar:eventcalendar:setting中文档协作Agentdrive:drive、docs:docsdrive:comment中全面办公助理上述所有权限contact:user、mail:mail高对于 AI Agent 场景建议采用最小权限原则按需开启。特别是生产环境不要一次性授予所有权限。2.2 本地环境安装与初始化larksuite/cli 支持多种安装方式推荐使用 npm 安装以获得自动更新# 使用npm安装最新版本 npx larksuite/clilatest install # 验证安装是否成功 lark-cli --version如果从源码构建需要先准备构建环境# 确保已安装 Go 1.23 和 Python 3 git clone https://github.com/larksuite/cli.git cd cli make install # 安装 CLI Skill必需步骤 npx skills add larksuite/cli -y -g安装完成后进行初始化配置# 交互式配置应用凭证 lark-cli config init # 使用推荐权限登录自动选择常用范围 lark-cli auth login --recommendconfig init命令会引导你完成应用凭证配置包括 App ID、App Secret 等。如果是在 AI Agent 环境中使用可以添加--new参数让命令非阻塞运行# Agent模式输出授权URL后立即退出不等待用户操作 lark-cli config init --new2.3 认证流程详解与身份管理larksuite/cli 支持多种认证方式适应不同使用场景# 交互式登录TUI引导域名和权限选择 lark-cli auth login # 按域名过滤权限 lark-cli auth login --domain calendar,task # 使用推荐范围最安全的选择 lark-cli auth login --recommend # 指定精确权限范围 lark-cli auth login --scope calendar:calendar:read # Agent模式立即返回验证URL非阻塞 lark-cli auth login --domain calendar --no-wait # 使用设备码恢复登录适合断点续传 lark-cli auth login --device-code DEVICE_CODE身份管理是另一个重要功能允许在不同身份间切换# 以用户身份执行命令 lark-cli calendar agenda --as user # 以机器人身份发送消息 lark-cli im messages-send --as bot --chat-id oc_xxx --text 系统通知 # 检查当前登录状态 lark-cli auth status # 验证特定权限是否已授予 lark-cli auth check --scope calendar:calendar:read2.4 多环境配置管理在实际项目中通常需要区分开发、测试和生产环境。larksuite/cli 支持通过环境变量管理多套配置# 设置环境变量指定配置路径 export LARK_CLI_CONFIG_PATH~/.lark-cli/config-prod.json # 或者使用命令行参数指定配置文件 lark-cli --config ~/.lark-cli/config-dev.json calendar agenda建议为每个环境创建独立的应用避免权限混淆。以下是一个典型的多环境配置结构~/.lark-cli/ ├── config-dev.json # 开发环境配置 ├── config-test.json # 测试环境配置 ├── config-prod.json # 生产环境配置 └── credentials/ # 认证令牌存储 ├── dev-user.token ├── test-user.token └── prod-bot.token3. AI Agent Skills 集成实战larksuite/cli 的核心价值在于其预置的 26 个 AI Agent Skills。这些 Skills 不是简单的 API 封装而是经过专门优化的工作流让 Agent 能够以更自然的方式操作飞书资源。3.1 核心 Skills 功能详解每个 Skill 都针对特定业务场景进行了优化下面介绍几个最常用的 Skillslark-im消息管理 Skill# 发送文本消息 lark-cli im messages-send --chat-id oc_xxx --text 会议提醒 # 发送富文本消息 lark-cli im messages-send --chat-id oc_xxx --content { text: 请查看at user_id\\ou_xxx\\张三/at提交的at message_id\\om_xxx\\文档/at } # 上传并发送图片 lark-cli im messages-send --chat-id oc_xxx --image-path ./screenshot.png # 搜索消息历史 lark-cli im messages-search --query 项目周报 --time-range 7dlark-calendar日历管理 Skill# 查看今日议程 lark-cli calendar agenda # 创建会议事件 lark-cli calendar events-create \ --summary 项目评审会 \ --start-time 2024-01-15T14:00:0008:00 \ --end-time 2024-01-15T15:00:0008:00 \ --attendees user1company.com,user2company.com # 查询空闲时间 lark-cli calendar freebusy-list \ --user-ids ou_xxx,ou_yyy \ --time-min 2024-01-15T09:00:0008:00 \ --time-max 2024-01-15T18:00:0008:00lark-base多维表格管理 Skill# 列出所有Base lark-cli base apps-list # 获取表格数据 lark-cli base records-list --app-token bascnxxx --table-id tblxxx # 新增记录 lark-cli base records-create --app-token bascnxxx --table-id tblxxx \ --records [{ fields: { 项目名称: API集成开发, 负责人: 张三, 状态: 进行中 } }]3.2 Skill 组合使用案例会议助手 Agent实际项目中单个 Skill 的能力有限组合多个 Skills 才能实现复杂的工作流。以下是一个会议助手 Agent 的完整示例#!/usr/bin/env python3 import subprocess import json from datetime import datetime, timedelta class MeetingAssistant: def __init__(self): self.check_auth() def check_auth(self): 检查认证状态 result subprocess.run( [lark-cli, auth, status, --format, json], capture_outputTrue, textTrue ) if result.returncode ! 0: raise Exception(认证失败请先运行 lark-cli auth login) def schedule_meeting(self, title, participants, duration_hours1): 安排会议并发送通知 # 查找最近的可用的时间 slot start_time self.find_available_slot(participants, duration_hours) # 创建日历事件 meeting_event self.create_calendar_event(title, start_time, duration_hours, participants) # 创建会议群聊 chat_id self.create_meeting_chat(title, participants) # 发送会议通知 self.send_meeting_notification(chat_id, meeting_event, participants) return meeting_event, chat_id def find_available_slot(self, participants, duration_hours): 查找参与者都有空的时间段 # 实现空闲时间查询逻辑 pass def create_calendar_event(self, title, start_time, duration_hours, participants): 创建日历事件 end_time start_time timedelta(hoursduration_hours) cmd [ lark-cli, calendar, events-create, --summary, title, --start-time, start_time.isoformat(), --end-time, end_time.isoformat(), --attendees, ,.join(participants), --format, json ] result subprocess.run(cmd, capture_outputTrue, textTrue) if result.returncode ! 0: raise Exception(f创建日历事件失败: {result.stderr}) return json.loads(result.stdout)[data] def create_meeting_chat(self, title, participants): 创建会议群聊 cmd [ lark-cli, im, chats-create, --name, f会议讨论{title}, --user-ids, ,.join(participants), --format, json ] result subprocess.run(cmd, capture_outputTrue, textTrue) if result.returncode ! 0: raise Exception(f创建群聊失败: {result.stderr}) return json.loads(result.stdout)[data][chat_id] def send_meeting_notification(self, chat_id, meeting_event, participants): 发送会议通知 message f会议安排通知 主题{meeting_event[summary]} 时间{meeting_event[start_time][date_time]} - {meeting_event[end_time][date_time]} 参与人{, .join(participants)} 会议链接{meeting_event[hangout_link] or 无} 请准时参加 cmd [ lark-cli, im, messages-send, --chat-id, chat_id, --text, message, --format, json ] result subprocess.run(cmd, capture_outputTrue, textTrue) if result.returncode ! 0: print(f发送通知失败: {result.stderr}) # 使用示例 if __name__ __main__: assistant MeetingAssistant() event, chat assistant.schedule_meeting( Q1项目规划会, [user1company.com, user2company.com] ) print(f会议已创建{event[id]}群聊{chat})3.3 自定义 Skill 开发当预置 Skills 无法满足特定需求时可以使用 lark-skill-maker 框架开发自定义 Skill# 创建新的 Skill 模板 lark-cli skill-maker skill-create --name my-custom-skill # 进入 Skill 目录 cd my-custom-skill # 安装依赖 npm install # 开发测试 npm run dev自定义 Skill 的基本结构my-custom-skill/ ├── package.json # Skill 元数据 ├── src/ │ ├── index.js # 主入口文件 │ ├── commands/ # 命令定义 │ └── affordances/ # 交互定义 ├── test/ # 测试用例 └── README.md # 使用文档一个简单的自定义命令示例// src/commands/hello-world.js module.exports { name: hello-world, description: 简单的问候命令, affordances: [ { type: cli-command, command: hello-world, parameters: [ { name: name, type: string, description: 问候的对象名称, required: true } ] } ], handler: async (context, parameters) { return { message: Hello, ${parameters.name}!, timestamp: new Date().toISOString() }; } };开发完成后可以本地测试并发布到 Skill 仓库供其他 Agent 使用。4. 生产环境部署与安全实践将 larksuite/cli 集成到生产环境 AI Agent 中时需要特别注意安全、监控和错误处理。以下是经过实际项目验证的最佳实践。4.1 安全配置与权限管理最小权限原则实施# 生产环境只授予必要权限 lark-cli auth login --scope im:message,calendar:event:readonly # 定期检查权限使用情况 lark-cli auth scopes --used # 撤销不必要的权限 lark-cli auth logout --scope drive:drive敏感信息保护永远不要将 App Secret 硬编码在代码中使用环境变量或密钥管理服务存储凭证定期轮换认证令牌# 正确的凭证管理方式 import os from typing import Optional class SecureConfig: def __init__(self): self.app_id os.getenv(LARK_APP_ID) self.app_secret os.getenv(LARK_APP_SECRET) self.config_path os.getenv(LARK_CONFIG_PATH, ~/.lark-cli/config.json) def validate(self) - bool: 验证配置完整性 if not all([self.app_id, self.app_secret]): return False return True # 错误示例硬编码敏感信息 class InsecureConfig: def __init__(self): self.app_id cli_xxxxxx # 严禁这样做 self.app_secret xxxxxx # 严禁这样做4.2 错误处理与重试机制飞书 API 有调用频率限制完善的错误处理机制至关重要import time import logging from typing import Callable, Any class RateLimitAwareClient: def __init__(self, max_retries: int 3, base_delay: float 1.0): self.max_retries max_retries self.base_delay base_delay self.logger logging.getLogger(__name__) def execute_with_retry(self, command: list, operation_name: str) - dict: 带重试的命令执行 for attempt in range(self.max_retries 1): try: result subprocess.run( command, capture_outputTrue, textTrue, timeout30 ) if result.returncode 0: return json.loads(result.stdout) error_data json.loads(result.stderr) # 处理速率限制错误 if self._is_rate_limit_error(error_data): wait_time self.base_delay * (2 ** attempt) self.logger.warning(f速率限制等待 {wait_time}秒后重试) time.sleep(wait_time) continue # 处理认证错误不重试 if self._is_auth_error(error_data): self.logger.error(认证失败需要重新登录) raise AuthenticationError(认证已过期) # 其他错误直接抛出 raise CommandExecutionError(error_data[error][message]) except subprocess.TimeoutExpired: self.logger.warning(f命令执行超时第{attempt1}次重试) if attempt self.max_retries: raise TimeoutError(命令执行超时) except json.JSONDecodeError as e: self.logger.error(f响应解析失败: {e}) raise raise MaxRetriesExceededError(f操作{operation_name}重试{self.max_retries}次后失败) def _is_rate_limit_error(self, error_data: dict) - bool: 判断是否为速率限制错误 return error_data.get(error, {}).get(code) in [99991400, 99991401] def _is_auth_error(self, error_data: dict) - bool: 判断是否为认证错误 return error_data.get(error, {}).get(code) in [99991663, 99991664] # 使用示例 client RateLimitAwareClient() try: result client.execute_with_retry( [lark-cli, im, messages-send, --chat-id, oc_xxx, --text, test], 发送消息 ) print(操作成功) except (AuthenticationError, CommandExecutionError) as e: print(f操作失败: {e})4.3 监控与日志记录生产环境需要完善的监控体系来跟踪 Agent 行为import logging from datetime import datetime from dataclasses import dataclass from typing import Dict, Any dataclass class OperationMetrics: operation: str start_time: datetime end_time: datetime None success: bool False error_message: str None retry_count: int 0 property def duration_ms(self) - float: if self.end_time: return (self.end_time - self.start_time).total_seconds() * 1000 return 0 class MonitoringMiddleware: def __init__(self): self.logger logging.getLogger(lark-cli.monitoring) self.metrics: Dict[str, OperationMetrics] {} def start_operation(self, operation: str) - str: 开始记录操作指标 operation_id f{operation}_{datetime.now().strftime(%Y%m%d_%H%M%S_%f)} self.metrics[operation_id] OperationMetrics( operationoperation, start_timedatetime.now() ) return operation_id def end_operation(self, operation_id: str, success: bool, error_message: str None): 结束操作记录 if operation_id in self.metrics: self.metrics[operation_id].end_time datetime.now() self.metrics[operation_id].success success self.metrics[operation_id].error_message error_message metrics self.metrics[operation_id] if success: self.logger.info( f操作完成: {metrics.operation}, f耗时: {metrics.duration_ms:.2f}ms ) else: self.logger.error( f操作失败: {metrics.operation}, f错误: {error_message}, f耗时: {metrics.duration_ms:.2f}ms ) def get_metrics_report(self) - Dict[str, Any]: 生成监控报告 successful_ops [m for m in self.metrics.values() if m.success] failed_ops [m for m in self.metrics.values() if not m.success] avg_duration ( sum(m.duration_ms for m in successful_ops) / len(successful_ops) if successful_ops else 0 ) return { total_operations: len(self.metrics), successful_operations: len(successful_ops), failed_operations: len(failed_ops), success_rate: len(successful_ops) / len(self.metrics) if self.metrics else 0, average_duration_ms: avg_duration, recent_errors: [{ operation: op.operation, error: op.error_message, timestamp: op.start_time.isoformat() } for op in failed_ops[-10:]] # 最近10个错误 }4.4 性能优化与批量操作对于需要处理大量数据的场景使用批量操作和异步处理可以显著提升性能import asyncio from concurrent.futures import ThreadPoolExecutor from typing import List, Coroutine class BatchProcessor: def __init__(self, max_workers: int 5): self.max_workers max_workers self.executor ThreadPoolExecutor(max_workersmax_workers) async def process_batch(self, operations: List[dict]) - List[dict]: 批量处理操作 loop asyncio.get_event_loop() # 将同步命令转换为异步任务 tasks [ loop.run_in_executor( self.executor, self._execute_single_operation, operation ) for operation in operations ] # 并发执行但控制并发数量避免触发限流 results [] for i in range(0, len(tasks), self.max_workers): batch_tasks tasks[i:i self.max_workers] batch_results await asyncio.gather(*batch_tasks, return_exceptionsTrue) results.extend(batch_results) # 批次间延迟避免触发速率限制 if i self.max_workers len(tasks): await asyncio.sleep(1) return results def _execute_single_operation(self, operation: dict) - dict: 执行单个操作同步 try: result subprocess.run( operation[command], capture_outputTrue, textTrue, timeoutoperation.get(timeout, 30) ) return { operation_id: operation[id], success: result.returncode 0, output: result.stdout if result.returncode 0 else result.stderr, error: None if result.returncode 0 else result.stderr } except Exception as e: return { operation_id: operation[id], success: False, output: None, error: str(e) } # 使用示例 async def main(): processor BatchProcessor(max_workers3) operations [ { id: msg_1, command: [lark-cli, im, messages-send, --chat-id, oc_xxx, --text, 通知1] }, { id: msg_2, command: [lark-cli, im, messages-send, --chat-id, oc_xxx, --text, 通知2] } # ... 更多操作 ] results await processor.process_batch(operations) success_count sum(1 for r in results if r[success]) print(f批量操作完成: {success_count}/{len(operations)} 成功) # 运行批量处理 asyncio.run(main())5. 常见问题排查与解决方案在实际使用 larksuite/cli 过程中会遇到各种问题。下面列出最常见的问题及其解决方案。5.1 认证与权限问题问题1认证令牌过期现象操作返回99991663或99991664错误码原因访问令牌已过期默认2小时解决方案配置自动令牌刷新或实现重认证逻辑class TokenManager: def __init__(self, config_path: str): self.config_path config_path self.last_refresh datetime.now() def ensure_valid_token(self): 确保令牌有效 if (datetime.now() - self.last_refresh).total_seconds() 7000: # 接近2小时 self.refresh_token() def refresh_token(self): 刷新访问令牌 try: subprocess.run([ lark-cli, auth, refresh, --config, self.config_path ], checkTrue, capture_outputTrue) self.last_refresh datetime.now() print(令牌刷新成功) except subprocess.CalledProcessError as e: print(f令牌刷新失败: {e.stderr}) # fallback 到重新登录 self.full_login()问题2权限不足现象操作返回99991679错误码原因应用缺少必要权限解决方案检查并补充权限# 检查当前已授权限 lark-cli auth status --format json | jq .data.scopes # 检查操作需要的权限 lark-cli schema im.messages.send --format json | jq .required_scopes # 补充权限需要用户重新授权 lark-cli auth login --scope im:message,im:chat5.2 速率限制与性能问题问题3触发速率限制现象操作返回99991400或99991401错误码原因短时间内API调用过于频繁解决方案实现指数退避重试机制class RateLimitHandler: staticmethod def calculate_backoff(attempt: int, max_delay: int 60) - float: 计算退避时间 delay min(max_delay, (2 ** attempt) random.uniform(0, 1)) return delay staticmethod def is_rate_limit_error(error_data: dict) - bool: 判断是否为速率限制错误 rate_limit_codes {99991400, 99991401, 99991402} return error_data.get(error, {}).get(code) in rate_limit_codes问题4批量操作性能瓶颈现象处理大量数据时速度很慢原因顺序执行API调用解决方案使用并发处理但注意控制并发数async def optimized_batch_process(operations: List[dict], concurrency: int 3): 优化的批量处理 semaphore asyncio.Semaphore(concurrency) async def process_with_limit(operation): async with semaphore: return await process_single_operation(operation) tasks [process_with_limit(op) for op in operations] return await asyncio.gather(*tasks, return_exceptionsTrue)5.3 数据一致性与错误处理问题5部分操作失败现象批量操作中部分成功部分失败原因网络波动或数据验证错误解决方案实现原子性操作或补偿机制class TransactionalProcessor: def __init__(self): self.pending_operations [] def add_operation(self, operation: dict): 添加待处理操作 self.pending_operations.append(operation) async def commit(self) - dict: 提交所有操作保证原子性 results [] successful_ops [] try: for i, operation in enumerate(self.pending_operations): result await self.execute_operation(operation) results.append(result) if result[success]: successful_ops.append(operation) else: # 遇到失败回滚已成功操作 await self.rollback(successful_ops) return { success: False, error: f操作失败于第{i1}步, detailed_results: results } return {success: True, results: results} except Exception as e: await self.rollback(successful_ops) return {success: False, error: str(e)} async def rollback(self, operations: List[dict]): 回滚已成功操作 for operation in reversed(operations): if rollback_command in operation: await self.execute_operation(operation[rollback_command])5.4 调试与日志分析问题6操作结果不符合预期现象命令执行成功但业务效果不对原因参数理解错误或业务逻辑问题解决方案启用详细日志和干运行模式# 启用调试日志 export LARK_CLI_LOG_LEVELdebug # 使用干运行模式预览操作 lark-cli im messages-send --chat-id oc_xxx --text test --dry-run # 查看详细的API请求响应 lark-cli im messages-send --chat-id oc_xxx --text test --verbose问题7复杂的错误诊断现象错误信息不明确难以定位根本原因解决方案实现分层错误诊断class DiagnosticHelper: staticmethod def diagnose_error(error_data: dict, command: list) - str: 错误诊断助手 error_code error_data.get(error, {}).get(code) diagnosis { 99991663: 访问令牌过期需要重新认证, 99991664: 刷新令牌过期需要完整重新登录, 99991679: 权限不足检查应用权限配置, 99991400: 触发速率限制需要降低调用频率, 99991401: 并发请求过多减少并发数, } base_message diagnosis.get(error_code, 未知错误请查看详细错误信息) # 根据具体命令提供针对性建议 if im in command and error_code 99991679: base_message 。需要 im:message 权限 elif calendar in command and error_code 99991679: base_message 。需要 calendar:event 权限 return base_message通过系统化的错误处理和监控可以大幅提升 AI Agent 在使用 larksuite/cli 时的稳定性和可靠性。实际项目中建议将