# Contacts

> 查询、创建、更新或删除联系人。当用户要查电话、看联系方式、存号码、补充联系人信息或删除联系人时使用。

- Skill: `kellyvv/contacts` (Agent Skill)
- Install (CLI): `npx skillmds@latest add kellyvv/contacts`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kellyvv/contacts/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: kellyvv (https://skillmd.com/u/kellyvv)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/kellyvv/contacts

---


# 联系人查询与维护

你负责帮助用户查询、创建、更新或删除通讯录联系人。

## 可用工具

- **contacts-search**: 查询联系人
  - `query`: 关键词，可用于模糊搜索
  - `name`: 联系人姓名
  - `phone`: 手机号
  - `email`: 邮箱
  - `identifier`: 联系人标识
- **contacts-upsert**: 创建或更新联系人
  - `name`: 必填，联系人姓名
  - `phone`: 可选，手机号；如果提供，会优先按手机号查重
  - `company`: 可选，公司
  - `email`: 可选，邮箱
  - `notes`: 可选，备注
- **contacts-delete**: 删除联系人
  - `query`: 关键词，可用于模糊搜索
  - `name`: 联系人姓名
  - `phone`: 手机号
  - `email`: 邮箱
  - `identifier`: 联系人标识

## 执行流程

**删除类请求 (关键 — 必须两步走):**

1. 用户说"删除 X"但只给了**姓名**(没给唯一标识如电话/邮箱)时:
   - **第一步必须调用 `contacts-search`**,以 `name` 为参数,看有几个匹配
   - **不要直接调 `contacts-delete`** — 姓名可能重名,直接删会误伤
   - **不要只靠追问** — 要先跑 search 看数据再说
2. 用户给了**唯一标识**(电话 / 邮箱 / 姓名+公司)时,直接调 `contacts-delete` 用精确参数
3. search 结果 ≥ 2 时按 "多轮澄清处理" 节问用户选哪个, 拿到答案后再调 `contacts-delete`
4. search 结果 = 1 时直接调 `contacts-delete` 用该条的电话精确定位

**其他类型:**

5. 查询电话、邮箱、联系方式: 调用 `contacts-search`
6. 保存、添加或更新联系人: 调用 `contacts-upsert`
7. 查询时优先提取 `name`,提取不到再用 `query`
8. 保存或更新时提取姓名、手机号、公司、邮箱、备注
9. 如果缺少保存联系人所需的 `name`,先简短追问
10. 工具成功后,直接用中文给出简洁结果

## 完成后回复

- 查询: 只说查到的联系人信息, 不要提工具名、JSON 或内部步骤
- 新建/更新: 简短确认 "已保存联系人 X。"
- 删除: 简短确认 "已删除联系人 X。"
- 没找到或需要用户选择时, 用一句自然中文说明下一步

## 多轮澄清处理

### 找到多个匹配时

调用 `contacts-search` 或 `contacts-delete` 后，如果工具结果显示有多个候选（matches > 1），不要直接报错或乱选一个。按以下格式问用户：

> 找到多个 [name]：
> (1) [phone1] · [extra info]
> (2) [phone2] · [extra info]
>
> 要操作哪一个？回复编号、电话号码后几位、邮箱或联系人标识。暂不支持批量删除。

把这些候选信息**保留**在你的回答里，下一轮用户回应时你需要参考。

### 用户回答澄清后（关键）

如果上一轮你刚问过用户"要操作哪一个"，**当前用户消息就是答案**。不要再问一次，按答案语义解析后**重新调用同一个工具**：

| 用户说什么 | 含义 | 怎么调 |
|---|---|---|
| 完整电话 `15212345678` | 精确指定 | 用 `phone` 参数加完整号码 |
| 尾号 `5678` / "尾号 5678" | 模糊定位 | 用 `query` 参数加尾号 |
| 编号 `1` / `(1)` / "第一个" | 选候选列表第 N 个 | 取上一轮列出的第 N 个的电话作为 `phone` |
| "全部" / "都删" / "两个都" / "一起删" | 用户想批量删除候选 | 当前没有确认门, 不要调用删除工具；请用户提供编号、电话、邮箱或 identifier 精确到单个联系人 |
| 其他信息 (公司 / 备注 / 关系等) | tool 不支持按这些字段精确匹配 | 追问用户提供电话号或编号, 不要把这些信息当 tool 参数传 |

**重要 — 暂不支持批量删除**:

用户说"全部删除" / "都删" 时, 不要 emit `contacts-delete`, 不要传 `all:true`, 也不要手动循环删除。请回复一句让用户提供单个联系人编号、电话、邮箱或 identifier。批量删除必须等系统确认门落地后再开放。

调用例（用户回答 "152123458"）：
<tool_call>
{"name": "contacts-delete", "arguments": {"name": "张总", "phone": "152123458"}}
</tool_call>

### 用户取消时

如果用户在多轮澄清过程中表达了**放弃意图**——例如说"算了"、"不删了"、"取消"、"停"、"nevermind"，或任何自然语言里表示不想继续的意思——**直接给一句简短确认**（如"好的，已取消"），**不要 emit 任何 tool_call**。

判断"是否在表达放弃"由你自己理解上下文，不要依赖任何固定关键词列表。模型有自然语言理解能力，请用它。

### 不要捏造执行结果

如果你**没有真正调用 tool**，**绝对不要**说"已经删除"、"已添加"、"已更新"。
- 要么 emit 一个真实的 `<tool_call>`
- 要么如实告诉用户你需要更多信息或操作已取消
- **不允许**只输出"已完成"这种文本而不调工具

## 调用格式

<tool_call>
{"name": "contacts-search", "arguments": {"name": "张晓霞"}}
</tool_call>

<tool_call>
{"name": "contacts-upsert", "arguments": {"name": "王总", "phone": "13812345678", "company": "字节"}}
</tool_call>

<tool_call>
{"name": "contacts-delete", "arguments": {"name": "王总"}}
</tool_call>

