TraceStudio-dev/docs/studio1.3/FUNCTION_NESTING_QUICKSTART.md
2026-01-09 21:37:02 +08:00

297 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 函数节点嵌套 - 快速开始指南
## 🎯 5分钟快速上手
### 第1步: 创建一个函数
1. 在画布上设计任何工作流(建议包含 InputNode 和 OutputNode
2. 在画布**空白处右键** → 选择 **"保存为函数"**
3. 输入函数名(英文,如: `my_first_function`
4. 输入显示名(中文,如: `我的第一个函数`
5. 点击确认 ✅
**完成!函数已保存到 `cloud/custom_nodes/functions/` 目录**
---
### 第2步: 使用函数节点
1. 在 NodePalette左侧中找到刚创建的函数节点
2. 拖拽到新的或现有的工作流中
3. 连接输入/输出端口
4. **本步完成**
---
### 第3步: 进入函数编辑
1. **双击**函数节点
2. 画布自动显示函数内部的工作流
3. 顶部会出现面包屑导航: **主工作流 / my_first_function (L1)**
4. 可以编辑、删除或添加节点
**你现在在函数内部!** 🎉
---
### 第4步: 返回主工作流
**3种方式选一种**:
#### 方式A: 点击面包屑的"返回"按钮
```
[← 返回] 主工作流 / my_first_function (L1)
```
#### 方式B: 点击面包屑的"主工作流"链接
```
[← 返回] [主工作流] / my_first_function (L1)
↑ 点击这里
```
#### 方式C: 按Ctrl+Z返回如果实现了快捷键
- 需要自定义扩展
---
### ✅ 就这么简单!
你现在已经掌握了函数嵌套的基本用法。
---
## 🚀 高级用法: 多层嵌套
### 场景: 函数套函数
```
主工作流
├─ InputNode (x1)
├─ 函数节点 A
│ ├─ InputNode
│ ├─ 函数节点 B ← 可以在这里再嵌套!
│ │ ├─ InputNode
│ │ ├─ 处理逻辑
│ │ └─ OutputNode
│ └─ OutputNode
└─ OutputNode
```
### 操作步骤
1. 进入函数A双击
2. 在函数A内创建一个函数B节点拖拽
3. 双击函数B节点进入
4. 面包屑显示: **主工作流 / 函数A / 函数B (L2)**
5. 编辑完成后,使用面包屑返回或跳转
### 支持的最大层级
- 理论无限制 (取决于内存和性能)
- 建议不超过 **5层** 以保证良好的用户体验
---
## 📋 命名规范
### 函数名称 (function_name)
- ✅ 使用英文字母、数字、下划线
- ✅ 以字母或下划线开头
- ❌ 不能有空格、中文、特殊符号
**示例**:
```
good_names: ✅
- extract_data
- process_csv_v2
- _private_function
- Transform123
bad_names: ❌
- Extract Data (有空格)
- 提取数据 (中文)
- function-name (有横杠)
- 123function (数字开头)
```
### 显示名称 (display_name)
- 可以使用中文、英文、特殊符号
- 在 NodePalette 中显示
- 在面包屑导航中显示
**示例**:
```
✅ 提取数据
✅ Extract Data
✅ 数据 → 转换 v2.0
✅ [高级] 复杂处理
```
---
## 🔍 常见问题
### Q1: 双击函数节点没有反应
**检查清单**:
- [ ] 确认是函数节点(不是 InputNode/OutputNode
- [ ] 打开浏览器控制台查看错误
- [ ] 确认后端服务运行: `curl http://127.0.0.1:8000/api/functions/list`
- [ ] 检查网络连接
**解决方案**:
```javascript
// 在浏览器控制台执行
fetch('http://127.0.0.1:8000/api/functions/list')
.then(r => r.json())
.then(d => console.log(d))
```
### Q2: 保存函数时提示"函数名称无效"
**原因**: 函数名称不符合命名规范
**正确做法**:
- ✅ 只用英文字母、数字、下划线
- ✅ 以字母或下划线开头
- ✅ 不含空格或特殊符号
**错误做法**:
- ❌ 中文名称
- ❌ 包含空格
- ❌ 包含横杠或其他符号
### Q3: 面包屑导航不显示
**原因**:
- 尚未进入任何函数 (functionStack 为空)
- 或者 BreadcrumbNav 组件被隐藏
**解决方案**:
1. 双击函数节点进入
2. 如果还是不显示,打开浏览器开发者工具的"元素检查器"
3. 搜索 "BreadcrumbNav" 或检查 z-index
### Q4: 返回上一层时工作流数据丢失
**原因**:
- 进入函数时未正确保存上一层级的状态
- 浏览器 localStorage 被清空
**解决方案**:
1. 重新加载页面(会从 localStorage 恢复)
2. 检查浏览器控制台是否有错误
3. 确认 Workspace 中的 useStore 调用正确
### Q5: 能否在函数内直接编辑,然后自动保存?
**当前行为**:
- 编辑自动保存到 localStorage
- 但**不会更新** 函数定义文件 (`.json`)
**计划改进** (Phase 3):
- 添加"保存函数"按钮
- 自动检测函数内部工作流的变化
- 版本控制和历史记录
### Q6: 支持撤销/重做吗?
**当前**:
- 基本的 undo/redo (由 zustand store 提供)
- 在函数内编辑支持历史记录
**改进方向**:
- 函数版本控制
- 编辑历史跟踪
- 比较功能
---
## 💡 最佳实践
### ✅ DO (推荐)
1. **按功能划分函数**
- 每个函数执行单一功能
- 使用清晰的命名
2. **编写输入/输出节点**
- 明确定义函数的输入参数
- 明确定义输出数据
- 便于重用
3. **测试函数**
- 创建函数后先测试单独使用
- 确认输入/输出正确
4. **文档函数**
- 使用 `display_name``description` 记录用途
- 后续搜索和使用更方便
5. **保持层级深度**
- 不超过 3-5 层为佳
- 过深导致难以理解和维护
### ❌ DON'T (避免)
1. ❌ 创建无用的函数
- 只有一个节点的函数
- 从未使用过的函数
2. ❌ 过度嵌套
- 函数A包含函数B包含函数C包含函数D...
- 难以理解数据流
3. ❌ 混淆输入/输出
- 函数没有清晰的 InputNode/OutputNode
- 导致数据流不清楚
4. ❌ 频繁更改已发布的函数
- 可能破坏依赖该函数的工作流
- 建议版本管理 (v1, v2, ...)
5. ❌ 循环依赖
- 函数A包含函数B函数B包含函数A
- 导致无限递归
---
## 🎓 学习路径
### 初级 (这节课)
- [x] 创建函数
- [x] 使用函数节点
- [x] 进入/退出函数
- [x] 面包屑导航
### 中级 (下一步)
- [ ] 函数参数验证
- [ ] 错误处理
- [ ] 函数文档生成
- [ ] 多版本管理
### 高级 (进阶)
- [ ] 函数库管理
- [ ] 函数搜索和发现
- [ ] 函数分享和导入
- [ ] 性能优化
---
## 📞 需要帮助?
1. **查看完整文档**: [FUNCTION_NESTING_IMPLEMENTATION.md](FUNCTION_NESTING_IMPLEMENTATION.md)
2. **检查示例函数**: `cloud/custom_nodes/functions/example_function.json`
3. **浏览器控制台**: 按 F12 查看错误和日志
4. **后端日志**: 检查 `server.log`
---
**祝你使用愉快!** 🎉
---
*版本: v1.0.0 | 最后更新: 2024-01-15*