最佳实践
本文汇总了场景开发的最佳实践,帮助您创建高质量、安全、易维护的场景。
提示词优化
DO ✅
- 使用清晰的角色定位,避免模糊描述
- 设置具体的输出格式要求
- 给出正反示例,帮助 AI 理解期望
- 使用分级指令(禁止/必须/建议)
- 控制提示词长度,避免过度消耗 token
DON'T ❌
- 不要使用矛盾的指令
- 不要在提示词中包含敏感信息(API Key 等)
- 不要假设 AI 了解所有外部知识
- 不要过度约束 AI 的创造力
权限声明
- 遵循最小权限原则,只声明实际需要的权限
- 避免声明
workspace:execute和system:shell等高危权限 - 在描述中说明每个权限的用途
- 定期审查权限是否仍然需要
工具设计
- 工具名称使用
snake_case命名,清晰描述功能 - 提供中文和英文描述
- 参数定义完整,包含类型、描述、枚举值
- 返回结构化的结果,而非纯文本
- 设置合理的超时时间
typescript
// ✅ 好的工具定义
{
name: 'search_products',
definition: {
name: 'search_products',
description: 'Search products by keyword',
descriptionZh: '按关键词搜索产品',
parameters: {
type: 'object',
properties: {
keyword: { type: 'string', description: 'Search keyword', descriptionZh: '搜索关键词' },
category: { type: 'string', description: 'Product category', descriptionZh: '产品分类', enum: ['electronics', 'clothing', 'food'] },
limit: { type: 'number', description: 'Max results', descriptionZh: '最大结果数', default: 10 },
},
required: ['keyword'],
},
},
}数据库设计
- 表名使用
snake_case - 始终包含主键
- 为常用查询字段创建索引
- 使用
IF NOT EXISTS避免重复创建 - 安装脚本和卸载脚本对称
错误处理
- 所有工具执行器捕获异常
- 返回有意义的错误信息
- 使用
context.logger记录错误日志 - 健康检查检测关键功能状态
typescript
executor: async (args, context) => {
try {
const result = await performOperation(args)
return { success: true, data: result }
} catch (error) {
context.logger.error('操作失败', error)
return {
success: false,
error: `操作失败: ${error instanceof Error ? error.message : '未知错误'}`,
}
}
}版本管理
- 遵循语义化版本(SemVer)
- 每次发布更新版本号
- 在 changelog 中说明变更内容
- 重大变更时更新
minAppVersion
测试
- 使用
dev命令进行本地测试 - 测试所有工具的正常和异常情况
- 测试权限不足时的行为
- 测试数据库操作的完整性
- 使用
validate命令检查构建产物
发布前检查
- [ ] 所有工具已测试通过
- [ ] 权限声明合理
- [ ] 提示词已优化
- [ ] 版本号已更新
- [ ] changelog 已准备
- [ ] 通过了
validate --strict校验 - [ ] 图标和描述已完善
性能优化
- 声明式场景优先于编程式(更轻量)
- 数据库查询使用索引
- 避免在激活脚本中执行耗时操作
- 合理使用共享依赖,减少包大小
- 自定义面板组件保持轻量
安全建议
- 不在提示词中硬编码 API Key
- 使用环境变量传递敏感配置
- 对用户输入进行校验
- 避免在工具中执行任意代码
- 数据库操作使用参数化查询
国际化
- 场景专属 key 放在场景
i18n/目录中,不污染全局 i18n 文件 - Key 命名使用
<scenario-id>.<feature>.<key>三段落格式 - 在
onActivate中注册翻译,onDeactivate中反注册 - 全局共享 key(如
statusBar.cancel)保留在全局 i18n 中
typescript
// ✅ 场景独立 i18n
import { registerScenarioI18n, unregisterScenarioI18n } from '@renderer/i18n'
onActivate: async (context) => {
registerScenarioI18n('my-scenario', { en, zh })
}
onDeactivate: async (context) => {
unregisterScenarioI18n('my-scenario')
}详见 场景国际化。
组件隔离
- 场景专属组件放在
scenarios/<name>/components/目录下 - 通过
@scenarios/<name>/...路径别名引用,避免相对路径 - 共享层组件(如
WorkspaceEditor)通过DynamicPanelView加载场景组件 - 场景专属设置使用
wideMode: true在主内容区展示,而非侧边栏
scenarios/<name>/
├── components/ # 场景专属组件
├── settings/ # 场景专属设置
├── i18n/ # 场景独立翻译
├── hooks/ # 场景专属 Hook
└── utils/ # 场景专属工具原则:能放场景目录的代码不放共享层,避免场景代码污染全局。

