跳至主要內容

第10天上午_项目答辩

周子力大约 12 分钟教学文档Python基础

第四天上午培训详解:Python 代码与记忆机制

🎯 培训主题:让校园百事通"会计算、懂记忆、更懂你"——学习伴侣模块进阶


📅 8:00-9:45|Python 代码节点入门

🔹 学习目标

  • 理解工作流中 Python 代码节点的价值与边界
  • 掌握代码节点的输入/输出定义规范
  • 学会编写基础数据处理函数(字符串解析/格式转换)
  • 理解代码沙箱的安全限制与调试方法

🔹 为什么需要代码节点?

🧩 工作流 vs 代码节点

能力维度普通工作流节点Python 代码节点适用场景
逻辑处理条件分支/循环复杂算法/递归普通节点:简单判断;代码节点:复杂计算
数据操作字段映射/拼接正则/JSON 解析/加密代码节点:处理非结构化文本
数学计算基础加减统计/矩阵/科学计算代码节点:GPA/绩点/排名计算
外部依赖仅限插件标准库(math/re/json)代码节点:无需联网的纯逻辑处理
执行效率高(原生)中(沙箱启动)普通节点:高频调用;代码节点:按需调用

💡 关键认知:代码节点是工作流的"增强引擎",用于处理原生节点难以实现的复杂逻辑,但应避免滥用(能不用代码则不用,便于维护)[[31]]。

🔧 代码节点核心机制

执行流程:
1. 输入接收:从上游节点获取参数(JSON 格式)
2. 沙箱运行:在隔离的 Python 环境中执行代码(无外网权限)
3. 结果返回:输出 JSON 数据供下游节点使用
4. 错误处理:抛出异常时中断流程或触发降级分支

安全限制:
❌ 禁止网络请求(requests/http)
❌ 禁止文件系统操作(open/write)
❌ 禁止导入非标准库(仅限 math/re/json/datetime 等)
✅ 允许:逻辑计算/字符串处理/数据转换

🔹 实操步骤:编写数据处理函数

步骤1️⃣:添加与配置代码节点(20 分钟)

🎯 操作路径:
工作流编辑页 → 拖拽"代码"节点 → 选择 Python 3.10

📋 配置详解:
┌─────────────────────────────────────┐
│ 输入变量定义(Input):             │
│ • 变量名:raw_text                  │
│ • 类型:String                      │
│ • 必填:是                          │
│ • 示例:"高等数学 3 学分 90 分"      │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ 输出变量定义(Output):            │
│ • 变量名:course_name               │
│ • 类型:String                      │
│ • 变量名:credit                    │
│ • 类型:Number                      │
│ • 变量名:score                     │
│ • 类型:Number                      │
└─────────────────────────────────────┘

💡 配置技巧:
• 输入名尽量语义化(避免 input1, input2)
• 输出类型必须与代码返回值一致
• 添加"示例值"便于调试时自动填充

步骤2️⃣:编写字符串解析代码(40 分钟)

🎯 场景:从用户自然语言中提取课程信息
用户输入:"我高等数学考了 90 分,3 个学分"

