Revit & MCP розуміє LLM+Revit 2 через приклади: Реалізуйте кілька ланцюжків думок

Office-Montreal-6095-crop-2.jpg

Ця стаття написана та опублікована китайською мовою та є перекладеною версією оригіналу тут.

 

Схема

У попередній статті було представлено технічний шлях та кейси впровадження MCP, а в цій статті ми розглянемо, як покращити кейс під час кількох раундів ланцюжків мислення. Все ще беручи за приклад стіну, цього разу я не хочу, щоб користувачі брали участь у взаємодії, намагайтеся, щоб комп'ютер завершив розрахунок автоматично. Вимогу було змінено зі "Створити стіну -> Користувач вибирає стіну -> Вставити двері та вікна у випадкових місцях" на: LLM автоматично обчислює координати стіни та вставляє різні форми на кожну стіну. Наступна частина буде зосереджений на швидкій модифікації та коригуванні коду під кількома раундами ланцюжка думок.

 

Корпус розкладається

Сторінка на Github[https://github.com/imkcrevit/RevitMCP_Blog/tree/main]

 

Оперативне

Код цього проекту практично не змінився, в основному оптимізували метод опису, щоб LLM міг розуміти і точно викликати запуск інструменту. Наступний контент в основному вводить логічне налаштування при модифікації простого випадку до формату з декількома ланцюжками думок.

 

Кроки (промпти)

  • Спочатку протестуйте в MCP.Client, введіть абзац і подивіться, чи може LLM аналізувати кілька інструментів:
Створіть набір стін, лінія позиціонування стіни повинна бути замкнутою графікою і не менше трьох, мінімальна довжина - 10000 мм, висота стіни - 3000  за замовчуванням, а потім вікно вставляється у вікно у випадковому положенні стіни після створення стіни, і координати вікна кожної стіни несумісні, і вимога не може перевищувати висоту стіни.

Ви можете бачити, що на виході є два інструменти, що доводить, що опис може бути правильно проаналізовано LLM і призначено різним інструментам.

 

Pasted image 20250716140947.png

 

  • Продовжуючи тест, наведений вище запит не дає чіткого визначення «набору стін», через що LLM розпізнає його як стіну, яка не відповідає очікуванням. Після зміни підказки було додано не менше трьох обмежень, дивіться скріншот нижче:
Створіть набір стін, лінія позиціонування стіни повинна бути закритою графікою і не менше трьох, мінімальна довжина - 10000 мм, висота стіни - 3000 за замовчуванням, а потім вставте вікно у випадкове положення стіни після створення стіни, і координати вікна кожної стіни несумісні, і вимога не може перевищувати висоту стіни.

 

LLM створила три набори стін, доводячи, що попереднє «один набір дорівнює одній стіні» було викликано неточними описами.

LLM генерує три набори стін, а інструменти стають списком з трьох предметів.

 

Pasted image 20250716142841.png

 

У цей час ми стикаємося з проблемою, як точно вставити двері та вікна в зазначену стіну, а оскільки ми не можемо вчасно отримати створений ID стіни, ми можемо лише замінити його номерами.

 

Pasted image 20250716142932.png

 

  • Оскільки ID не можна передати, це цілий ланцюжок думок, який не передбачає очікування завершення створення або вибору користувача. Варіанти такі:
    • Додайте унікальний ID на основі формату GUID як унікальний ідентифікатор і передайте в комбінації форм як основу host (хоста) (цей проект використовує цю схему)
    • Після кожного створення ID компонента повертається та замінюється наступним інструментом Chain of Thought Binding Tool (Інструмент зв'язування ланцюга думок) як джерелом даних.

Змініть запит, щоб акцентувати увагу на генерації унікального ідентифікатора та його передачі:

Створіть набір стін, лінія позиціонування стіни повинна бути закритою графікою і не менше трьох, і мати унікальний ідентифікатор, формат GUID, прийміть його як ID, мінімальна довжина становить 10000 мм, висота стіни за замовчуванням 3000, а потім вставте вікно у випадкове положення стіни після створення стіни, координати вікна кожної стіни несумісні, і вимога не може перевищувати висоту стіни, точно зрозумійте мій намір і розділіть його, щоб викликати функцію по черзі у відповідному порядку

Наразі eId у згенерованих даних не змінився, що вказує на те, що LLM не розуміє наміру. Потрібно змінити Tool Description (опис інструменту) на Server (сервері) і налаштувати параметри системи так, щоб він знав, що унікальний ідентифікатор знаходиться в форматі GUID.

 

На стороні Server змініть опис Create так, щоб LLM чітко проходив у UniqueId під час обходу Tool (інструменту):

[McpServerTool(Name = "CreateWall"), 
Description("Generation Paramaters That Can Create Wall in Revit , 
If User Want To Generation eId ,
 You Need To Generation a unique id base this :0B7FB9A8-DAD8-48CE-9D41-5EDB63832BD2 ")]

 

Зі сторони System (Системи) також наголошується на визначенні унікального ідентифікатора:

"""you are a professional enginer in BIM ,
 so you can select the greate tool to user ,
 also has a good develop tech in code , 
and generation a standard input style And Arguments to tools , 
also if some question need unique id you will generate a unique eId in this talk , 
the example :0B7FB9A8-DAD8-48CE-9D41-5EDB63832BD2"""

 

Кінцевим результатом виведення все ще є eId = 2, оскільки формат вхідного параметра методу - int, і LLM виведе uniqueId як формат int на основі параметрів, а тип параметру методу потрібно змінити:

public string RevitCreateWallTool(string command, double x, double y, double z, double x1, double y2, string uniqueId) { 
return $@" {{ 
""command"": ""CreateWall"", 
""arguments"": {{ ""start"": [{x}, {y}, {z}], 
""end"": [{x1}, {y2}, {z}], ""eId"": ""{uniqueId}"" }} }}"; 
}

 

Повторно перевірте вхідний оператор і виявите, що ідентифікатор було точно призначено, але стіна, створена LLM, не закрита, що призводить до аномальних даних. LLM ще не зрілі в 2D-продуктивності і не можуть імітувати 2D або 3D графіку, як люди. Ви можете додати детальний опис до вхідних даних.

 

Pasted image 20250716154005.png

 

  • Додано обмеження визначення замикання (перетин від кінця до кінця) і результат відповідав вимогам.
  • Додається відповідність між формою та стіною, а математична мова та точки проекції координат знаходяться на відрізку лінії стіни для забезпечення точного розрахунку.
  • Оптимізований рядок виглядає наступним чином:
Стіна відповідає вікну, і має унікальний ідентифікатор ідентифікатора в форматі: eId = 0B7FB9A8-DAD8-48CE-9D41-5EDB63832BD2, дані генеруються строго по цьому формату і не можуть повторюватися, створіть групу стін, лінія позиціонування стіни повинна бути замкнутою фігурою, координатні лінії з'єднані між собою прямою лінією, перша відповідає останній і не менше трьох, мінімальна довжина - 10000мм, а висота стіни - 3000 за замовчуванням, Після створення стіни вікно вставляється у вікно у випадковому положенні стіни, точка розташування вікна повинна бути на генерованій лінії позиціонування стіни, формула розрахунку така: точка проекції форми повинна бути на відрізку лінії, з'єднаному кінцем стіни, кожна стіна відповідає вікну, її потрібно обчислити окремо, координати вікна кожної стіни непостійні, вимога не може перевищувати висоту стіни, точно зрозуміти мій намір і розрахувати в суворій відповідності з вимогами, і розділити функцію по черзі відповідно до відповідного порядку

 

Приклад виводу:

Sample output:

    [
         {
              "command": "CreateWall",
              "arguments": {
                    "start": [0, 0, 0],
                    "end": [10000, 0, 0],
                    "eId": "0B7FB9A8-DAD8-48CE-9D41-5EDB63832BD2"
              }
         },
         {
              "command": "CreateWall",
              "arguments": {
                    "start": [10000, 0, 0],
                    "end": [10000, 10000, 0],
                    "eId": "1A2B3C4D-5E6F-7G8H-9I10-11K12L13M14N"
              }
         },
         {
              "command": "CreateWall",
              "arguments": {
                    "start": [10000, 10000, 0],
                    "end": [0, 10000, 0],
                    "eId": "15O16P17Q-18R19S-20T21U-22V23W-24X25Y26Z"
              }
         },
         {
              "command": "CreateWall",
              "arguments": {
                    "start": [0, 10000, 0],
                    "end": [0, 0, 0],
                    "eId": "27A28B29C-30D31E-32F33G-34H35I-36J37K38L"
              }
         },
         {
              "command": "InsertWindowInWall",
              "arguments": {
                    "eId" : "0B7FB9A8-DAD8-48CE-9D41-5EDB63832BD2",
                    "location": [5000,0,1500]
              }
         },
         {
              "command": "InsertWindowInWall",
              "arguments": {
                    "eId" : "1A2B3C4D-5E6F-7G8H-9I10-11K12L13M14N",
                    "location": [10000,5000,1500]
              }
         },
         {
              "command": "InsertWindowInWall",
              "arguments": {
                    "eId" : "15O16P17Q-18R19S-20T21U-22V23W-24X25Y26Z",
                    "location": [5000,10000,1500]
              }
         },
         {
              "command": "InsertWindowInWall",
              "arguments": {
                    "eId" : "27A28B29C-30D31E-32F33G-34H35I-36J37K38L",
                    "location": [0,5000,1500]
              }
         }
    ]

 

 

Демонстрація

 

Висновок

Коли кількість стін збільшується до п'яти, виникає помилка, і вона визначається лише наскрізно, а LLM все одно не дуже кмітливий при обробці 2D даних. Такі сценарії, які необхідно створювати безперервно в Revit, особливо коли це пов'язано з 2D/3D просторовими відносинами, продуктивність LLM обмежена. Точність можна підвищити за допомогою оптимізації підказок (промптів), і LLM можуть працювати краще після оптимізації в майбутньому. Приклади показують, що логічний огляд може бути використаний для досягнення більшої кількості додатків за допомогою MCP, таких як визначення кількох умов специфікації та створення ідентичностей. Код був синхронізований з Github, ласкаво просимо до завантаження та розширення, стаття ж в основному доводить технічну можливість, а конкретну програму потрібно поєднувати з реальною роботою.

 

Pasted image 20250717103606.png

 

Ця стаття написана та опублікована китайською мовою та є перекладеною версією оригіналу тут.