第10天上午_项目答辩
第四天上午培训详解: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)
}
🔧 调试技巧:
- 点击"测试运行",输入示例文本
- 观察右侧"运行结果",确认 JSON 结构
- 若报错,查看"错误日志"定位行号
- 添加
print()语句在日志中查看中间变量(可选)
❌ 常见错误: • 缩进错误:Python 对缩进敏感,确保统一 4 空格 • 类型不匹配:返回了字符串但输出定义为 Number • 未捕获异常:非法输入导致节点直接失败
#### 步骤3️⃣:集成到工作流(25 分钟)
🔗 上下游连接: • 上游:用户输入节点 → 代码节点.raw_text • 下游:代码节点.course_name → 数据库节点/回复节点
🧪 测试场景:
- 标准输入:"高等数学 3 学分 90 分" → 解析成功
- 模糊输入:"高数考了 90" → 学分默认为 0,需下游处理
- 异常输入:"今天天气不错" → 返回"解析失败",触发降级提示
💡 最佳实践: • 代码节点尽量"无状态"(不依赖外部变量) • 复杂逻辑拆分为多个代码节点,便于调试 • 添加注释说明算法逻辑,便于团队协作
> 💡 **讲师提示**:代码节点是"黑盒",务必在输入输出边界做好校验。假设上游传入的数据可能是空的或错误的,代码中要有防御性编程意识[[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 分钟演示脚本(功能亮点 + 技术架构)
---
## 📚 附:高级功能资源包
📂 当日提供材料:
- 《Python 代码节点开发手册.pdf》
- 《GPA 算法代码模板.py》
- 《记忆机制配置指南.md》
- 《隐私合规检查清单.xlsx》
🔗 技术参考: • Coze 代码节点文档:https://www.coze.cn/docs/code • 记忆机制最佳实践:https://www.coze.cn/guide/memory • 社区案例:#学习伴侣 标签下的 GPA 计算项目
💬 持续支持: • 代码调试:提供在线 Python 沙箱测试环境 • 记忆优化:协助分析记忆检索准确率 • 隐私审查:提供合规性建议
🎓 讲师寄语: 今天你掌握了智能体的"大脑"(代码逻辑)与"记忆"(个性化)。 技术是冷的,但服务是热的。 用代码计算绩点,用记忆温暖陪伴, 期待看到你打造的学习伴侣真正助力师生成长!✨
> 🔐 **安全与合规提醒**:涉及学生成绩/偏好数据时,务必:① 明确告知存储用途 ② 提供删除入口 ③ 不跨用户共享记忆 ④ 定期审查记忆内容是否含敏感信息[[35]]。