📋 Python 代码示例:
```python
import re
import json

def main(raw_text):
    """
    从文本中提取课程名、学分、成绩
    支持格式:"课程名 X 学分 Y 分" 或 "课程名 XY 分"
    """
    try:
        # 初始化默认值
        course_name = "未知课程"
        credit = 0.0
        score = 0.0
        
        # 正则匹配模式
        # 匹配数字 + 学分
        credit_match = re.search(r'(\d+(?:\.\d+)?)\s*学分', raw_text)
        # 匹配数字 + 分
        score_match = re.search(r'(\d+(?:\.\d+)?)\s*分', raw_text)
        # 提取课程名(去除数字和单位)
        name_match = re.sub(r'\d+(?:\.\d+)?\s*(?:学分 | 分)', '', raw_text).strip()
        
        if credit_match:
            credit = float(credit_match.group(1))
        if score_match:
            score = float(score_match.group(1))
        if name_match:
            course_name = name_match
            
        return {
            "course_name": course_name,
            "credit": credit,
            "score": score
        }
    except Exception as e:
        # 错误处理:返回空值而非中断流程
        return {
            "course_name": "解析失败",
            "credit": 0,
            "score": 0,
            "error": str(e)
        }

🔧 调试技巧:

  1. 点击"测试运行",输入示例文本
  2. 观察右侧"运行结果",确认 JSON 结构
  3. 若报错,查看"错误日志"定位行号
  4. 添加 print() 语句在日志中查看中间变量(可选)

❌ 常见错误: • 缩进错误:Python 对缩进敏感,确保统一 4 空格 • 类型不匹配:返回了字符串但输出定义为 Number • 未捕获异常:非法输入导致节点直接失败


#### 步骤3️⃣:集成到工作流(25 分钟)

🔗 上下游连接: • 上游:用户输入节点 → 代码节点.raw_text • 下游:代码节点.course_name → 数据库节点/回复节点

🧪 测试场景:

  1. 标准输入:"高等数学 3 学分 90 分" → 解析成功
  2. 模糊输入:"高数考了 90" → 学分默认为 0,需下游处理
  3. 异常输入:"今天天气不错" → 返回"解析失败",触发降级提示

💡 最佳实践: • 代码节点尽量"无状态"(不依赖外部变量) • 复杂逻辑拆分为多个代码节点,便于调试 • 添加注释说明算法逻辑,便于团队协作


> 💡 **讲师提示**:代码节点是"黑盒",务必在输入输出边界做好校验。假设上游传入的数据可能是空的或错误的,代码中要有防御性编程意识[[32]]。

---

## 📅 9:45-11:00|GPA 计算器实现

### 🔹 学习目标
- 掌握学校特定绩点算法的代码实现
- 学会处理多门课程批量计算逻辑
- 理解加权平均与算术平均的区别
- 完成 GPA 计算工作流的端到端测试

### 🔹 绩点算法原理与设计

#### 📊 常见绩点算法对比
| 算法类型 | 计算公式 | 适用场景 | 代码复杂度 |
|------|---------|---------|---------|
| **标准 4.0** | (分数 -50)/10 | 多数高校通用 | 低 |
| **加权平均** | ∑(学分×绩点)/∑学分 | 保研/奖学金评定 | 中 |
| **分段映射** | 90-100→4.0, 80-89→3.0 | 部分院校特殊规定 | 高(需配置映射表) |

#### 🎯 本次实战算法(加权平均法)

单科绩点公式: • 60 分以下:0.0 • 60-69 分:1.0-1.9 • 70-79 分:2.0-2.9 • 80-89 分:3.0-3.9 • 90-100 分:4.0 • 简化公式:GPA = (Score - 50) / 10 (上限 4.0, 下限 0.0)

总 GPA 公式: Total_GPA = Σ(Credit_i * GPA_i) / Σ(Credit_i)


### 🔹 实操步骤:构建 GPA 计算器工作流

#### 步骤1️⃣:输入数据结构设计(15 分钟)

📋 输入参数(JSON 数组): [ {"course": "高等数学", "credit": 5, "score": 90}, {"course": "大学英语", "credit": 3, "score": 85}, {"course": "计算机基础", "credit": 4, "score": 78} ]

🔧 工作流输入节点: • 变量名:course_list • 类型:Array (Object) • 示例:上述 JSON 结构


#### 步骤2️⃣:编写核心计算代码(30 分钟)
```python
def main(course_list):
    """
    计算加权平均 GPA
    输入:course_list (List[Dict])
    输出:total_gpa, total_credit, detail_list
    """
    total_credit_weighted = 0.0
    total_credit = 0.0
    detail_list = []
    
    for course in course_list:
        try:
            credit = float(course.get('credit', 0))
            score = float(course.get('score', 0))
            name = course.get('course', '未知')
            
            # 计算单科绩点 (简化公式)
            if score < 60:
                gpa = 0.0
            else:
                gpa = min(4.0, (score - 50) / 10)
            
            # 累加
            total_credit_weighted += credit * gpa
            total_credit += credit
            
            detail_list.append({
                "course": name,
                "credit": credit,
                "score": score,
                "gpa": round(gpa, 2)
            })
        except Exception as e:
            # 跳过错误课程,记录日志
            continue
    
    # 计算总 GPA
    if total_credit == 0:
        final_gpa = 0.0
    else:
        final_gpa = total_credit_weighted / total_credit
    
    return {
        "total_gpa": round(final_gpa, 2),
        "total_credit": total_credit,
        "detail": detail_list
    }

