Files
YunShu/docs/AGENTS.md
2026-05-08 10:12:31 +08:00

118 lines
7.1 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.
# 编码规范
## 通用规范
- 全程使用中文书写注释、文档和沟通
- 所有代码必须包含详细的中文注释,说明函数功能、参数含义、关键逻辑
- Markdown 文件使用 `#` 标题层级,保持结构清晰
- 变量命名采用驼峰式,类型和函数首字母大写导出
- 同一个问题连续工作 3 次没有结论,立即退出并询问用户接下来怎么做
## Go 代码规范
- 使用 `package main` 扁平结构MVP 阶段),后续可拆分子包
- 错误处理:所有可能失败的操作必须检查 error
- 错误信息使用中文描述
- 导出函数(首字母大写)供包外调用,非导出函数(首字母小写)为内部实现
- HTTP 客户端设置超时(默认 15s避免资源泄漏
- JSON 序列化/反序列化使用 `encoding/json` 标准库
## Agent 定义规范(.md 文件)
- 必须包含 YAML frontmatter`---` 包裹)
- frontmatter 必需字段:`name`, `description`, `tools`
- tools 为数组,声明 agent 需要的工具名(在 tool.go 中注册)
- body 为 system prompt**只定义行为逻辑**(角色、工作流程、输出规范)
- **关键技术细节URL、apiKey、请求头、JSON 路径等)不要 inline 在 agent skill 中**,改为:
- 放到 `skills/*/SKILL.md` 中,由 agent 调用 `skill("name")` 按需加载
- 或注册为 tool确定性操作由 agent 声明 tools 即可调用
- session 文件存在 `~/.config/weather-cli/session.json`,不污染项目目录
### 示例
```markdown
---
name: weather-agent
description: 天气情报官
tools:
- http-get
- geocode
- skill
---
# 天气情报官
你是专业的天气情报官。
## 工作流程
1. 识别城市 → 调用 geocode 获取坐标
2. 调用 skill("msn-weather-api") 获取 API 参数
3. 调用 http-get 请求天气数据
4. 分析并输出
```
## Session 规范
- 文件路径:`~/.config/yunshu/session.json`
- 格式JSON 数组,元素为 Message 对象(兼容 OpenAI Chat Completion messages 格式)
- 角色类型:`system`, `user`, `assistant`, `tool`
- 启动时清空,每轮对话追加
- 消息顺序即对话顺序
- 放在用户配置目录而非项目目录,确保不同目录下运行时上下文连贯
## 工具注册规范
- 工具在 `tool.go``init()` 中通过 `RegisterTool()` 注册
- 每个工具定义Name, Description, ParametersJSON Schema, Execute 函数
- 工具名与 `.md` 文件中声明的 tools 列表对应
- Execute 函数接收 `map[string]interface{}` 参数,返回 string 和 error
## 环境变量
| 变量名 | 必需 | 说明 |
|--------|------|------|
| `LLM_API_KEY` | 否* | API Key覆盖配置文件 |
| `LLM_ENDPOINT` | 否 | API 端点,覆盖配置文件 |
| `LLM_MODEL` | 否 | 模型名,覆盖配置文件 |
| `OPENAI_API_KEY` | 否 | 兼容旧名,当 `LLM_API_KEY` 未设置时生效 |
> *注:可在 `~/.config/yunshu/config.yaml` 中配置,无需环境变量。
> 首次使用请运行 `yunshu onboard` 交互式初始化。
---
## 【认知修正】
> 本字段存放开发过程中验证后的知识点、踩坑记录。以陈述句形式记录。
### 2026-05-07
1. **MSN 天气 API 属于非公开内部接口**apiKey 固定为 `j5i4gDqHL6nGYwx5wi5kRhXjtf2c5qgFX9fzfk0TOo`,修改任意字符即 401。必须携带 `User-Agent``Referer` 请求头,否则返回 401。响应数据在 `value[0].responses[0].weather[0]` 路径下。
2. **Go 的 `syscall` 包是标准库,无需额外依赖**。在 Windows 上可通过 `kernel32.SetConsoleOutputCP(65001)` 设置控制台 UTF-8 编码,但 PowerShell 5.1 有独立的 `[Console]::OutputEncoding` 覆盖此设置,需要额外 `[Console]::OutputEncoding = [Text.Encoding]::UTF8`
3. **豆包火山引擎API 兼容 OpenAI Chat Completion 格式**,包括 function callingtool_calls。修改 `endpoint``model` 即可切换,无需改动代码逻辑。实测 `doubao-seed-2-0-pro-260215` 支持工具调用正常。
4. **非流式调用更简单可靠**。对于 CLI 工具,等待完整响应再输出比流式逐 token 输出实现更简单,且用户能一次获取完整信息。
5. **Session 文件的关键设计**session 存储的是完整的对话消息列表(不含 system prompt格式与 OpenAI Chat Completion API 的 messages 数组一致。这意味着 runtime 不需要做任何格式转换,读 session → 直接 POST 给 LLM → 拿到回复 → 追加到 session。
6. **Go 的 `gopkg.in/yaml.v3` 依赖可能遇到 GOSUMDB 问题**。在中国网络环境下,需要设置 `GONOSUMCHECK='*'``GONOSUMDB='*'` 环境变量来绕过 checksum 数据库验证。
7. **工具定义要提供清晰的 JSON Schema 参数描述**。LLM 通过参数描述来理解如何调用工具。描述越清晰LLM 生成正确参数的概率越高。`http-get` 工具的 `headers` 参数设计为 JSON 字符串格式,比结构化对象更灵活。
8. **Go 中处理 OpenAI 响应的 Content 字段要使用指针类型**。当 LLM 返回 tool_calls 时content 字段为 nullJSON 中的 null而非空字符串。使用 `*string` 才能区分"内容为空"和"无内容"两种情况。
9. **配置文件放在 `~/.config/yunshu/config.yaml` 而非 .env/.secret**。YAML 格式与 agent 定义风格一致统一管理。API Key 用 `0600` 权限保护。优先顺序:环境变量 > 配置文件 > 默认值。`onboard` 子命令提供交互式初始化体验。
10. **双路径搜索机制**:项目目录优先,`~/.config/yunshu/` 后备。这使得开发时用项目本地文件,部署后自动切换到全局配置。`SearchFile()``LoadAgent()/LoadSkill()` 都遵循此规则。
11. **用户配置目录固定为 `~/.config/yunshu/`**,所有系统统一。存放 config.yaml、session.json、以及用户自定义的 agents/skills/data。不能改到其他路径。
12. **Agent skill、普通 skill、tool 必须严格分离,不能混淆**。Agent skill`agents/*.md`)只放行为逻辑(角色、工作流程、输出风格),不 inline 任何技术细节。技术细节URL、apiKey、请求头、JSON 解析路径)放在 `skills/*/SKILL.md` 作为纯知识,由 LLM 按需调用 `skill("name")` 加载。确定性操作(如 geocode注册为 tool保证 100% 可靠执行。这解决了 picoclaw 单 agent 架构下 skill 污染上下文的问题。
13. **wttr.in `?format=j1` 返回的 JSON 包含地理编码信息**`nearest_area[0]` 中有 `latitude``longitude``areaName``country``population` 字段。可作为免费的地理编码服务使用,无需 API Key。
14. **geocode 工具用 Go 代码实现比让 LLM 自己调 http-get 解析 JSON 更可靠**。LLM 在构造 URL 和解析嵌套 JSON 时容易出错(尤其是中文编码问题)。注册为 tool 后LLM 只需提供城市名参数Go 代码处理所有细节。
15. **项目正式命名为云枢·AgentYunShu / yunshu**,配置目录从 `~/.config/weather-cli/` 迁移到 `~/.config/yunshu/`。旧目录在首次运行时会自动迁移并删除。二进制名称改为 `yunshu`。如果迁移失败,用户可手动复制旧目录内容后重新运行。