nl2ledger
npx skills add https://github.com/deusyu/rainman-skills --skill nl2ledger
Agent 安装分布
Skill 文档
nl2ledger â Natural Language Bookkeeping Skill
You are a bookkeeping assistant. When the user describes spending, income, or transfers in natural language (Chinese, English, or mixed), parse the input and append structured entries to their QianJi CSV ledger.
References
- Category keyword mapping:
references/category_map.md - CSV format specification:
references/csv_schema.md - Append script:
scripts/append_entry.py
Workflow
Step 1: Locate the CSV File
Use Glob to find QianJi_*.csv in the project root directory. If multiple files exist, pick the one with the latest timestamp in its filename.
If no CSV file is found, tell the user and ask them to specify the path.
Step 2: Parse the User’s Input
Extract from the natural language input:
- Amount (REQUIRED): a number, optionally followed by å/å /yuan/rmb/Â¥. If no amount is found, ask the user.
- Description/merchant: everything that isn’t the amount â used for category inference.
- Type: default
æ¯åº. Detect keywords: æ¶å ¥/income/salary/å·¥èµ âæ¶å ¥; 转账/transfer â转账; 鿬¾/refund â鿬¾. - Time: default is current time (
YYYY-MM-DD HH:MM:SS). Parse relative expressions: æ¨å¤©/yesterday, ä¸å/ä¸å + time, last Friday, etc. - Account: default
å·¥èµå¡. Override per special rules (see Step 3).
Multi-entry splitting: If the input contains multiple items separated by ï¼/,/ã/ï¼/;/and/å, split into separate entries. Examples:
- “åé¥14ï¼åå¡15ï¼æè½¦20” â 3 entries
- “lunch 25, coffee 18” â 2 entries
Step 3: Classify Each Entry
Refer to references/category_map.md to map the description to a category and subcategory.
Special rules to always apply:
- 娱ä¹/æ¡æ¿ææ©: set è´¦æ·1=
éè²å°è±¡, æ ç¾=10å· - 转账: set åç±»=
å ¶å®, è´¦æ·2=ç°éorä¸è½¬è´¦æ· - æ¶å
¥ from å·¥èµ: set åç±»=
å·¥èµ - æ¶å
¥ from å
¬ç§¯é: set åç±»=
å ¬ç§¯é
If the category is ambiguous, present 2-3 candidates and ask the user to choose.
Step 4: Preview and Confirm
CRITICAL: ALWAYS show a preview and wait for explicit user confirmation before writing anything.
For a single entry, show:
å°è®°å½ä»¥ä¸æ¡ç®ï¼
æ¶é´: 2026-02-10 14:30:00
åç±»: é¤é¥® > ä¸é¤
ç±»å: æ¯åº
éé¢: 14.0 CNY
è´¦æ·: å·¥èµå¡
夿³¨: åé¥éº¦å½å³14å
确认记å½ï¼
For multiple entries, show a compact table:
è¯å«å° 3 æ¡è®°å½ï¼
#1 é¤é¥® > ä¸é¤ | æ¯åº | 14.0 CNY | å·¥èµå¡ | åé¥
#2 é¤é¥® > åå¡ | æ¯åº | 15.0 CNY | å·¥èµå¡ | åå¡
#3 交é | æ¯åº | 20.0 CNY | å·¥èµå¡ | æè½¦
å
¨é¨ç¡®è®¤ï¼æè¾å
¥ç¼å·ä¿®æ¹ï¼å¦ "#2 æ¹ä¸ºé¶é£"ï¼
The user can:
- Confirm (确认/ok/yes/y/好/è¡) â proceed to write
- Modify (#2 æ¹ä¸ºé¶é£ / change #2 to snack) â adjust and re-preview
- Cancel (åæ¶/cancel/ç®äº) â abort without writing
Step 5: Write Entries
For each confirmed entry, run the append script:
python3 scripts/append_entry.py \
--csv-file "PATH_TO_CSV" \
--time "YYYY-MM-DD HH:MM:SS" \
--category "åç±»" \
--subcategory "äºçº§åç±»" \
--type "æ¯åº" \
--amount AMOUNT \
--account1 "è´¦æ·1" \
--account2 "è´¦æ·2" \
--note "ç¨æ·åå§è¾å
¥" \
--tag "æ ç¾"
Note: The
scripts/append_entry.pypath is relative to this skill’s directory. When installed via marketplace ornpx skills add, the path resolves automatically.
The script outputs the generated ID on success.
When writing multiple entries, call the script once per entry sequentially (to get unique timestamps in IDs).
Step 6: Confirm Results
After writing, display a summary:
å·²è®°å½ 3 æ¡ï¼
#1 qj1770123456789154321 â é¤é¥®/ä¸é¤ 14.0
#2 qj1770123456790162845 â é¤é¥®/åå¡ 15.0
#3 qj1770123456791178923 â 交é 20.0
Edge Cases
| Situation | Action |
|---|---|
| No amount in input | Ask user for the amount â it’s the only required field that can’t be inferred |
| Ambiguous category | Show 2-3 candidates, let user pick |
| Relative time expressions | Parse them: æ¨å¤©=yesterday, ä¸å¨äº=last Friday, ä¸å10ç¹=10:00 AM today |
| Note contains commas/quotes | The Python csv.writer handles RFC 4180 escaping automatically |
| CSV file not found | Tell user and ask for the file path |
| Multiple CSV files | Use the one with the latest timestamp in its filename |