步骤3️⃣:多场景测试与验证(30 分钟)

🧪 测试用例设计:

【场景 1:正常计算】
输入:3 门课程,分数分别为 90/85/78
预期:GPA ≈ 3.57
检查:加权计算是否正确(高学分课程影响更大)

【场景 2:挂科处理】
输入:包含一门 55 分的课程
预期:该课程绩点为 0.0,拉低总 GPA
检查:是否正确处理<60 分边界

【场景 3:空数据】
输入:[] 空列表
预期:GPA=0.0,不报错
检查:除零错误处理(if total_credit == 0)

【场景 4:异常数据】
输入:学分包含负数或字符串
预期:跳过异常项或返回错误提示
检查:代码健壮性

🔧 调试技巧:
• 在代码中添加 `print()` 输出中间累加值
• 使用"断点调试"(若平台支持)观察循环过程
• 对比 Excel 手动计算结果,验证准确性

步骤4️⃣:结果展示优化(15 分钟)

🎨 输出格式化:
• 将代码输出的 JSON 转换为自然语言
• 示例模板:
  "📊 你的 GPA 计算结果:
   • 平均绩点:**{{total_gpa}}**
   • 总学分:{{total_credit}}
   • 课程明细:
     {% for item in detail %}
     • {{item.course}}: {{item.score}}分 (绩点{{item.gpa}})
     {% endfor %}
   💡 建议:保持当前状态,重点提升低绩点课程~"

✅ 验收标准:
□ 计算结果与手动计算一致
□ 边界情况(0 学分/0 课程)不报错
□ 输出格式清晰易读

💡 业务提示:不同学校绩点算法差异巨大,建议在提示词中注明"本计算基于标准 4.0 算法,具体请以教务系统为准",避免误导学生[[33]]。


📅 11:00-12:00|长期记忆机制应用

🔹 学习目标

  • 理解变量、数据库、长期记忆三者的区别与适用场景
  • 掌握 Coze 长期记忆(Long-term Memory)的配置方法
  • 实现"用户偏好记忆"功能(座位/食堂/学习习惯)
  • 理解隐私保护与记忆清除机制

🔹 三种存储机制对比

📦 存储选型指南

机制生命周期数据结构适用场景示例
工作流变量单次会话/流程临时值中间计算结果临时计算的 GPA 值
数据库 (Table)永久存储结构化表格任务/成绩/记录每日开销记录、作业清单
长期记忆 (Memory)永久存储非结构化文本用户画像/偏好/习惯"喜欢坐图书馆 3 楼"、"不吃香菜"

💡 关键认知:记忆是"隐式"的(AI 自动调用),数据库是"显式"的(需查询)。记忆适合模糊偏好,数据库适合精确记录[[34]]。

🔹 实操步骤:实现用户偏好记忆

步骤1️⃣:配置长期记忆模块(15 分钟)

🎯 操作路径:
智能体编辑页 → 右侧"记忆"模块 → 点击"开启记忆"

📋 配置详解:
┌─────────────────────────────────────┐
│ 记忆开关:☑ 启用长期记忆            │
│                                     │
│ 记忆范围:                          │
│ • 用户信息:姓名/专业/年级          │
│ • 偏好设置:座位/食堂/学习习惯      │
│ • 历史交互:重要对话摘要            │
│                                     │
│ 记忆优先级:                        │
│ • 高:用户明确声明的偏好("我常去...")│
│ • 中:多次重复的行为模式            │
│ • 低:一次性对话内容                │
└─────────────────────────────────────┘

💡 配置技巧:
• 在提示词中添加:"请主动记忆用户的个人偏好"
• 设置记忆更新策略:新信息覆盖旧信息

步骤2️⃣:提示词增强记忆调用(20 分钟)

