删掉serena的提示词
This commit is contained in:
parent
163986f9e5
commit
3cc840b183
@ -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
232
CLAUDE.md
@ -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) // Bug!heightDiff是模型单位
|
||||
|
||||
// ✅ 正确:转换后使用
|
||||
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文档搜索最佳实践
|
||||
|
||||
Loading…
Reference in New Issue
Block a user