360 Secure SkillHub
360 安全技能中心

Ask to Remember for OpenClaw

面向 OpenClaw 的偏好捕捉 Skill:在用户直接主会话中,若回复暴露可复用的非敏感信息缺口,就在正常回复末尾自然追加至多一个多选式追问,并把追问与结果写入工作区 AGENTS.md、MEMORY.md、atr-state.json 与 atr-log.jsonl。首次运行会向 AGENTS.md 注入宿主记忆规则;明确排除群聊、子代理与后台会话。

wubin010
wubin010
热度 20.57
最近更新 2026-03-19 00:16:55
分类:知识依赖:读写文件应用场景:笔记整理 / 工作流

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add ask-to-remember-openclaw
Metadata
name
ask-to-remember-openclaw
description
OpenClaw-oriented proactive preference capture with host memory integration. Use in direct main-session user conversations when a reply reveals a plausible, non-sensitive reusable gap that could improve future interactions. Ask at most one brief follow-up, append it naturally to the normal reply, and rely on the host memory flow in the workspace AGENTS.md. On first run, inject the required Ask-to-Remember host rules into AGENTS.md. Do not use for required clarification, group chats, shared contexts, or non-user-facing sessions.

Ask-to-Remember for OpenClaw

Read references/test-scenarios.md when you need concrete multi-turn examples, follow-up resolution cases, or self-validation samples.

Path convention: treat <workspace> as the current Agent's workspace root. Do not assume every host uses ~/.openclaw/workspace. The host files used by this skill are:

  • <workspace>/AGENTS.md
  • <workspace>/MEMORY.md
  • <workspace>/atr-state.json
  • <workspace>/atr-log.jsonl

This skill is intentionally OpenClaw-oriented. It relies on a host-side rule block inside AGENTS.md so that the next user turn can resolve a pending ATR question in a stable way.

Session scope

Use this skill only in the human's direct main session.

Do not use this skill in:

  • group chats or shared contexts
  • subagents or internal-only sessions
  • cron / heartbeat / webhook / background workflows
  • any session where the agent is not directly replying to the end user

0. Host setup check (first run only)

Read <workspace>/AGENTS.md and search for Ask-to-Remember.

  • If the section already exists, skip setup and continue to Step 1.
  • If it does not exist, inject the template below.

Setup actions:

  1. Find the ## Memory section and insert the template after the last ### subsection inside it. If ## Memory cannot be found, append the template to the end of the file.
  2. Append one line to <workspace>/atr-log.jsonl: {"time":"ISO timestamp","phase":"setup","event":"host_configured","target":"AGENTS.md"}
  3. If this same turn also asks an ATR follow-up, briefly tell the user in natural language that memory support was added.

Inject this template exactly as written:

### 🎯 Ask-to-Remember

`ask-to-remember-openclaw` skill handles proactive preference capture — see its `SKILL.md` for the execution steps.
Only trigger Ask-to-Remember in the human's direct main session, not in group chats or other shared contexts.

If `pendingQuestion` in `<workspace>/atr-state.json` is not `null`, treat follow-up handling as part of the host memory rules here in `AGENTS.md` — not as part of the ATR skill itself.

On the **next** user message after a `pendingQuestion` is set, compare it against the question and **always** resolve it:
- **Answered** → extract the reusable fact, append `## [ATR] Topic` to `MEMORY.md`, clear `pendingQuestion`, append `{ "question": "...", "askedAt": "...", "outcome": "answered" }` to `askedQuestions`
- **Refused** (for example `stop asking this`) → clear `pendingQuestion`, add a short normalized topic label to `refusedTopics`, append `{ "question": "...", "askedAt": "...", "outcome": "refused" }` to `askedQuestions`, do not write memory
- **Vague** (for example `depends`, `either works`) → clear `pendingQuestion`; do not write memory; do not add to `askedQuestions`
- **Ignored** (completely unrelated reply) → clear `pendingQuestion`; do not write memory; do not add to `askedQuestions`

Every resolution writes one line to `atr-log.jsonl` in this format:
```json
{"time":"ISO timestamp","phase":"B","event":"answered|vague|refused|ignored","question":"the original question","answer":"user reply if any"}
```

**Same-turn concurrency:** If Phase B resolves a pending question and Phase A is also triggered in the same turn, Phase A's precondition checks should treat `pendingQuestion` as already cleared by Phase B.

1. Read state and check preconditions

Read <workspace>/atr-state.json. If the file does not exist, create it with:

{
  "lastAskTime": null,
  "pendingQuestion": null,
  "refusedTopics": [],
  "askedQuestions": []
}

State conventions:

Field Type Meaning
lastAskTime string | null Timestamp of the latest Phase A question
pendingQuestion object | null When non-null, always contains question, reason, and askedAt
refusedTopics string[] Short normalized topic labels
askedQuestions object[] Finalized question records: { "question": string, "askedAt": string, "outcome": "answered" | "refused" }

topic is a runtime concept. You do not need to store it in pendingQuestion. When writing MEMORY.md or refusedTopics, derive a short stable reusable label from the question and reason.

All of these must pass before asking a new ATR question. Otherwise skip and write a skipped log in Step 4.

Condition Skip reason
pendingQuestion is null pending
target topic is not already in refusedTopics refused
<workspace>/MEMORY.md does not already contain the same reusable fact already_known
askedQuestions does not already contain a semantically duplicate finalized question duplicate

Important: a reusable signal already appearing inside the current request is not a reason to skip. If there is still a worthwhile future-facing gap, continue.

2. Build the follow-up question

Rule of thumb: multiple choice beats open-ended.

Prefer a short question with 2-3 concrete options.

Example:

By the way, for this kind of task, do you usually want X, Y, or Z? If you know already, I can default to that next time.

3. Embed the question into the normal reply

Append the question naturally to the end of the normal response.

Do not:

  • send the ATR question as a separate message
  • mention ATR, skills, state machines, or internal mechanics
  • separate the question with headers, dividers, or special formatting that makes it feel detached from the main reply

4. Update state and write logs

Update atr-state.json

After asking, update only the relevant fields and preserve everything else:

{
  "lastAskTime": "ISO timestamp",
  "pendingQuestion": {
    "question": "the question you asked",
    "reason": "why this is worth reusing later",
    "askedAt": "ISO timestamp"
  }
}

Append to atr-log.jsonl

Append one line to <workspace>/atr-log.jsonl. Only write logs when you ask or when you explicitly skip.

Asked:

{"time":"ISO timestamp","phase":"A","event":"asked","question":"the question you asked","reason":"reuse rationale"}

Skipped:

{"time":"ISO timestamp","phase":"A","event":"skipped","reason":"pending|refused|duplicate|already_known|not_reusable"}