📝 系统提示词补充:
```markdown
## 记忆使用规范
1️⃣ 主动记忆:
   当用户表达偏好时(如"我喜欢坐靠窗位置"),
   自动存入长期记忆,并回复"已记住您的偏好~"

2️⃣ 主动调用:
   当用户询问建议时(如"推荐个座位"),
   优先检索记忆中的偏好,再结合实际情况推荐

3️⃣ 记忆确认:
   涉及关键偏好变更时,需用户确认
   例:"检测到您常去食堂变了,要更新记忆吗?"

4️⃣ 隐私保护:
   不记忆敏感信息(手机号/身份证/密码)
   用户要求删除时,立即清除相关记忆

🧪 测试交互: Q: "我一般喜欢去二食堂吃饭" AI: "好的,已记住您偏好二食堂~ 下次推荐会优先考虑那里✅"

Q: "推荐个吃饭的地方" AI: "根据您的偏好,推荐【二食堂】的二楼窗口,人少味好~"


#### 步骤3️⃣:记忆与数据库联动(25 分钟)

🔄 联动场景:偏好 + 记录 场景:用户说"还是老地方,记一下花了 20 元"

📋 工作流逻辑: 1️⃣ 检索记忆:获取"老地方"指代(如"二食堂") 2️⃣ 写入数据库:将"二食堂" + 20 元 存入开销表 3️⃣ 更新记忆:若用户频繁去新地方,提示更新偏好

🔧 代码节点示例(记忆解析):

def main(memory_text, user_input):
    # 从记忆文本中提取地点
    if "二食堂" in memory_text:
        location = "二食堂"
    else:
        location = "未知"
    
    return {"location": location}

⚠️ 隐私与合规: • 提供"清除记忆"指令(如"忘记我的偏好") • 不在日志中明文存储记忆内容 • 遵循学校数据最小化原则


### 🔹 常见误区与避坑指南

⚠️ 误区 1:把所有数据都存记忆 → 正解:结构化数据(成绩/任务)存数据库,偏好存记忆

⚠️ 误区 2:记忆越多越好 → 正解:记忆过多会干扰检索,定期清理过期偏好

⚠️ 误区 3:记忆绝对准确 → 正解:记忆可能混淆,关键信息需用户确认("您是说二食堂吗?")

⚠️ 误区 4:忽略记忆清除 → 正解:必须提供"忘记我"的功能,符合隐私法规


---

## 📋 上午培训成果检查清单

✅ 能力达成: □ 能独立编写 Python 代码节点处理复杂逻辑 □ 掌握 GPA 加权算法的代码实现与测试 □ 理解变量/数据库/记忆三种存储机制的区别 □ 能配置长期记忆并实现偏好记忆功能 □ 掌握隐私保护与记忆清除机制

📊 交付物要求: • 1 个包含代码节点的工作流(字符串解析或 GPA 计算) • 1 份 GPA 计算测试报告(含边界用例) • 1 个启用长期记忆的智能体配置截图 • 1 页个人心得:代码与记忆应用的 1 个关键洞察

🎯 下午预告: 【项目完善与答辩准备】 • 项目整合:将四天模块整合为完整应用 • 体验优化:提示词润色/交互流程打磨 • 答辩准备:PPT 制作/演示脚本/Q&A 准备 • 成果展示:分组演示与专家评审

💡 预习建议: • 整理四天所学功能,梳理用户故事线 • 思考:你的智能体解决了什么核心痛点? • 准备 3 分钟演示脚本(功能亮点 + 技术架构)


---

## 📚 附:高级功能资源包

📂 当日提供材料:

  1. 《Python 代码节点开发手册.pdf》
  2. 《GPA 算法代码模板.py》
  3. 《记忆机制配置指南.md》
  4. 《隐私合规检查清单.xlsx》

🔗 技术参考: • Coze 代码节点文档:https://www.coze.cn/docs/code • 记忆机制最佳实践:https://www.coze.cn/guide/memory • 社区案例:#学习伴侣 标签下的 GPA 计算项目

💬 持续支持: • 代码调试:提供在线 Python 沙箱测试环境 • 记忆优化:协助分析记忆检索准确率 • 隐私审查:提供合规性建议

🎓 讲师寄语: 今天你掌握了智能体的"大脑"(代码逻辑)与"记忆"(个性化)。 技术是冷的,但服务是热的。 用代码计算绩点,用记忆温暖陪伴, 期待看到你打造的学习伴侣真正助力师生成长!✨


> 🔐 **安全与合规提醒**:涉及学生成绩/偏好数据时,务必:① 明确告知存储用途 ② 提供删除入口 ③ 不跨用户共享记忆 ④ 定期审查记忆内容是否含敏感信息[[35]]。
上次编辑于:
贡献者: zilizhou