360 Secure SkillHub
360 安全技能中心

Revit Command Template

核心功能是按平台规范创建可被AI调用的Revit命令插件,涵盖项目结构搭建、代码编写(含框架协议、[Command]属性配置、InputParams参数类)、编译部署全流程。典型场景为设计师需实现AI可操控的Revit自动化操作。输入为用户的命令需求,输出为标准化项目代码结构、示例代码及部署指引,需依赖Revit 2019-2025与VS/Rider环境。

ryanchan720
ryanchan720
热度 24.53
最近更新 2026-06-02 15:59:51
分类:开发依赖:纯提示词应用场景:代码生成 / API 集成

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add copilot-for-design-revit-command
Metadata
name
copilot-for-design-revit-command
description
Create Revit command plugins for the Copilot for Design platform. When a user asks to build a Revit command that can be called by an AI agent, follow this guide. Covers project structure, [Command] and [CommandInput] attributes, InputParams class conventions, framework protocol code, and deployment. Do not remove or rename framework-protocol code.

Copilot for Design — Revit 命令开发

Copilot for Design 是一个让设计师在 Revit 中通过对话操控模型和数据的 AI 平台。 本 Skill 指导你创建一个符合平台标准的 Revit 命令插件。

前置条件:Revit 2019-2025、Visual Studio 或 Rider。


项目结构

为用户的每个需求创建独立目录:

MyAddin/
├── MyCommand.cs              # 命令逻辑(一个文件对应一个命令)
├── MyCommand.csproj          # 项目配置
├── Properties/
│   └── AssemblyInfo.cs       # 插件元数据(名称、版本、语言、作者)
└── README.md

将 MyAddin 替换为插件名,MyCommand 替换为汉语拼音或英文命令名(加 Command 后缀)。


第一步:Properties/AssemblyInfo.cs

写入以下内容,根据用户需求填写实际值:

using System.Reflection;
using System.Runtime.InteropServices;
using SharedLibrary;

[assembly: AssemblyTitle("插件名")]
[assembly: AssemblyDescription("一句话简介")]
[assembly: AssemblyCompany("作者或团队")]
[assembly: Plugin(
    RevitVersion = "支持的 Revit 版本,如 2020-2025",
    Language = "目标自然语言,如 中文、English",
    Author = "作者"
)]
[assembly: Guid("用 Visual Studio 生成一个 GUID")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

RevitVersion 语法:单版本 "2024" 或范围 "2020-2025"。


第二步:MyCommand.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <LangVersion>12</LangVersion>
    <Nullable>enable</Nullable>
    <RootNamespace>MyAddin</RootNamespace>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="RevitAPI">
      <HintPath>$(RevitAPIPath)\RevitAPI.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="RevitAPIUI">
      <HintPath>$(RevitAPIPath)\RevitAPIUI.dll</HintPath>
      <Private>False</Private>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="CopilotForDesign.Contracts.Revit" Version="1.0.*" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
</Project>

<GenerateDocumentationFile>true</GenerateDocumentationFile> 必须保留——框架用它生成的 .xml 文件构建 JSON Schema。 <RootNamespace> 改为实际命名空间。


第三步:MyCommand.cs

标注"框架协议"的代码绝对不能删除或改名。

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SharedLibrary;

namespace MyAddin
{
    [Transaction(TransactionMode.Manual)]
    [Command(
        Title = "命令的中文名称",
        Description = "在 Revit 中执行什么操作",
        Trigger = "什么情况下该调用?AI 据此判断调用时机",
        Notes = "注意事项和坑点",
        ReturnDescription = "执行后返回什么",
        Discipline = "general",
        IsDestructive = false,
        Timeout = 20
    )]
    public class MyCommand : IExternalCommand
    {
        // ── 框架协议 ↓ ──
        [CommandInput(typeof(InputParams))]
        public JObject Parameters { get; set; } = new JObject();

        // ── 框架协议 ↓ 类名固定为 InputParams ──
        public class InputParams
        {
            /// <summary>字段说明</summary>
            public List<int> elem_ids { get; set; } = new();

            /// <summary>字段说明</summary>
            public string target_name { get; set; } = "";

            /// <summary>字段说明</summary>
            public int max_results { get; set; } = 200;
        }
        // ── 框架协议 ↑ ──

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            var doc = commandData.Application.ActiveUIDocument.Document;

            // ── 框架协议 ↓ ──
            var req = Parameters.ToObject<InputParams>();
            // ── 框架协议 ↑ ──

            var executeResult = "";
            var detailedMessage = "";

            try
            {
                // 业务逻辑。req 是强类型对象,有 IDE 智能提示。

                return Result.Succeeded;
            }
            catch (Exception ex)
            {
                detailedMessage = ex.Message;
                message = ex.Message;
                return Result.Failed;
            }
            finally
            {
                // ── 框架协议 ↓ ──
                var className = this.GetType().Name;
                AppEventHub.RaiseCommandCompleted(className, executeResult, detailedMessage);
                // ── 框架协议 ↑ ──
            }
        }
    }
}

[Command] 属性填写指南

根据用户需求填写。每个字段 AI 如何使用:

字段 必填 作用
Title 是 工具列表显示的中文名称
Description 是 功能描述
Trigger 是 关键——AI 据此判断调用时机。越具体越好
Notes 是 避坑指南。如"仅当前视图搜索"、"AND 逻辑"
ReturnDescription 是 返回值含义
Discipline 否 专业:general / architecture / structure / hvac / electrical / plumbing / interior
IsDestructive 否 是否修改模型,默认 false
Timeout 否 秒数。简单 5-10s,查询 20-60s,批量 ≥60s

InputParams 类指南

  • 类名固定 InputParams——框架按此名反射生成 JSON Schema。
  • 每个字段写 /// <summary>——自动变成 Schema 描述。
  • 有默认值 = optional,无默认值 = required。
  • C# 自动映射:string→string、int→integer、double→number、bool→boolean、List<T>→array、enum→枚举值。
  • 命令无入参:保留空类,写 /// <summary>无入参</summary>,[CommandInput] 属性不删。

禁止删除的代码

代码 删除后果
[Command(...)] AI 看不到此命令
[CommandInput(typeof(InputParams))] AI 不知道参数结构
public JObject Parameters { get; set; } 命令收不到参数
public class InputParams 无法生成 JSON Schema
Parameters.ToObject<InputParams>() Execute 拿不到值
AppEventHub.RaiseCommandCompleted(...) 调用方收不到结果

编译和部署

dotnet build -c Release

输出 MyAddin.dll + MyAddin.xml,放入:

%ProgramData%\RevitCopilot\RevitAddinPlatform\Addins\MyAddin\
├── MyAddin.dll
└── MyAddin.xml

启动 Revit,在 Copilot for Design 命令面板注册。


开发原则

  • 无界面:用传参代替弹窗
  • 无状态:每次调用独立,不依赖 static 变量
  • 单次交互:一次传入全部参数,一次返回完整结果

多命令

一个项目 = 一个命令。多个命令 = 多个 .csproj 项目,各自不同 RootNamespace。