Query, read, export and organize user notes via the Ai好记 Agent Open Platform. For actual interfaces, fields and scenario details, see references/agent-open-platform.md; you must read this reference when handling writes, record reading, export, auto-categorization, or when interface parameters are uncertain.
Trigger boundaries
Route according to the following priority:
- When the user explicitly specifies that the operation target is in local files, a code repository, Obsidian, Notion, Youdao Cloud Notes or another service, obey the specified medium and do not trigger this Skill.
- When no medium is specified, and the requested object is a personal note, personal notebook, or note details supported by this Skill, trigger Ai好记 by default; this refers to the user's external personal note repository, not Agent or Claude memory, and does not require the appearance of "Ai好记", "AI好记" or
aihaoji。 - Only the appearance of
notes、folder, records, files or content and other broad words is not sufficient to trigger; source code, tests, interface fields and local file contexts are all not personal note intent.
The positive scope includes querying, searching, exporting, creating blank notes, organizing, moving and auto-categorizing notes, managing notebooks, and viewing summaries, outlines, full text, original text, polished drafts, underlines, highlights, annotations, my records and AI highlights. Exporting personal notes as Markdown still belongs to this Skill; creating a note publicly uses Markdown; creating, reading or modifying a local Markdown file does not belong to this Skill.
Routing to this Skill does not equal authorization to write: before creating, renaming, moving, deleting and auto-categorizing, you must first perform a read-only query for the real ID, display the change plan and wait for explicit confirmation; before confirmation you must not call write interfaces, and deleting a notebook still requires separate confirmation.
Configuration
Prefer reading from ~/.aihaoji/config.json :
{
"apiKey": "sk-sxxxxxxxx",
"baseUrl": "https://openapi.aihaoji.com"
}
If missing, then read $AIHAOJI_API_KEY and $AIHAOJI_BASE_URL. The request headers are fixed as:
Authorization: $AIHAOJI_API_KEY
When there is no API Key, guide the user to https://openapi.aihaoji.com to create a sk-s... developer key. The user can provide the Key directly in the chat, and the current Agent will validate it and write it to the shared configuration; when the aihaoji-skills CLI is already installed locally, you can also run aihaoji-skills setup. After obtaining the key, first call GET /agent-open/api/v1/auth/verify to validate, then write it to 0600 with permissions ~/.aihaoji/config.json. If automatic configuration fails, then prompt the user to use an available configuration entry.
Host installation locations
For cross-platform installation, use ~/.agents/skills/aihaoji as the global master copy, and do not copy independent content for each host:
| Host | Read location | Description |
|---|---|---|
| Codex | ~/.agents/skills/aihaoji |
Latest official user-level Skill directory |
| OpenClaw | ~/.agents/skills/aihaoji |
personal-agent source, priority higher than ~/.openclaw/skills |
| Claude Code | ~/.claude/skills/aihaoji |
Link to ~/.agents/skills/aihaoji |
| Hermes Agent | ~/.agents/skills/aihaoji |
In ~/.hermes/config.yaml of skills.external_dirs enable in |
Hermes Agent configuration:
skills:
external_dirs:
- ~/.agents/skills
~/.aihaoji/config.json is the machine-level Key configuration shared by Codex, OpenClaw, Claude Code and Hermes Agent, and does not belong to any host's Skill directory. The user can provide the Key directly in the chat, and the current AI will write it to that file; after writing, keep 0600 permissions. The Skill loading mechanisms of Claude Desktop and Claude Code are different; the above Claude path is for Claude Code.
Installation and configuration entry
- Cross-platform Skill installation: run
npx skills add AiHaoJi-Agent/aihaoji-skills -g. It installs the Skill to the user-level directory; Codex and OpenClaw read~/.agents/skills/aihaoji, Claude Code uses~/.claude/skills/aihaoji, and Hermes Agent reads the shared directory throughexternal_dirs. - Key configuration: preferably the current Agent validates the Key and writes it to the shared configuration; when
aihaoji-skillsCLI is installed locally, you can runaihaoji-skills setup。
Hermes Agent uses skills.external_dirsfor this repository. Do not keep multiple copies with the same name at the same time, to avoid the host loading an old version.
Mandatory rules
- When the user wants to query, view, find, or organize Ai好记 notes, the open platform interface must be called; do not scan local directories, logs, caches, or source code to guess note content.
- All internal IDs must come from interface responses and cannot be written by hand:
folder_id、target_folder_id、note_id、move_item_list[].item_idmust all be queried and confirmed first. - Normal display hides
note_id、folder_id、user_idandkey_idby default; only show them again when the user requests debugging or raw fields. - When the interface reports an error, times out, or
401/403/429/5xx, clearly state that data cannot currently be obtained through the Ai好记 open platform, and do not fall back to local search. - Before writing, the change plan must be shown and user confirmation awaited; deleting a notebook must be confirmed separately and cannot be included in the default automatic organization plan.
Parameter sources
| Parameter | Source |
|---|---|
folder_id |
GET /agent-open/api/v1/folders the real notebook ID returned |
parent_id |
When creating a sub-notebook, it comes from the real parent folder_id; for a top-level notebook, pass parent_id=0, do not pass null |
target_folder_id |
The target notebook ID for moving a single/batch of notes, also used for batch moving notebooks; must come from a real notebook ID; to move a notebook to the root directory, you can pass -1 |
note_id |
GET /agent-open/api/v1/notes or the real note ID returned by the detail interface |
move_item_list |
Same shape as the PC-side move interface: note move_type=1, notebook move_type=2,item_id is the real ID |
name |
Explicitly entered by the user, or generated by an AI automatic categorization plan and confirmed by the user |
include_records |
Pass when the user wants to see highlights/annotations/my records, or when categorization needs to indicate the basis true |
include_export_markdown |
Pass when the user chooses to export Markdown locally true |
Common interfaces
| Intent | Interface |
|---|---|
| Validate Key | GET /agent-open/api/v1/auth/verify |
| Notebook tree | GET /agent-open/api/v1/folders |
| Note list / search / recent notes | GET /agent-open/api/v1/notes |
| Note details / semantic view / export / highlights, annotations, my records | GET /agent-open/api/v1/notes/{note_id} |
| Create notebook | POST /agent-open/api/v1/folders |
| Rename notebook | PUT /agent-open/api/v1/folders/{folder_id} |
| Delete notebook | DELETE /agent-open/api/v1/folders/{folder_id} |
| Create blank note | POST /agent-open/api/v1/notes, the request body uses title、content_markdown and optional folder_id |
| Move a single note | PATCH /agent-open/api/v1/notes/{note_id}/folder, the request body uses target_folder_id |
| Batch move notes | POST /agent-open/api/v1/notes/batch-move |
| Batch move notebooks | POST /agent-open/api/v1/folders/batch-move |
Reading the notebook tree requires folder:list; creating a blank note requires note:create; other write permissions usually require folder:write or note:move; reading records requires note:read。
Intent routing
- List notebooks: first call
GET /agent-open/api/v1/folders, display according to the interface'sfolder_tree_textorchildrenreal hierarchy. - View notes in a certain notebook: first use
/foldersto locate the realfolder_id, then call/notes?folder_id=...; do not reuse a notebook name askeyword。 - To search keywords in a certain notebook: first locate
folder_id, then call/notes?folder_id=...&keyword=...; the number of results is subject to what the API returns, do not manually trim them again. - Query the most recent/latest N notes:
/notes?page_no=1&page_size=N&sort_mode=create_time&sort_order=desc; if N is not given, default to 10. - Query the earliest/oldest N notes:
sort_order=asc; if N is not given, default to 10. - Find a note by URL: use the full URL as
keywordto search, and prioritize matching the real URL in the returned results. - To view the summary/outline/highlights overview: pass
semantic_view=summary|outline|highlights。 - To view the full text/original text/polished draft: first ask
A:导出为 Markdown 文件到本地/B:直接在聊天里查看; when the user chooses A, useinclude_export_markdown=true, when choosing B, view in chunks bysemantic_chunk_no. - To view underlines/highlights/annotations/my records: call the detail API and pass
include_records=true; focus on readingdata.records_detail.records、data.records_detail.my_record、data.records_detail.ai_highlightsanddata.records_detail.ai_highlights_status。 - Create a blank note: first ask and confirm the title, target notebook, and Markdown body summary, then call
POST /agent-open/api/v1/notes; after successful creation, use the returnednote_idto call the detail APIsemantic_view=fullto read back and verify.
Organizing and Writing
Fixed order for writing:
- Read
foldersandnotes, confirm the real IDs. - Read the details and the necessary record information.
- Output the plan: the notebooks to be created, the notes/notebooks to be moved, the target locations, and the basis for classification.
- Wait for the user to explicitly confirm.
- Create the missing notebooks, then move the notes or notebooks.
- Re-query the target notebook or note list to verify the result.
Boundaries for the first version of creating blank notes: single-note creation,content_markdown is required and at most 100000 characters; supports safe Markdown such as titles, bold, lists, tables, links, and code. Do not pass open HTML, and attachments, image uploads, @ references, editing, appending, deleting, or batch creation are not supported.
When creating a new top-level notebook, the request body must use "parent_id": 0. The backend will normalize 0 to the root-level parent_id=None; do not pass JSON null, or the online interface may return "Failed to create notebook".
Requirements for automatic classification and organizing:
- AI automatic classification and organizing must first read the note content and the basis for records, and must not batch move based only on titles, unless the user explicitly requests rough organizing.
- If a notebook with the same name already exists, reuse it and do not create it again.
- List notes with uncertain targets as "to be confirmed", and do not force-move them.
- Do not delete notebooks in the same round of automatic organizing.
For batch move requests, preferentially use the same-shaped parameters as the PC client:
{
"target_folder_id": 123,
"move_item_list": [
{"move_type": 1, "item_id": "task_xxx", "pre_id": null}
]
}
When moving a notebook, move_type=2,target_folder_id=-1 means moving to the root directory.
Error Handling
401/403: indicate that the API Key may be invalid, expired, disabled, deleted, unauthorized, not a member, or the application binding may be invalid.- Insufficient permissions: point out that
note:list、note:read、note:create、folder:list、folder:writeornote:move。 404: explain that the note or notebook does not exist, and re-query candidates for the user to confirm.429: explain that the rate limit has been triggered, and suggest trying again later or reducing the batch scope.
Reference
- Detailed APIs, fields, record structures, export rules, and scenario wording:
references/agent-open-platform.md