init: 云枢·Agent 初始提交
This commit is contained in:
117
docs/AGENTS.md
Normal file
117
docs/AGENTS.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# 编码规范
|
||||
|
||||
## 通用规范
|
||||
|
||||
- 全程使用中文书写注释、文档和沟通
|
||||
- 所有代码必须包含详细的中文注释,说明函数功能、参数含义、关键逻辑
|
||||
- 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, Parameters(JSON 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 calling(tool_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 字段为 null(JSON 中的 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. **项目正式命名为云枢·Agent(YunShu / yunshu)**,配置目录从 `~/.config/weather-cli/` 迁移到 `~/.config/yunshu/`。旧目录在首次运行时会自动迁移并删除。二进制名称改为 `yunshu`。如果迁移失败,用户可手动复制旧目录内容后重新运行。
|
||||
297
docs/MSN天气API探索报告.md
Normal file
297
docs/MSN天气API探索报告.md
Normal file
@@ -0,0 +1,297 @@
|
||||
# MSN 天气 API 探索报告
|
||||
|
||||
**生成时间**: 2026-05-03
|
||||
**探索目标**: 确认 MSN 天气是否有免费可用的 API 接口
|
||||
|
||||
---
|
||||
|
||||
## 一、核心结论
|
||||
|
||||
**MSN 没有官方公开的免费 REST API**,但存在**微软官方内部 API**(通过浏览器抓包获得),在国内访问速度快,可直接调用。
|
||||
|
||||
- ❌ **不是**官方对外公开的 API(无文档、无 SLA)
|
||||
- ✅ **是**微软官方的后台接口(`assets.msn.cn` / `api.msn.cn` 均为微软域名)
|
||||
- ⚠️ 属于**非公开内部 API**,随时可能变更或失效
|
||||
|
||||
---
|
||||
|
||||
## 二、可用接口汇总
|
||||
|
||||
| 接口 | URL | 功能 | 稳定性 |
|
||||
|------|-----|------|--------|
|
||||
| **当前天气** | `https://assets.msn.cn/service/weather/current` | 获取实时天气 | ✅ 稳定可用 |
|
||||
| **每日预报** | `https://assets.msn.cn/service/weather/dailyforecast` | 未来10天预报 | ✅ 稳定可用 |
|
||||
| **天气趋势** | `https://assets.msn.cn/service/weather/weathertrends` | 历史+趋势+日历 | ✅ 可用(参数复杂) |
|
||||
| api.msn.cn 当前 | `https://api.msn.cn/weather/current` | 用城市名获取 | ✅ 可用(但城市名不准) |
|
||||
| api.msn.cn 预报 | `https://api.msn.cn/weather/forecast` | 预报 | ❌ 500错误 |
|
||||
|
||||
**推荐**:只用 `assets.msn.cn` 的两个接口即可满足大部分需求。
|
||||
|
||||
---
|
||||
|
||||
## 三、关键参数说明
|
||||
|
||||
### 必须参数
|
||||
- **`apiKey`**: `j5i4gDqHL6nGYwx5wi5kRhXjtf2c5qgFX9fzfk0TOo`
|
||||
- 固定值,修改任意字符即返回 401 Unauthorized
|
||||
- 从微软 MSN 天气前端代码中提取
|
||||
- **`lat`** / **`lon`**: 经纬度(WGS84 坐标系)
|
||||
- **`locale`**: 语言区域,如 `zh-cn`、`en-us`
|
||||
|
||||
### 可选参数
|
||||
- **`units`**: 温度单位,`C`(摄氏)或 `F`(华氏)
|
||||
- **`days`**: 预报天数(dailyforecast 接口,最大10天)
|
||||
|
||||
### 不需要的参数
|
||||
- `user`: 测试发现不带也能正常工作
|
||||
- `cm`、`ocid`、`fdhead` 等: weathertrends 专用,dailyforecast 不需要
|
||||
|
||||
### 必须请求头
|
||||
```http
|
||||
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
|
||||
Referer: https://www.msn.com/zh-cn/weather
|
||||
```
|
||||
不带这些请求头会返回 `401 Authorization Required`。
|
||||
|
||||
---
|
||||
|
||||
## 四、调用示例
|
||||
|
||||
### PowerShell 示例
|
||||
|
||||
```powershell
|
||||
$apiKey = "j5i4gDqHL6nGYwx5wi5kRhXjtf2c5qgFX9fzfk0TOo"
|
||||
$headers = @{
|
||||
"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
||||
"Referer" = "https://www.msn.com/zh-cn/weather"
|
||||
}
|
||||
|
||||
# 获取当前天气(北京)
|
||||
$uri_current = "https://assets.msn.cn/service/weather/current?apiKey=$apiKey&lat=39.904172&lon=116.407417&units=C&locale=zh-cn"
|
||||
$currentResp = Invoke-RestMethod -Uri $uri_current -Headers $headers
|
||||
$current = $currentResp.value[0].responses[0].weather[0].current
|
||||
|
||||
Write-Host "温度: $($current.temp)C"
|
||||
Write-Host "天气: $($current.cap)"
|
||||
Write-Host "体感: $($current.feels)C"
|
||||
Write-Host "湿度: $($current.rh)%"
|
||||
Write-Host "风速: $($current.windSpd)km/h"
|
||||
Write-Host "气压: $($current.baro)hPa"
|
||||
Write-Host "紫外线: $($current.uv) ($($current.uvDesc))"
|
||||
Write-Host "AQI: $($current.aqi) ($($current.aqiSeverity))"
|
||||
|
||||
# 获取未来7天预报
|
||||
$uri_forecast = "https://assets.msn.cn/service/weather/dailyforecast?apiKey=$apiKey&lat=39.904172&lon=116.407417&units=C&locale=zh-cn&days=7"
|
||||
$forecastResp = Invoke-RestMethod -Uri $uri_forecast -Headers $headers
|
||||
$days = $forecastResp.value[0].responses[0].weather[0].days
|
||||
|
||||
Write-Host "`n未来7天预报:"
|
||||
foreach ($day in $days) {
|
||||
$d = $day.daily
|
||||
Write-Host " $($d.valid.ToString().Substring(0,10)): $($d.tempLo)-$($d.tempHi)C, 降水$($d.precip)%, 风速$($d.windMax)km/h"
|
||||
}
|
||||
```
|
||||
|
||||
### curl 示例
|
||||
|
||||
```bash
|
||||
# 当前天气
|
||||
curl -H "User-Agent: Mozilla/5.0" \
|
||||
-H "Referer: https://www.msn.com/zh-cn/weather" \
|
||||
"https://assets.msn.cn/service/weather/current?apiKey=j5i4gDqHL6nGYwx5wi5kRhXjtf2c5qgFX9fzfk0TOo&lat=39.904172&lon=116.407417&units=C&locale=zh-cn"
|
||||
|
||||
# 7天预报
|
||||
curl -H "User-Agent: Mozilla/5.0" \
|
||||
-H "Referer: https://www.msn.com/zh-cn/weather" \
|
||||
"https://assets.msn.cn/service/weather/dailyforecast?apiKey=j5i4gDqHL6nGYwx5wi5kRhXjtf2c5qgFX9fzfk0TOo&lat=39.904172&lon=116.407417&units=C&locale=zh-cn&days=7"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、返回数据结构
|
||||
|
||||
### current 接口响应
|
||||
|
||||
```json
|
||||
{
|
||||
"@odata.context": "api.msn.com/weather/$metadata#current",
|
||||
"value": [{
|
||||
"responses": [{
|
||||
"weather": [{
|
||||
"current": {
|
||||
"temp": 20.0, // 当前温度
|
||||
"cap": "晴", // 天气描述
|
||||
"capAbbr": "晴", // 简短描述
|
||||
"feels": 20.0, // 体感温度
|
||||
"rh": 14.0, // 相对湿度 %
|
||||
"baro": 1006.0, // 气压 hPa
|
||||
"windSpd": 25.0, // 风速 km/h
|
||||
"windDir": 360, // 风向(度)
|
||||
"windGust": 43.0, // 阵风速度
|
||||
"uv": 5.0, // 紫外线指数
|
||||
"uvDesc": "中等", // 紫外线描述
|
||||
"vis": 30.0, // 能见度 km
|
||||
"dewPt": -8.0, // 露点温度
|
||||
"aqi": 22.0, // AQI指数
|
||||
"aqiSeverity": "优", // AQI等级
|
||||
"cloudCover": 15.0, // 云量 %
|
||||
"created": "2026-05-03T14:29:06+08:00"
|
||||
}
|
||||
}],
|
||||
"source": {
|
||||
"location": "北京, 北京市, 中国",
|
||||
"coordinates": {"lat": 39.904172, "lon": 116.407417}
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
### dailyforecast 接口响应
|
||||
|
||||
```json
|
||||
{
|
||||
"@odata.context": "api.msn.com/weather/$metadata#dailyforecast",
|
||||
"value": [{
|
||||
"responses": [{
|
||||
"weather": [{
|
||||
"days": [
|
||||
{
|
||||
"daily": {
|
||||
"valid": "2026-05-03T00:00:00", // 日期
|
||||
"tempLo": 8, // 最低温
|
||||
"tempHi": 21, // 最高温
|
||||
"precip": 5.0, // 降水概率 %
|
||||
"windMax": 10.0, // 最大风速
|
||||
"windMaxDir": 286, // 风向
|
||||
"rhHi": 35.85, // 最高湿度
|
||||
"rhLo": 14.0, // 最低湿度
|
||||
"icon": 1, // 图标代码
|
||||
"symbol": "d000", // 天气符号
|
||||
"uv": 5.0, // 紫外线指数
|
||||
"uvDesc": "中等"
|
||||
}
|
||||
}
|
||||
// ... 更多天
|
||||
]
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、多城市验证结果
|
||||
|
||||
| 城市 | 经纬度 | 状态 | 示例数据 |
|
||||
|------|--------|------|----------|
|
||||
| 北京 | 39.904172, 116.407417 | ✅ 正常 | 20°C, 晴, 湿度14% |
|
||||
| 上海 | 31.2304, 121.4737 | ✅ 正常 | 21°C, 多云, 湿度54% |
|
||||
| 广州 | 23.1291, 113.2644 | ✅ 正常 | 24°C, 多云, 湿度79% |
|
||||
| 成都 | 30.5728, 104.0668 | ✅ 正常 | 23°C, 局部多云, 湿度42% |
|
||||
|
||||
---
|
||||
|
||||
## 七、限制与注意事项
|
||||
|
||||
### 1. apiKey 固定
|
||||
- 当前 key 硬编码在微软前端代码中
|
||||
- 修改任意字符即失效(返回 401)
|
||||
- **长期有效性未知**,微软可能随时更换
|
||||
|
||||
### 2. 非公开接口
|
||||
- 无官方文档
|
||||
- 无 SLA(服务等级协议)保证
|
||||
- 数据结构可能随时变更
|
||||
|
||||
### 3. 需要特定请求头
|
||||
必须携带 `User-Agent` 和 `Referer`,否则返回 401。
|
||||
|
||||
### 4. 限流未知
|
||||
未测试请求频率限制,建议生产环境加入适当的请求间隔。
|
||||
|
||||
### 5. 城市名接口不可靠
|
||||
`api.msn.cn` 使用城市名参数可能返回错误城市(测试"北京"返回了也门首都萨那)。
|
||||
|
||||
### 6. 法律合规
|
||||
- 这是非公开接口,用于个人项目/内部工具问题不大
|
||||
- **不建议用于商业产品**(随时可能失效,且无使用授权)
|
||||
|
||||
---
|
||||
|
||||
## 八、推荐方案
|
||||
|
||||
### 最简调用方案
|
||||
|
||||
```powershell
|
||||
function Get-MSNWeather {
|
||||
param(
|
||||
[double]$Lat,
|
||||
[double]$Lon,
|
||||
[string]$Locale = "zh-cn"
|
||||
)
|
||||
|
||||
$apiKey = "j5i4gDqHL6nGYwx5wi5kRhXjtf2c5qgFX9fzfk0TOo"
|
||||
$headers = @{
|
||||
"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
||||
"Referer" = "https://www.msn.com/zh-cn/weather"
|
||||
}
|
||||
|
||||
# 当前天气
|
||||
$currentUri = "https://assets.msn.cn/service/weather/current?apiKey=$apiKey&lat=$Lat&lon=$Lon&units=C&locale=$Locale"
|
||||
$current = Invoke-RestMethod -Uri $currentUri -Headers $headers
|
||||
|
||||
# 7天预报
|
||||
$forecastUri = "https://assets.msn.cn/service/weather/dailyforecast?apiKey=$apiKey&lat=$Lat&lon=$Lon&units=C&locale=$Locale&days=7"
|
||||
$forecast = Invoke-RestMethod -Uri $forecastUri -Headers $headers
|
||||
|
||||
return @{
|
||||
Current = $current.value[0].responses[0].weather[0].current
|
||||
Forecast = $forecast.value[0].responses[0].weather[0].days
|
||||
}
|
||||
}
|
||||
|
||||
# 使用示例
|
||||
$weather = Get-MSNWeather -Lat 39.904172 -Lon 116.407417
|
||||
$weather.Current.temp # 当前温度
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 九、补充:天气图标对照
|
||||
|
||||
接口返回的 `icon` 或 `symbol` 字段对应天气图标:
|
||||
- `0`: 晴天
|
||||
- `1`: 大部晴朗
|
||||
- `2`: 局部多云
|
||||
- `3`: 多云
|
||||
- `4`: 阴天
|
||||
- `5-6`: 有雾
|
||||
- `7-8`: 阴沉
|
||||
- `9-12`: 阵雨
|
||||
- `13-18`: 雷雨
|
||||
- `19-22`: 雨夹雪
|
||||
- `23-26`: 小雪
|
||||
- `27-30`: 中到大雪
|
||||
|
||||
图标完整 URL:
|
||||
```
|
||||
http://img-s-msn-com.akamaized.net/tenant/amp/entityid/AAehR3S.img
|
||||
```
|
||||
(其中 `AAehR3S` 是从 `urlIcon` 字段获取)
|
||||
|
||||
---
|
||||
|
||||
## 十、总结
|
||||
|
||||
| 项目 | 结论 |
|
||||
|------|------|
|
||||
| 是否有免费 API | ✅ 有(非公开内部接口) |
|
||||
| 国内速度 | ✅ 快(msn.cn 国内节点) |
|
||||
| 稳定性 | ⚠️ 未知(非官方,随时可能变) |
|
||||
| 数据完整性 | ✅ 完整(当前+预报+AQI+紫外线等) |
|
||||
| 推荐用途 | 个人项目、内部工具、原型开发 |
|
||||
| 不推荐用途 | 商业产品、长期运行服务 |
|
||||
|
||||
**建议**:如果用于生产环境,推荐同时准备备用方案(如和风天气、OpenWeatherMap 等)。
|
||||
70
docs/architecture.md
Normal file
70
docs/architecture.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# 云枢·Agent 架构参考
|
||||
|
||||
> 详细架构白皮书见 `~/Desktop/yunshu-architecture.md`
|
||||
>
|
||||
> 本文档为项目内部精简参考
|
||||
|
||||
## 项目命名
|
||||
|
||||
- **中文名**:云枢·Agent(坐看云卷云舒,静听花开花落)
|
||||
- **英文名**:YunShu / yunshu
|
||||
- **配置目录**:`~/.config/yunshu/`
|
||||
|
||||
## 三层分离架构
|
||||
|
||||
```
|
||||
Agent Skill (agents/*.md) → 纯行为(~40行,全程在 system prompt)
|
||||
普通 Skill (skills/*/SKILL.md) → 纯知识(按需加载,用完即走)
|
||||
Tool (src/tool.go 注册) → 确定性执行(Go 代码,仅返回结果)
|
||||
```
|
||||
|
||||
## 四种能力对比
|
||||
|
||||
| 维度 | Agent Skill | 普通 Skill | Tool | MCP |
|
||||
|------|------------|-----------|------|-----|
|
||||
| 本质 | 角色定义("我是谁") | 知识手册("怎么用") | 确定性执行("帮我做") | 外部服务("远程调用") |
|
||||
| 加载方式 | 启动即加载 | `skill("name")` | 声明即注册 | 外部进程协议 |
|
||||
| 上下文影响 | 全程 | 仅该轮 | 仅结果文本 | 同 tool |
|
||||
| 实现形式 | .md frontmatter+body | .md body | Go 函数 | 外部 server |
|
||||
|
||||
## 判断准则
|
||||
|
||||
```
|
||||
"做什么" → Agent Skill
|
||||
"怎么做" → 继续问
|
||||
"知识" → 普通 Skill
|
||||
"操作" → 继续问
|
||||
"本地操作" → Tool
|
||||
"远程服务" → MCP
|
||||
```
|
||||
|
||||
## 和 picoclaw 的关键区别
|
||||
|
||||
| | picoclaw | 云枢·Agent |
|
||||
|---|---|---|
|
||||
| 上下文 | 行为+知识+工具全堆在一起 | 三层分离,各司其职 |
|
||||
| 角色 | 一个 prompt 塞 N 个角色 | 一个 agent = 一个角色 |
|
||||
| 知识加载 | 预置或直接塞入 | 按需加载,仅该轮存在 |
|
||||
| 工具执行 | 依赖 LLM 构造 URL 解析 JSON | Tool 用 Go 代码,100% 可靠 |
|
||||
|
||||
## 当前 tools
|
||||
|
||||
| 工具名 | 作用 | 实现 |
|
||||
|--------|------|------|
|
||||
| http-get | HTTP GET 请求 | Go |
|
||||
| skill | 按需加载知识 | Go |
|
||||
| geocode | 城市名 → 坐标 | Go(调 wttr.in) |
|
||||
| read-file | 读取文件 | Go |
|
||||
|
||||
## 后续演进
|
||||
|
||||
```
|
||||
云枢·Agent (三层分离+单agent)
|
||||
↓
|
||||
河虾 claw (三层分离+主-从)
|
||||
├─ master: 意图识别+任务分发
|
||||
├─ weather-subagent
|
||||
├─ tts-subagent
|
||||
├─ asr-subagent
|
||||
└─ ...更多 subagent
|
||||
```
|
||||
56
docs/changelog.md
Normal file
56
docs/changelog.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# 云枢·Agent 版本变更日志
|
||||
|
||||
> 坐看云卷云舒,静听花开花落
|
||||
|
||||
## [1.0.0] - 2026-05-07
|
||||
|
||||
### 重大变更
|
||||
- **项目更名**:weather-cia → **云枢·Agent**(英文名 YunShu / yunshu)
|
||||
- **配置目录迁移**:`~/.config/weather-cli/` → `~/.config/yunshu/`(自动迁移)
|
||||
- 二进制名称改为 `yunshu`
|
||||
|
||||
## [0.3.0] - 2026-05-07
|
||||
|
||||
### 新增
|
||||
- `geocode` 工具:通过 wttr.in 查询城市坐标,支持中文和英文城市名
|
||||
- `skills/geocoding/SKILL.md`:地理编码验证规则(同名城市检测、国家核对)
|
||||
- 架构分离:agent skill 只放行为,普通 skill 只放知识,tool 负责确定性执行
|
||||
|
||||
### 变更
|
||||
- `agents/weather-agent.md` 精简为纯行为定义(去掉所有 MSN API 内联细节,改为按需加载 skill)
|
||||
- 城市定位方式:从静态 cities.json 查表 → 调用 `geocode` 工具实时查询
|
||||
- `agents/weather-agent.md` tools 新增 `geocode`
|
||||
- session 文件从项目目录移至 `~/.config/weather-cli/session.json`
|
||||
|
||||
## [0.2.0] - 2026-05-07
|
||||
|
||||
### 新增
|
||||
- `onboard` 子命令:交互式初始化向导,引导用户配置 LLM 连接信息
|
||||
- 全局配置文件 `~/.config/weather-cli/config.yaml`,存储 LLM host/model/key
|
||||
- 双路径搜索机制:项目目录优先,`~/.config/weather-cli/` 后备
|
||||
- 首次运行检测:未配置时提示用户运行 `weather-cia onboard`
|
||||
|
||||
### 变更
|
||||
- 项目重命名为 `weather-cia`
|
||||
- 配置加载改为:配置文件 → 环境变量(环境变量优先级更高)
|
||||
- Agent/skill 搜索路径扩展:项目目录 → 全局配置目录
|
||||
- `onboard` 自动复制默认 agents/skills/data 到全局配置目录
|
||||
|
||||
## [0.1.0] - 2026-05-07
|
||||
|
||||
### 新增
|
||||
- 项目初始化,基于 Go 实现的轻量级 agent 框架
|
||||
- 核心架构:.md 文件定义 agent 行为,代码只负责加载和执行
|
||||
- 工具系统:声明式注册(http-get, skill, read-file)
|
||||
- Session 会话管理:session.json 记录对话历史,支持上下文追问
|
||||
- 天气情报官 agent(weather-agent.md):通过 MSN 天气 API 查询实时天气和预报
|
||||
- MSN 天气 API Skill(msn-weather-api/SKILL.md):API 知识按需加载
|
||||
- 内置 42 个中国城市经纬度数据库(data/cities.json)
|
||||
- 支持单次查询和交互模式两种运行方式
|
||||
- 默认集成豆包(火山引擎)LLM,通过环境变量可切换
|
||||
|
||||
### 技术细节
|
||||
- 语言:Go 1.21
|
||||
- 依赖:仅 gopkg.in/yaml.v3(用于解析 frontmatter)
|
||||
- API 兼容 OpenAI Chat Completion 格式
|
||||
- 环境变量:`OPENAI_API_KEY`(必填)、`LLM_ENDPOINT`、`LLM_MODEL`
|
||||
144
docs/taolun.md
Normal file
144
docs/taolun.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# 讨论历史
|
||||
|
||||
## 2026-05-07 项目启动与架构设计
|
||||
|
||||
### 背景
|
||||
用户有一个 `MSN天气API探索报告.md` 文档,记录了通过抓包发现的微软 MSN 天气内部 API(`assets.msn.cn`),该 API 国内访问速度快,数据完整(温度、湿度、风速、AQI、紫外线等),但属于非公开接口,无 SLA 保证。
|
||||
|
||||
### 目标演变
|
||||
1. **最初目标**:做一个"天气情报官" agent,后期结合 TTS 和 ASR 实现语音查询播报
|
||||
2. **深化**:用户想从 0 实现一个类似 opencode 主-从架构的个人 AI 助理,解决现有单 agent 框架(zeroclaw/picoclaw)的痛点:上下文污染、工具执行懒惰、skill 效果差
|
||||
3. **当前范围**:先做一个最小化的 CLI 天气查询工具,验证 .md 外挂 agent 定义 + session 会话管理 + 工具注册表机制
|
||||
|
||||
### 架构决策
|
||||
|
||||
#### 为什么不用现有框架(LangChain 等)
|
||||
- 核心创新是 .md 文件即 agent 定义,与任何框架都耦合不上
|
||||
- 自实现核心 ~500 行,无外部依赖包袱
|
||||
|
||||
#### Agent 定义格式(仿 opencode)
|
||||
- YAML frontmatter + Markdown body
|
||||
- frontmatter 字段:name, description, type, tools, permission
|
||||
- body 即 system prompt,定义角色行为
|
||||
|
||||
#### Session 会话机制
|
||||
- `session.json` 文件存对话历史,格式兼容 OpenAI Chat Completion API messages 数组
|
||||
- 每次启动清空,每轮对话追加
|
||||
- 追问时 LLM 自动判断是否需要重新调 API(数据过期/不同城市)
|
||||
- 通用设计,后续 master-subagent 架构也可复用
|
||||
|
||||
#### LLM 提供商
|
||||
- 用户提供豆包(火山引擎)API:`https://ark.cn-beijing.volces.com/api/v3`
|
||||
- 模型:`doubao-seed-2-0-pro-260215`
|
||||
- 环境变量可配置:`LLM_ENDPOINT`, `LLM_MODEL`, `LLM_API_KEY`
|
||||
|
||||
### 工具系统
|
||||
- 声明式注册:`tool.go` 注册工具,`.md` 文件声明即可用
|
||||
- 内置工具:`http-get`, `skill`, `read-file`
|
||||
- skill 工具按需加载,不预置到 system prompt
|
||||
|
||||
### Windows 编码问题
|
||||
- PowerShell 输出编码为 GB2312,Go 输出 UTF-8 导致中文乱码
|
||||
- 通过 `kernel32.SetConsoleOutputCP(65001)` 设置控制台 CP 为 UTF-8
|
||||
- 在 PowerShell 中需额外执行 `[Console]::OutputEncoding = [Text.Encoding]::UTF8`
|
||||
|
||||
### 项目结构(最终)
|
||||
```
|
||||
weather/
|
||||
├── main.go # CLI 入口
|
||||
├── types.go # 核心类型
|
||||
├── loader.go # .md 解析 + skill 加载
|
||||
├── llm.go # LLM API 封装(默认豆包)
|
||||
├── tool.go # 工具注册表
|
||||
├── runtime.go # agent 循环 + session
|
||||
├── agents/
|
||||
│ └── weather-agent.md # 天气情报官定义
|
||||
├── skills/
|
||||
│ └── msn-weather-api/SKILL.md
|
||||
├── data/
|
||||
│ └── cities.json # 42 个中国城市
|
||||
├── taolun.md # 本文件
|
||||
├── changelog.md # 版本变更
|
||||
└── agents.md # 编码规范
|
||||
```
|
||||
|
||||
### 验证结果
|
||||
- 单次查询:`.\weather-agent.exe "北京今天天气"` → 成功返回温度、湿度、AQI 等
|
||||
- 交互模式:启动后连续追问 → `session.json` 记录历史,LLM 基于上下文回答"适合穿什么"
|
||||
- 豆包 API 工具调用正常:自动读取 cities.json → 调 MSN API → 分析输出
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-07 项目重命名与配置体系
|
||||
|
||||
### 变更
|
||||
1. **项目重命名**:`weather-agent` → `weather-cia`(CIA = 天气情报官)
|
||||
2. **配置体系**:`~/.config/weather-cli/config.yaml` 统一管理 LLM 配置
|
||||
3. **初始化方式**:`weather-cia onboard` 交互式向导,替代手动写配置文件
|
||||
4. **双路径搜索**:项目目录优先 + `~/.config/weather-cli/` 后备
|
||||
|
||||
### 关键决策
|
||||
- **用 config.yaml 而非 .env/.secret**:YAML 风格与 agent 定义一致,API Key 用 0600 权限保护
|
||||
- **配置优先级**:环境变量 > 配置文件 > 默认值(`init()` 中依次加载)
|
||||
- **`onboard` 子命令**:交互式 TTY 输入,自动复制默认 agents/skills/data 到全局目录
|
||||
- **搜索路径**:`SearchFile()` 统一管理,开发者用项目文件,用户用全局配置
|
||||
|
||||
### 验证
|
||||
- `weather-cia onboard` 成功创建 `~/.config/weather-cli/config.yaml`
|
||||
- `weather-cia "北京今天天气"` 无需环境变量,直接读取配置文件中的豆包 key 并成功返回天气数据
|
||||
- 全局配置目录自动包含 agents/、skills/、data/ 的完整副本
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-07 架构分离:Agent Skill vs 普通 Skill vs Tool
|
||||
|
||||
### 背景
|
||||
参考了 picoclaw 的 weather skill 设计,对比发现:
|
||||
- picoclaw 的 skill 写得很完整(含验证规则、边界情况)
|
||||
- 但我们的 `weather-agent.md` 之前 inline 了大量 API 细节 → 和 picoclaw 一样污染上下文
|
||||
|
||||
### 决策:三层分离
|
||||
|
||||
| 层 | 文件位置 | 加载时机 | 上下文影响 |
|
||||
|---|---------|---------|-----------|
|
||||
| **Agent skill** | `agents/weather-agent.md` | 启动即加载为 system prompt | **全程** |
|
||||
| **普通 skill** | `skills/*/SKILL.md` | LLM 调用 `skill("name")` 时 | **仅该轮对话** |
|
||||
| **Tool** | `src/tool.go` 注册 | 预声明,LLM 调用时执行 | **仅返回结果文本** |
|
||||
|
||||
### 具体改造
|
||||
|
||||
1. **新增 `geocode` tool**(Go 代码):
|
||||
- 输入城市名,调 wttr.in `?format=j1` 解析 JSON
|
||||
- 返回 `{lat, lon, name, country}` 结构化数据
|
||||
- 确定性执行,比 LLM 自己构造 URL 解析 JSON 更可靠
|
||||
|
||||
2. **新建 `skills/geocoding/SKILL.md`**:
|
||||
- 纯知识:wttr.in 查询格式、JSON 解析路径
|
||||
- 验证规则:同名城市检测、country 核对、population 排序
|
||||
|
||||
3. **精简 `agents/weather-agent.md`**:
|
||||
- 去掉所有 MSN API URL、apiKey、请求头、JSON 路径等内联知识
|
||||
- 改为行为描述:识别城市 → geocode → skill("msn-weather-api") → http-get → 分析
|
||||
- 从 65 行缩减为 40 行,只留行为逻辑
|
||||
|
||||
4. **session 移至 `~/.config/weather-cli/session.json`**
|
||||
|
||||
### 结果
|
||||
- Agent skill 保持瘦身,system prompt 不膨胀
|
||||
- 知识按需加载,用完即走,不残留上下文
|
||||
- Tool 执行可靠,不依赖 LLM 的 JSON 解析能力
|
||||
- 三种内容互不干扰,为后续主-从架构打下基础
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-07 项目更名:云枢·Agent
|
||||
|
||||
### 变更
|
||||
1. **正式命名**:云枢·Agent(YunShu / yunshu)
|
||||
- 坐看云卷云舒,静听花开花落
|
||||
2. **配置目录迁移**:`~/.config/weather-cli/` → `~/.config/yunshu/`(自动迁移)
|
||||
3. **二进制名称**:`yunshu`
|
||||
4. **架构白皮书**:`~/Desktop/yunshu-architecture.md`
|
||||
|
||||
### 设计理念
|
||||
"云枢"二字呼应了项目作为 AI 助理"中枢调度"的定位——云是分布式的、流转的,枢是枢纽、核心。后续主-从架构中,master 负责调度、subagent 各司其职,恰如云卷云舒。
|
||||
Reference in New Issue
Block a user