最近在手搓纯web版Agent,从Agent Loop开始,到渐进式加载skill,再到执行skill的脚本。调用llm接口等全部流程,包括视觉稿在线预览,都在前端完成,不经过后端。在浏览器实现虚拟的文件系统
仓库地址:Snake Design。在线体验地址:snake-design.vercel.app/。这个项目主要是复刻claude design,可以一句话生成UI设计稿,带交互原型。下面是用GLM-4.6V-Flash生成的效果


背景
skill里面可以定义脚本,并告诉模型如何使用。比如ui-ux-pro-max里面有个search.py脚本,就是用来在data目录搜索相关的设计系统的

问题:
- skill里面的示例的脚本路径有什么要求?
- 怎么获取脚本执行的结果
skill的加载及执行过程
以自开发的hello-baby 为例:


当用户发出"你好"时,agent共经过四轮循环
- 第一轮循环:调用接口,生成会话标题。具体参数见第一轮循环出入参
- 第二轮循环:发送用户消息,模型返回加载 "hello-baby" skill的指令。具体参数详见第二轮循环出入参
- 第三轮循环:"Skill"工具调用,获取 "hello-baby" 的内容,并传给模型。模型返回调用
Bash工具执行get_user_name脚本的指令。具体参数详见第三轮循环出入参 - 第四轮循环:
Bash工具执行get_user_name脚本,返回用户名。模型返回打招呼结果。具体参数详见第四轮循环出入参
Skill 中 Bash 脚本的结果如何获取
skill 脚本需要将结果输出到标准输出中,才能被Bash工具正确获取到结果。比如node.js脚本需要调用console.log输出到标准输出中。
如果将console.log(getUserName())改为getUserName(),没有将结果输出到标准输出,Bash没法获得脚本执行结果。如下图所示


将结果输出到终端中,bash工具即可获取到结果。

Skill 中 Bash 路径解析规则
skill.md中给出的示例脚本的路径,不管是绝对路径,还是相对路径,都必须要包含skill name这一层级的目录,否则脚本路径解析会失败。下面通过几个例子说明一下:
- 正确路径示例
示例中使用相对路径,从根目录给出脚本的位置 
- 错误路径示例
使用相对路径,但是路径没有包含skill name这层目录,即hello-baby。脚本执行报错:Exit code 1

- 正确路径示例
使用绝对路径,包含hello-baby这层目录 
- 正确路径示例
使用绝对路径,包含hello-baby这层目录

- 错误路径示例
使用绝对路径,但没有hello-baby这层目录

- 正确路径:使用相对路径
使用相对路径,包含hello-baby这层目录

Skill Bash 脚本执行总结
一、执行流程概览
Skill 中的 Bash 脚本执行共经历 4 轮循环:
用户消息 → 模型返回加载 Skill 指令 → Skill 工具读取内容 → 模型返回 Bash 执行指令 → Bash 工具执行脚本 → 返回结果给模型
二、路径解析规则
规则:脚本路径中必须包含
{skill名称}/scripts/这一层级,否则报MODULE_NOT_FOUND错误。
| 写法 | 示例 | 结果 |
|---|---|---|
| 相对路径(含 skill 名) | .claude/skills/hello-baby/scripts/get_user_name.js |
✅ |
| 相对路径(缺 skill 名) | /scripts/get_user_name.js |
❌ |
| 绝对路径(完整) | /Users/lzc/.../.claude/skills/hello-baby/scripts/get_user_name.js |
✅ |
| 绝对路径(简写,含 skill 名) | /hello-baby/scripts/get_user_name.js |
✅ |
| 绝对路径(缺 skill 名) | /scripts/get_user_name.js |
❌ |
结论 :无论相对路径还是绝对路径,路径中必须出现 skill 名称目录,这是 Claude Code 解析 Bash 脚本位置的必要条件。
三、结果输出规则
脚本必须将结果输出到标准输出(stdout),Bash 工具才能捕获并传回模型:
| 语言 | 正确写法 | 错误写法 | 说明 |
|---|---|---|---|
| JavaScript | console.log(getUserName()) |
getUserName() |
不输出则终端无日志,模型拿不到结果 |
| Python | print(get_user_name()) |
get_user_name() |
同上,必须用 print 输出 |