删掉serena的提示词

This commit is contained in:
tian 2025-10-10 09:44:29 +08:00
parent 163986f9e5
commit 3cc840b183
2 changed files with 96 additions and 139 deletions

View File

@ -159,7 +159,8 @@
"Read(//c/Program Files/Autodesk/Navisworks Manage 2026/**)",
"Bash(where:*)",
"Read(//c/Users/Tellme/Pictures/Screenshots/**)",
"Bash(./deploy-plugin.bat)"
"Bash(./deploy-plugin.bat)",
"Read(//c/Users/Tellme/**)"
],
"deny": [],
"additionalDirectories": [

232
CLAUDE.md
View File

@ -42,6 +42,100 @@ The system implements multiple Navisworks plugin types working together:
- **GeometryExtractor.cs**: Spatial analysis and bounding box calculations
- **FloorDetector.cs**: Automatic floor/level detection for multi-story logistics
#### ⚠️ 模型单位系统 - 极其重要!
**核心原则网格地图生成和路径规划中统一使用模型单位Model Units不使用米制单位**
本项目中出现的大量bug都源于混淆模型单位和米制单位。必须严格遵守以下规则
**1. 单位转换原则**
```csharp
// ✅ 正确做法:在函数入口处一次性转换所有参数
public GridMap GenerateFromBIM(BoundingBox3D bounds, double cellSize, double vehicleRadius, ...)
{
// 第一步:立即转换所有米制参数为模型单位
double metersToModelUnitsConversionFactor = UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units);
double cellSizeInModelUnits = cellSize * metersToModelUnitsConversionFactor;
double vehicleRadiusInModelUnits = vehicleRadius * metersToModelUnitsConversionFactor;
double safetyMarginInModelUnits = safetyMargin * metersToModelUnitsConversionFactor;
double vehicleHeightInModelUnits = vehicleHeight * metersToModelUnitsConversionFactor;
// 之后所有计算都使用模型单位变量
var gridMap = new GridMap(bounds, cellSizeInModelUnits);
}
// ❌ 错误做法:在计算过程中混用米制和模型单位
```
**2. 网格地图内部统一使用模型单位**
GridMapGenerator和AutoPathFinder中的所有空间计算都基于模型单位
- 网格单元大小CellSize模型单位
- 车辆半径VehicleRadius模型单位
- 安全间隙SafetyMargin模型单位
- 车辆高度VehicleHeight模型单位
- 扫描高度ScanHeight模型单位
- 膨胀半径InflationRadius模型单位
- 高度差阈值MaxHeightDiff模型单位
- 网格坐标和世界坐标转换:模型单位
**3. 常见错误模式及避免方法**
```csharp
// ❌ 错误:直接使用常量米制值
private const double MAX_HEIGHT_DIFF = 0.35; // 这是米!
if (heightDiff > MAX_HEIGHT_DIFF) // BugheightDiff是模型单位
// ✅ 正确:转换后使用
private const double MAX_HEIGHT_DIFF_METERS = 0.35; // 明确标注单位
double maxHeightDiffInModelUnits = MAX_HEIGHT_DIFF_METERS * UnitsConverter.GetMetersToUnitsConversionFactor();
if (heightDiff > maxHeightDiffInModelUnits) // 正确!
// ❌ 错误:在循环中重复转换
for (int i = 0; i < count; i++) {
double modelValue = meterValue * UnitsConverter.GetMetersToUnitsConversionFactor(); // 性能浪费
}
// ✅ 正确:提前转换一次
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
double modelValue = meterValue * metersToModelUnits; // 转换一次
for (int i = 0; i < count; i++) {
// 使用modelValue进行计算
}
```
**4. 变量命名约定**
为了避免混淆,强制使用以下命名规范:
- 米制变量:使用`Meters`后缀,如`vehicleHeightMeters`、`cellSizeMeters`
- 模型单位变量:使用`InModelUnits`后缀,如`vehicleHeightInModelUnits`、`cellSizeInModelUnits`
- 转换系数:统一命名为`metersToModelUnitsConversionFactor`
**5. 关键API的单位约定**
```csharp
// Navisworks API返回的坐标和尺寸都是模型单位
BoundingBox3D bbox = modelItem.BoundingBox(); // 模型单位
Point3D worldPos = gridMap.GridToWorld3D(gridPos); // 模型单位
// 用户配置的参数通常是米制
double cellSize = 0.5; // 米,需要转换
double vehicleRadius = 0.3; // 米,需要转换
```
**6. 日志输出最佳实践**
```csharp
// ✅ 正确:在日志中明确标注单位
LogManager.Info($"网格大小: {cellSize}米 → {cellSizeInModelUnits:F2}模型单位");
LogManager.Info($"高度差阈值: {MAX_HEIGHT_DIFF_METERS}米 = {maxHeightDiffInModelUnits:F2}模型单位");
// ❌ 错误:日志中不标注单位,容易造成误解
LogManager.Info($"网格大小: {cellSize}");
```
**记住违反这些规则会导致路径规划失败、碰撞检测错误、网格生成异常等各种难以追踪的bug**
### UI Architecture: WPF + WinForms Hybrid
- **WPF Components**: Modern MVVM-based controls in `src\UI\WPF\`
@ -139,144 +233,6 @@ public class PathClickToolPlugin : ToolPlugin { }
- **Modern animation system**: Use Navisworks 2026 native animation components instead of manual Transform manipulation
- **Enhanced APIs**: Take advantage of improved 2026 APIs for collision detection, animation, and model management
### Serena MCP工具配置
- **Token限制策略**: 所有serena MCP工具调用必须使用`max_answer_chars: 3000`参数
- **适用工具**: 包括但不限于:
- `mcp__serena__search_for_pattern`
- `mcp__serena__find_symbol`
- `mcp__serena__get_symbols_overview`
- `mcp__serena__find_referencing_symbols`
- 所有其他支持`max_answer_chars`参数的serena工具
#### 查询最佳实践
**核心原则**: 分步定位 + 分段读取,避免一次性获取大量内容
##### ❌ 错误做法
```python
# 错误1: 对大方法使用 include_body=true
mcp__serena__find_symbol(
name_path="LargeMethod",
include_body=true, # ❌ 500行方法 → 20k+ 字符 → 必然失败
max_answer_chars=3000
)
# 错误2: 使用OR模式的宽泛搜索
mcp__serena__search_for_pattern(
substring_pattern="时间标签|TimeTag|预估.*时间|总时间", # ❌ 多个模式 → 178k+ 字符
output_mode="files_with_matches"
)
# 错误3: 使用通用词搜索
mcp__serena__search_for_pattern(
substring_pattern="Manager", # ❌ 匹配太多文件
output_mode="content"
)
# 错误4: 使用 depth=1 获取所有成员
mcp__serena__find_symbol(
name_path="LargeViewModel",
include_body=false,
depth=1, # ❌ 返回所有方法签名 → 5k+ 字符
max_answer_chars=3000
)
```
##### ✅ 正确做法
**步骤1: 精确定位文件**
```python
# 方式A: 搜索精确的类名或方法名(单一关键词)
mcp__serena__search_for_pattern(
substring_pattern="TimeTagViewModel", # ✅ 单一精确词不用OR模式
paths_include_glob="**/*ViewModel.cs", # ✅ 限定文件类型
output_mode="files_with_matches"
)
# 方式B: 符号查找定位不使用depth
mcp__serena__find_symbol(
name_path="TimeTagViewModel",
include_body=false, # ✅ 只获取类本身
depth=0, # ✅ 不获取成员,避免内容过多
max_answer_chars=3000
)
```
**步骤2: 搜索关键方法调用**
```python
# 找到关键API调用而不是搜索通用词
mcp__serena__search_for_pattern(
substring_pattern="CalculateTimeMarkers", # ✅ 搜索具体API名称
relative_path="src/UI/WPF/ViewModels/TimeTagViewModel.cs", # ✅ 限定文件
output_mode="content",
context_lines_before=2,
context_lines_after=2,
max_answer_chars=3000
)
```
**步骤3: 定位实现类**
```python
# 根据步骤2找到的服务类定位实现文件
mcp__serena__search_for_pattern(
substring_pattern="TimeMarkerCalculationService", # ✅ 精确类名
paths_include_glob="**/*.cs",
output_mode="files_with_matches"
)
```
**步骤4: 分段读取实现代码**
```python
# 使用Read工具分段获取
Read(
file_path="src/PathPlanning/TimeMarkerCalculationService.cs",
offset=97, # 从方法起始行
limit=80 # 读取关键逻辑部分
)
# 如需继续,读取下一段
Read(
file_path="...",
offset=185, # 继续往下
limit=20
)
```
##### 何时可以使用 include_body=true
- ✅ 小方法(<100行
- ✅ 属性定义
- ✅ 简单类结构
- ❌ 大型方法(>200行
- ❌ 复杂类定义
- ❌ 带有 `depth=1` 的大型类
##### 常见错误模式总结
| 错误模式 | 为什么失败 | 正确做法 |
|---------|-----------|---------|
| `substring_pattern="A\|B\|C"` | OR模式匹配过多 | 使用单一精确关键词 |
| `substring_pattern="总时间"` | 通用词匹配太广 | 搜索具体API名称 |
| `depth=1` + 大型类 | 返回所有成员签名 | 使用 `depth=0` 或直接搜索方法 |
| `include_body=true` + 大方法 | 方法体太长 | 先定位再用Read分段 |
| 不限定文件范围 | 搜索整个代码库 | 使用 `paths_include_glob``relative_path` |
##### 执行原则总结
1. **单一精确关键词** > OR模式或通用词
2. **限定搜索范围**: 始终使用 `paths_include_glob``relative_path`
3. **分步骤获取信息**: 定位 → 搜索调用 → 定位实现 → 分段读取
4. **避免使用depth**: 对于大型类,使用 `depth=0` 或直接搜索方法名
5. **先定位后读取**: 用 `output_mode="files_with_matches"` 定位,再用 `Read` 获取
6. **善用context参数**: 搜索时只需少量上下文2-3行
7. 如遇到3k限制使用更精确的搜索条件重新查询而非提高限制
## API Documentation Search Strategy
### CHM文档搜索最佳实践