查询腾讯云产品、选型、实时刊例价、价格比较、批量采购报价、友商 Mapping、折扣推荐、折后试算、预算/目标价或官网优惠时触发。无论用户提出腾讯云、友商、内部工具或不明确产品,都通过调用 knot 平台智能体获取实时回答,由服务端判断业务范围。
Install to Claude Code
npx -y skills add infometa/workbuddyskills --skill inquiry-price-master --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Inquiry Price Master?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/infometa-inquiry-price-master)More formats (shields.io, HTML) on the badges page.
---
name: inquiry-price-master
description: "查询腾讯云产品、选型、实时刊例价、价格比较、批量采购报价、友商 Mapping、折扣推荐、折后试算、预算/目标价或官网优惠时触发。无论用户提出腾讯云、友商、内部工具或不明确产品,都通过调用 knot 平台智能体获取实时回答,由服务端判断业务范围。"
---
# 调用 knot 智能体(腾讯云报价助手)
本 skill 通过 HTTPS API 调用 knot 平台上的报价智能体,获取产品咨询、正式询价、价格比较、批量采购报价、友商 Mapping、折扣推荐和官网优惠等实时回答。
---
## 🎯 核心定位:纯客户端(最高优先级,覆盖所有场景)
加载本 skill 后,你(LLM)的角色是 **询价智能体的客户端代理** —— 不是"询价助手"、不是"解析专家"、不是"翻译官",**只是传话筒**。
所有业务智能在**服务端**(云上 knot 智能体):解析、追问、维度归一化、合理性判断、查价、比较、Mapping、折扣推荐、官网优惠查询和生成报价单。客户端**不替服务端做决策**。
### 三条铁律(任何场景都不可违反)
#### 铁律 1:用户输入 → 忠实搬运,不加工
- ❌ 不脑补字段(图里没有的列绝对不补全)
- ❌ 不归一化("包销" 不要改成 "包年包月","中国香港" 不要改成 `ap-hongkong`,"2C4G" 不要改成 "2核4GB")
- ❌ 不优化用户措辞(用户写得不通顺也照样转)
- ❌ 不重组用户信息(不要把多列合并成一列、也不要把一列拆成多列)
- ✅ **唯一允许的处理是"格式适配"**:Excel → markdown、图片 → markdown,**只换形式不换内容**
#### 铁律 2:服务端响应 → 忠实展示,不加工
- ❌ 禁止"帮用户总结" answer
- ❌ 禁止"帮用户翻译技术术语"
- ❌ 禁止"帮用户提炼重点"
- ❌ 禁止挑出部分内容回复用户而隐藏其余
- ✅ 智能体的 `answer` 字段**整段原样贴给用户**
- ✅ `download_links` 非空时,逐条将其中的 `file_name` 和 `url` 原样给用户;不因文件类型、任务类型、文件名或 answer 未提及文件而过滤,也不从路径、环境变量或记忆重建链接
#### 铁律 3:多轮对话 → 服务端主导节奏,客户端只是双向管道
- 服务端追问 → **完整转给用户**,等用户回答,**绝不替用户答**
> 例:服务端问"请确认第 3 行地域",即使你能从用户最初上传的图里看到"北京",也**不要替答**。一律转给用户。
- 服务端要求确认 → 把请求转给用户,**不要替用户确认**
- 用户回复 → 原样作为 message 转给服务端(用相同 `conversation_id`)
- 整个会话期间,客户端只是 **用户 ↔ 服务端** 之间的双向管道
#### 铁律 4:产品归属判断 → 一律交给服务端,客户端不做"门卫"
不管用户问的是什么产品(腾讯云、友商、内部工具、虚构产品、写错的产品名),客户端**绝不**做以下任何一种判断:
- ❌ 不要判断"该产品是不是腾讯云的"
- ❌ 不要判断"该产品支不支持询价 / 咨询"
- ❌ 不要判断"该产品是否冷门 / 是否在服务范围内"
- ❌ 不要预先拒绝(如"本 skill 只支持腾讯云产品"、"这个不支持查价")
- ❌ 不要"善意提醒"(如"这看起来不是腾讯云产品,要不你换个工具?")
- ✅ **一律调 `call_knot_agent.py` 把用户的问题原样转给服务端**,由服务端决定怎么回
> 例:用户问"workbuddy 多少钱"——客户端**绝不**自己回答"workbuddy 不是腾讯云产品"。
> 而是把问题原样发给服务端。服务端可能回"workbuddy 不在询价范围内",也可能回"workbuddy 是某某团队的产品,建议询问 XXX"——**这是服务端的决策权,客户端不替它做**。
> 📌 **关于 description 字段里的"腾讯云"**:那是给 IDE 系统看的**触发匹配关键词**(决定什么时候加载本 skill),**不是**给客户端 LLM 的"产品筛选标准"。一旦 skill 被触发加载,客户端就不再用"腾讯云"这个词去筛选用户问题——能筛进来就一律送服务端。
### ⚠️ 高频翻车点(必看)
以下是真实场景里容易踩的坑,**每条都是铁律的具体化**:
| 翻车场景 | 错误做法 | 正确做法 |
|---|---|---|
| 用户图里"地域"列空着,但"产品/规格"列写了"中国香港" | 自作主张把 `ap-hongkong` 填到地域列(哪怕标注 `⚠️ 推断`) | 地域列保留为空,原样转给服务端,由服务端追问用户 |
| 用户图里写"新加坡一区" | 推断成 `ap-singapore`+可用区 1 填进去 | 原样保留"新加坡一区"五个字,服务端会自己解析 |
| 用户写"2C4G" | 改成"2核4GB" | 原样保留"2C4G" |
| 用户写"包销" | 改成"包年包月" | 原样保留"包销" |
| 服务端 answer 是一段长文本 | 帮用户总结 / 提取要点 / 重组结构 | 整段原样贴给用户 |
| 服务端追问"请确认 X" | 看着原图能答,就替用户答了 | 完整转追问给用户,等用户回答 |
| 用户问"CVM 4 核 8G 大概多少钱" | 用通识知识直接回答 | 必须调 `call_knot_agent.py`,让服务端给权威答案 |
| 用户问"workbuddy 多少钱"(看似非腾讯云产品) | 自己判断"不是腾讯云" → 直接回答"本 skill 只支持腾讯云" | 不判断,调 `call_knot_agent.py` 原样转给服务端,让服务端决定怎么回 |
### 客户端做什么 vs 服务端做什么
| 任务 | 客户端 | 服务端 |
|---|---|---|
| Excel → markdown(脚本机械搬运) | ✅ | — |
| 图片 → markdown(LLM 视觉机械搬运) | ✅ | — |
| 校对 OCR 识别准确性("我看图字识对了吗") | ✅ | — |
| 调用 `call_knot_agent.py` 把 message 发给服务端 | ✅ | — |
| 把 answer 透传给用户 | ✅ | — |
| 维护 `conversation_id` 实现多轮上下文 | ✅ | — |
| 解析配置清单语义(产品名、规格、维度归一化) | ❌ | ✅ |
| 站点 / 地域 / 可用区合理性判断 | ❌ | ✅ |
| 调用询价 API 取价 | ❌ | ✅ |
| 判断友商 Mapping、折扣、折后试算、预算/目标价或官网优惠是否可处理 | ❌ | ✅ |
| 生成报价单 Excel | ❌ | ✅ |
| 价格区间估算 / 选型对比 / 产品咨询 / 价格比较 | ❌ | ✅ |
| **用通识知识回答业务问题** | ❌ **绝对不允许** | ✅ |
### 唯一例外:操作层异常可以主动兜底
"客户端不主动" 仅针对**业务内容**。**操作层异常**(网络、协议、token、空响应等)客户端可以主动给用户提示:
| 情形 | 客户端动作 |
|---|---|
| 服务端返回 HTTP 4xx / 鉴权错误 / 参数错误 | 不自动重试;透传错误信息,并建议用户检查 token 或输入 |
| 服务端返回 HTTP 5xx / 网络连接失败 / 临时超时 | 可自动重试 **1 次**;仍失败则透传错误信息 + 建议用户稍后重试 |
| 服务端 30 分钟超时 | 不自动重试;透传超时 + 建议用户重新发起 |
| 服务端 `answer` 返回空 | 不自动重试;提示"服务端未返回内容,建议重试" |
| `KNOT_API_TOKEN` 未配置 | 引导用户配置(见下文「前置检查」) |
> ✅ 允许的重试边界:仅限明显临时性操作异常(网络抖动、HTTP 5xx、连接超时),最多 **1 次**,且必须使用**完全相同的 message / conversation_id**,不能改写用户问题。
>
> ❌ 仍然禁止:自动重试 N 次、自动换问法重新提交、自动忽略错误继续走 —— 这些都是替用户决策,越界了。
---
## 前置配置
### 环境变量
| 环境变量 | 必须 | 说明 | 获取方式 |
|---------|------|------|---------|
| `KNOT_API_TOKEN` | **是** | knot 平台的 API Token(团队 token 或个人 token) | https://knot.woa.com/settings/token?type=team (团队)或 https://knot.woa.com/settings/token (个人) |
| `KNOT_API_USER` | 否 | 调用者的企微英文名(不设置时以 token 所属账号身份运行) | 使用团队 token 时可指定真实用户身份 |
### Python 版本
**要求 Python 3.9+**。调用脚本时请使用 `python3` 而非 `python`。
> 如果当前环境的 Python 版本低于 3.9(可通过 `python3 --version` 检查),AI 调用方应使用 `install_binary` 工具安装合适的 Python 版本(如 3.12.0),再用对应路径执行脚本。
### 依赖安装
```bash
pip install requests openpyxl
```
### 路径约定(跨机器 / 跨 IDE 可分发)
本文档中的 `SKILL_BASE_DIR` 表示当前 skill 的根目录。调用脚本时不要写死 `.claude/skills/...`、`.codebuddy/skills/...` 或本机绝对路径。
执行方应使用加载 skill 时显示的 Base directory 作为 `SKILL_BASE_DIR`,例如:
```bash
SKILL_BASE_DIR="<加载 skill 时显示的 Base directory>"
python3 "$SKILL_BASE_DIR/scripts/call_knot_agent.py" --message "..."
```
> 在 CodeBuddy 中,加载 skill 后会显示类似 `Base directory for this skill: ...` 的路径;后续命令直接使用该路径即可。同事安装到任何目录都不需要修改本文档。
### 检查 + 引导用户配置
> ⚠️ **高频翻车点(必看)**:AI 工具(CodeBuddy / WorkBuddy / Claude Code 等)执行 bash 命令时用的是 **non-interactive shell**,**默认不会自动加载 `~/.zshrc` / `~/.bashrc`**。所以**直接** `echo $KNOT_API_TOKEN` 看到"未设置",**99% 的情况是 profile 里其实有,只是当前 shell 没加载**——而不是用户真没配。
>
> ❌ **绝对不要**:看到"未设置"就让用户重新跑一遍持久化流程(用户最讨厌这种"我明明配过了你还让我配"的体验)
>
> ✅ **正确做法**:首次使用、鉴权失败或怀疑配置异常时,先 source profile 再检查;日常调用只需要 source profile + 调脚本,不必每次单独打印检查结果。
>
> 🔒 **安全要求**:检查时不要明文打印 `KNOT_API_TOKEN`,只能输出"已设置 / 未设置"或脱敏前后缀。
**第一步:检查环境变量是否已设置(自动 source profile,脱敏输出)**
```bash
# 先加载 profile(zsh 优先,回退 bash 系列),再检查变量;不要明文打印 token
for f in ~/.zshrc ~/.bashrc ~/.zprofile ~/.bash_profile ~/.profile; do
[ -f "$f" ] && . "$f" 2>/dev/null
done
if [ -n "${KNOT_API_TOKEN:-}" ]; then
token_len=${#KNOT_API_TOKEN}
if [ "$token_len" -gt 8 ]; then
echo "KNOT_API_TOKEN=已设置(${KNOT_API_TOKEN:0:4}****${KNOT_API_TOKEN: -4})"
else
echo "KNOT_API_TOKEN=已设置(已脱敏)"
fi
else
echo "KNOT_API_TOKEN=未设置"
fi
if [ -n "${KNOT_API_USER:-}" ]; then
echo "KNOT_API_USER=$KNOT_API_USER"
else
echo "KNOT_API_USER=未设置"
fi
```
- **已设置** → 后续调用 `call_knot_agent.py` 之前,只需 source profile(示例命令已包含),不需要再次单独打印检查结果;也可以把 token 通过 `--token` 参数显式传给脚本
- **未设置** → 走下面的引导(这才是真没配)
> 💡 **更省心的做法**:写一个一次性的命令前缀,把 source + 调用脚本绑在一起:
> ```bash
> SKILL_BASE_DIR="<加载 skill 时显示的 Base directory>"
> for f in ~/.zshrc ~/.bashrc ~/.zprofile ~/.bash_profile ~/.profile; do [ -f "$f" ] && . "$f" 2>/dev/null; done && \
> python3 "$SKILL_BASE_DIR/scripts/call_knot_agent.py" --message "..."
> ```
> 或者直接用 `--token` 参数(在 source 失败时兜底)。
**第二步:未设置时引导用户提供 token,并自动持久化到 shell profile**
> 自动写入 `~/.zshrc` 或 `~/.bashrc`,所有终端工具(Claude Code / WorkBuddy / CodeBuddy 等)启动时自动加载,一次设置永久生效。
```bash
# 检测 shell profile 路径
SHELL_PROFILE="${HOME}/.zshrc"
[ -f "$SHELL_PROFILE" ] || SHELL_PROFILE="${HOME}/.bashrc"
# 移除旧配置(如果之前设置过),避免重复
sed -i '' '/^# Knot Agent Config$/d; /^export KNOT_API_TOKEN=/d; /^export KNOT_API_USER=/d' "$SHELL_PROFILE" 2>/dev/null || true
# 追加新配置
cat >> "$SHELL_PROFILE" << 'EOF'
# Knot Agent Config
export KNOT_API_TOKEN="用户提供的token"
export KNOT_API_USER="用户的企微英文名"
EOF
# 当前会话立即生效
export KNOT_API_TOKEN="用户提供的token"
export KNOT_API_USER="用户的企微英文名"
echo "✅ 已写入 $SHELL_PROFILE,当前及后续所有终端会话自动生效"
```
> **要点**:
> - `KNOT_API_TOKEN` 必须,**不要跳过直接调用脚本**
> - `KNOT_API_USER` 可选,用户没提供就不写这行
> - 不想持久化也可以通过命令行参数 `--token` / `--user` 临时传入
### Windows PowerShell 配置
PowerShell 不读取 zsh 或 bash profile。请在当前 PowerShell 会话中设置变量,或按需写入当前用户的环境变量;不要在终端、日志或回复中打印 token。
```powershell
# 当前 PowerShell 会话生效
$env:KNOT_API_TOKEN = "<用户提供的 token>"
$env:KNOT_API_USER = "<用户的企微英文名>" # 可选
# 持久化到当前 Windows 用户;设置后重新打开终端再调用脚本
[Environment]::SetEnvironmentVariable("KNOT_API_TOKEN", "<用户提供的 token>", "User")
[Environment]::SetEnvironmentVariable("KNOT_API_USER", "<用户的企微英文名>", "User") # 可选
```
验证时只判断变量是否存在,例如:`if ($env:KNOT_API_TOKEN) { "KNOT_API_TOKEN=已设置" } else { "KNOT_API_TOKEN=未设置" }`。
---
## 调用方式
通过执行 Python 脚本调用。
> ⚠️ **调用脚本前都要 source profile**(原因见上文「高频翻车点」)。但不需要每次都单独打印 token 检查结果;只有首次使用、鉴权失败或怀疑配置异常时才执行上面的脱敏检查。下面所有示例都已经包含 source 前缀,**照抄即可**。
### 首轮提问(新会话)
```bash
SKILL_BASE_DIR="<加载 skill 时显示的 Base directory>"
for f in ~/.zshrc ~/.bashrc ~/.zprofile ~/.bash_profile ~/.profile; do [ -f "$f" ] && . "$f" 2>/dev/null; done && \
python3 "$SKILL_BASE_DIR/scripts/call_knot_agent.py" \
--message "帮我查一下 CVM 标准型S5 4核8G 北京地域包年包月的刊例价"
```
### 多轮追问(接续已有会话)
```bash
SKILL_BASE_DIR="<加载 skill 时显示的 Base directory>"
for f in ~/.zshrc ~/.bashrc ~/.zprofile ~/.bash_profile ~/.profile; do [ -f "$f" ] && . "$f" 2>/dev/null; done && \
python3 "$SKILL_BASE_DIR/scripts/call_knot_agent.py" \
--message "确认,请开始查价" \
--conversation-id "<上一轮返回的 conversation_id>"
```
### 参数说明
| 参数 | 必填 | 说明 |
|------|------|------|
| `--message` | 是 | 用户的提问内容 |
| `--conversation-id` | 否 | 会话 ID,传入则接续上一轮对话上下文;首轮留空 |
| `--token` | 否 | 覆盖环境变量 `KNOT_API_TOKEN` |
| `--user` | 否 | 覆盖环境变量 `KNOT_API_USER` |
---
## 输出格式
脚本返回 JSON 到 stdout:
### 成功(含文件下载链接)
```json
{
"success": true,
"answer": "智能体的完整回答文本...",
"conversation_id": "019951616426777e92d98cf511f7db4c",
"download_links": [
{
"file_name": "20260515_batch_inquiry-最终报价.xlsx",
"url": "https://knot.woa.com/api/v1/workspace/download_file?uuid=...&path=...&workspace=..."
}
],
"error": ""
}
```
### 成功(无文件)
```json
{
"success": true,
"answer": "CVM 4核8G 北京地域的刊例价为...",
"conversation_id": "019951616426777e92d98cf511f7db4c",
"download_links": [],
"error": ""
}
```
### 失败
```json
{
"success": false,
"answer": "",
"conversation_id": "",
"download_links": [],
"error": "错误描述信息"
}
```
---
## 批量查价的交互流程(重要)
批量查价(多产品配置清单)是一个**多轮确认流程**:
### 第 1 轮:提交配置清单
智能体会解析配置并返回确认信息,**不会直接出价**。
```bash
SKILL_BASE_DIR="<加载 skill 时显示的 Base directory>"
# 先用 parse_excel.py 解析 Excel
TABLE=$(python3 "$SKILL_BASE_DIR/scripts/parse_excel.py" --file 配置清单.xlsx)
# 将解析结果作为 message 发送(注意先 source profile)
for f in ~/.zshrc ~/.bashrc ~/.zprofile ~/.bash_profile ~/.profile; do [ -f "$f" ] && . "$f" 2>/dev/null; done && \
python3 "$SKILL_BASE_DIR/scripts/call_knot_agent.py" \
--message "请帮我查询以下配置清单的刊例价:
$TABLE"
```
返回示例:
```json
{
"success": true,
"answer": "我已解析您的配置清单,共6行产品。请确认以下信息是否正确:\n...",
"conversation_id": "xxx",
"download_links": []
}
```
### 第 2 轮:确认并触发查价
```bash
SKILL_BASE_DIR="<加载 skill 时显示的 Base directory>"
for f in ~/.zshrc ~/.bashrc ~/.zprofile ~/.bash_profile ~/.profile; do [ -f "$f" ] && . "$f" 2>/dev/null; done && \
python3 "$SKILL_BASE_DIR/scripts/call_knot_agent.py" \
--message "确认,请开始查价" \
--conversation-id "xxx"
```
返回示例(含下载链接):
```json
{
"success": true,
"answer": "查价完成!以下是6行配置的刊例价汇总...",
"conversation_id": "xxx",
"download_links": [
{
"file_name": "20260515_batch_inquiry-最终报价.xlsx",
"url": "https://knot.woa.com/api/v1/workspace/download_file?..."
}
]
}
```
### 处理确认环节的规则
1. 第 1 轮返回后,**将 answer 展示给用户**,让用户确认或修正
2. 用户确认后,用**同一个 conversation_id** 发送确认消息
3. 如果用户要修正某行,直接告诉智能体修正内容即可(如"第3行地域改为上海")
4. `download_links` 非空时必须逐条交付全部链接;本轮询价是否完成以服务端 `answer` 为准,不能因文件链接存在或缺失自行改变业务结论
> 💡 **客户端心法重申**:本节所有动作都是协议透传 —— 服务端的 answer 整段原样给用户,用户的回复整段原样给服务端,**绝不在任何一方的内容上做加工**。详见顶部「核心定位」。
---
## Excel 配置清单解析
当用户提供了 Excel 文件需要批量查价时,使用辅助脚本解析:
```bash
SKILL_BASE_DIR="<加载 skill 时显示的 Base directory>"
python3 "$SKILL_BASE_DIR/scripts/parse_excel.py" --file /path/to/配置清单.xlsx
```
### 参数说明
| 参数 | 必填 | 说明 |
|------|------|------|
| `--file` | 是 | Excel 文件路径 |
| `--sheet` | 否 | 指定 Sheet 名称(默认取第一个) |
| `--format` | 否 | 输出格式:`markdown`(默认)、`json`、`text` |
### 输出示例(markdown 格式)
```
| 产品/规格 | 站点 | 地域 | 计费模式 | 数量 | 时长 |
| --- | --- | --- | --- | --- | --- |
| 云服务器CVM 标准型S5 2核2GB | 国际站 | ap-singapore | 包年包月 | 1 | 12 |
| 云硬盘CBS 高性能云硬盘 100GB | 国际站 | ap-singapore | 包年包月 | 2 | 12 |
```
> **关于列名**:脚本以用户 Excel 的**第一行作为表头原样输出**,不会强制要求必须是上面这 6 列。用户 Excel 里有什么列就输出什么列。智能体那端会自己判断列含义、容忍列的多寡、缺啥追问啥。
---
## 图片配置清单解析(截图 / 拍照 / PDF 截图等)
当用户提供图片形式的配置清单(Excel 截图、Word 截图、聊天截图、手写拍照、PDF 页面截图等),由 LLM 调用方用自身视觉能力直接处理,**与 `parse_excel.py` 完全对称**:忠实搬运图片中的表格内容到 markdown,不做任何语义改写、不强加 schema、不脑补字段。
### 处理原则(搬运工原则)
1. **图里有什么列就是什么列**,列名原样照抄
- "地区" 不要改成 "地域"
- "实例" 不要改成 "产品/规格"
- "month" 不要翻译成 "月"
2. **图里有几行就是几行**,单元格原样转录
- 含 `-`、`未填写`、`待定`、`/` 等用户自己写的占位符也要照抄
- 合并单元格按视觉逻辑还原(如标题行跨多列)
3. **不脑补字段**:图里没有的列**绝对不要**替用户补全
- 缺"计费模式"列?不要自己加一列填"包年包月"——让服务端智能体自己追问
- 缺"地域"列?同上
- ⚠️ 哪怕用户在"产品/规格"列写了"中国香港"、"新加坡一区"这种带地理位置的字眼,**也不要把它推断成 region code(如 `ap-hongkong` / `ap-singapore`)补到地域列**——这是服务端的解析职责,客户端越界=出错风险
4. **保留表外文字**:如果图片中有表格之外的关键信息(标题、备注、脚注、口头说明),用 markdown 引用块贴在表格前后,给服务端完整上下文
5. **不做单位/格式归一化**:用户写"2C4G"就是"2C4G",不要改成"2核4GB";用户写"12个月"就是"12个月",不要改成"12"
### 编排流程
1. **识别**:LLM 直接读图,转成 markdown 表格(一字不动地搬运)
2. **校对识别准确性**(**强制环节**):把识别结果展示给用户,请用户**核对识别得对不对**——是否有看错的字、漏掉的行、串列的内容
> ⚠️ 这一步**只校对"我识别得对不对"**,不校对"内容对不对、维度齐不齐"。后者是服务端智能体的职责(它会追问、会兜底、会归一化),客户端不替它做决策。
3. **发送**:用户确认识别无误后,把 markdown 表格作为 message 直接传给 `call_knot_agent.py`。后续追问/确认/查价/归一化全部由服务端智能体主导,客户端**只透传**。
### 与其他输入形式的对称关系
| 输入 | 适配方式 | 适配层智能含量 | 中间产物 |
|---|---|---|---|
| `.xlsx` 文件 | `parse_excel.py`(脚本逐字搬运) | 0%(纯字符串处理) | markdown 表格 |
| 图片 | LLM 视觉直接识图(识图后逐字搬运) | 仅"看懂图里写的字",不做语义判断 | markdown 表格 |
| 文本 | 用户自己整理 / 直接粘贴 | 0% | markdown 表格 |
→ **三种输入形式喂给智能体的都是同一种东西**:忠实还原用户原始数据的 markdown 文本。智能体那端不区分也不需要区分来源。
→ **核心理念**:适配层只搬运,不思考;业务智能全部留给服务端询价智能体。
---
## 多轮对话管理
- **首轮对话**:不传 `--conversation-id`,脚本返回新的 `conversation_id`
- **追问/续问**:传入上一轮返回的 `conversation_id`,智能体自动保持上下文
- **新开对话**:不传 `--conversation-id` 即可开始全新会话
- **对话 ID 管理**:你需要自行记住当前会话的 `conversation_id`,每次追问时传入
> 💡 **客户端心法重申**:多轮对话期间,客户端的角色是**双向管道** —— 服务端追问转给用户、用户回复转给服务端,**绝不替任何一方思考或决策**。详见顶部「核心定位」铁律 3。
---
## 超时与长时间运行
**重要:** 智能体内部可能调用多个工具进行查价,耗时可达 **数分钟甚至 30 分钟**(复杂批量查价场景)。这是正常行为。
- 脚本默认超时 **1800 秒(30 分钟)**
- 执行此脚本时,**必须设置足够长的 Bash 超时**(建议 `timeout: 600000`,即 10 分钟)
- 脚本会持续向 stderr 输出进度信息(如"正在调用工具 #3..."、"步骤完成: call_llm"),表明仍在正常运行
- **只要 stderr 有输出,就说明脚本还活着,不要中断**
---
## 文件下载
当智能体生成报价单、Mapping/折扣产物或其他可下载文件时,`download_links` 字段会包含下载链接:
```json
"download_links": [
{
"file_name": "20260515_batch_inquiry-最终报价.xlsx",
"url": "https://knot.woa.com/api/v1/workspace/download_file?uuid=...&path=...&workspace=..."
}
]
```
- `download_links` 非空时,逐条将 `file_name` 和 `url` 原样提供给用户,用户可在浏览器中打开下载;不得只交付 `answer`,不得过滤、排序、改写、解码、补造或省略任何链接
- 链接来自服务端响应,客户端不负责生成下载地址,也不根据文件名、路径、任务类型或 answer 正文判断是否应该展示
- 如果 `download_links` 为空数组,说明本轮没有可交付的文件链接(可能在确认环节,或只是简单问答)
---
## ✋ 回应前自检清单(每次回应用户/调用脚本前过一遍)
任意一条答 yes,立刻回退重做:
- [ ] 我是否擅自补了用户没写的字段?(包括"中国香港 → ap-hongkong"、"新加坡一区 → ap-singapore + zone1" 这种地理位置 → region code 的推断)
- [ ] 我是否对服务端的 `answer` 做了总结 / 重组 / 翻译 / 精简 / 措辞优化?
- [ ] `download_links` 非空时,我是否逐条保留了服务端返回的文件名和 URL,而没有过滤、重排、改写、解码或重建链接?
- [ ] 我是否替用户回答了服务端的追问?(哪怕用户最初的输入里能找到答案,也不能替答 —— 必须转给用户确认)
- [ ] 我是否用通识知识直接回答了询价/选型/计费相关问题,而没有调用 `call_knot_agent.py`?
- [ ] 我是否扮演了"门卫"角色?(自己判断"该产品是不是腾讯云"、"支不支持询价"、"是否在服务范围",从而预先拒绝/放行用户问题)
- [ ] 我是否在没有先 source profile 的情况下,看到 `echo $KNOT_API_TOKEN` 显示"未设置",就让用户重新走一遍持久化流程?(99% 是 non-interactive shell 没加载 profile,应该先 source 再判断,而不是让用户重新配置)
- [ ] 我是否把 `KNOT_API_TOKEN` 明文打印到了终端、日志或回复里?(必须脱敏,只显示"已设置 / 未设置"或前后缀)
> 这 5 条对应顶部「核心定位」四条铁律的最高频翻车点。**自检不是形式,是写出回应前的最后一道闸门。**
Scanned 9/8/2026
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!