Two steps: first perform "information dehydration" on the material, then use the style Profile to "inject the soul", and finally output the exclusive manuscript in one go.
Core Process
0. Environment Preparation (First Execution)
Before running any script, first prepare .venv. The following approach does not depend on a fixed absolute path:
ROOT_DIR="$(cd ../.. && pwd)"
PYTHON_BIN="$ROOT_DIR/.venv/bin/python"
test -d "$ROOT_DIR/.venv" || python3 -m venv "$ROOT_DIR/.venv"
"$PYTHON_BIN" -m pip install -U pip
"$PYTHON_BIN" -m pip install -U powermem python-dotenv
All subsequent Python scripts are executed using $PYTHON_BIN , without depending on whether the current shell has activated the virtual environment.
Configuration Management Notes:
- On first use, the script will automatically create the
../pmem-config/shared configuration directory - containing
pmem-key.env(user configuration) and.env(full template) - Configuration priority: system environment variables >
pmem-config/pmem-key.env>pmem-config/.env - The two skills (extraction and generation) share the same configuration, so configuring once is enough
0.1 Configuration Check (Required Step)
The configuration check must be executed before each run:
"$PYTHON_BIN" scripts/check_config.py
If the configuration check fails (exit code is 1):
-
Check output description (fixed text is retained in the Skill; only missing items are dynamically output by the script):
# 运行配置检测(脚本会动态输出“当前缺失的配置项”) "$PYTHON_BIN" scripts/check_config.pyOutput structure example (the list of missing items is subject to the script's actual check results):
⚠️ 检测到以下配置项缺失或未设置: [这里的缺失项列表由 check_config.py 动态输出] 📝 共享配置文件位置: /path/to/skills/pmem-config/pmem-key.env 请点击上面的共享配置文件路径,进入文件夹后手动编辑文件:`pmem-key.env`。 手动填写完成后,返回聊天框回复:已完成 -
The Agent should perform the following operations:
- Clearly inform the user of the shared configuration directory path:
../pmem-config/ - Clearly inform the user of the filename that needs to be edited:
pmem-key.env - Do not collect configuration values item by item in the conversation; only wait for the user to fill them in manually
- After the user replies "completed", rerun
check_config.pyto verify the configuration
- Clearly inform the user of the shared configuration directory path:
-
Configuration writing example:
# 用户手动打开并编辑:../pmem-config/pmem-key.env # 在文件中填写缺失项,例如: LLM_API_KEY=sk-xxxxx EMBEDDING_API_KEY=sk-yyyyy # 重新检测 "$PYTHON_BIN" scripts/check_config.py -
Important Notes:
- The configuration will be persistently saved in
../pmem-config/pmem-key.env - There is no need to reconfigure when using either skill next time
- Users can also manually edit this file to modify the configuration
- The configuration will be persistently saved in
After the configuration check passes, continue with the subsequent steps.
1. Confirm the Creation Instructions
Clarify the following information from the user input (if anything is missing, proactively ask):
| Parameter | Description | Example |
|---|---|---|
| Target platform | Determines the style and length | Twitter, Xiaohongshu, WeChat official account, general long-form article |
| Style intent | The user's vague description (not a technical profile_id) | "lighter", "professional and serious", "emotional" |
| Original material | The original content to be created (article/URL/list of key points) | Paste an article, provide a URL, list a few facts |
If the user provides URL material, first call baoyu-url-to-markdown to obtain the content:
SKILL_URL_DIR="$HOME/.cursor/skills/baoyu-url-to-markdown"
npx -y bun ${SKILL_URL_DIR}/scripts/main.ts <url> -o /tmp/source_content.md
2. Information Dehydration (Neutral Outline Extraction)
Do not call any style, and only perform objective information extraction on the original material. Use the following Prompt:
你是一位中立的信息提炼专家。请从下面的素材中提取纯粹的事实信息和核心论点,不加入任何情感或风格倾向。
输出格式为结构化大纲:
## 核心主题
[一句话概括素材的主题]
## 关键事实
- [事实1]
- [事实2]
- [事实3,最多5-8条]
## 核心论点/观点
- [论点1]
- [论点2]
## 数据与引用
- [数据或引用(如有)]
## 背景上下文
[必要背景信息,1-3句]
待提炼素材:
---
{MATERIAL}
---
Save the extraction result as /tmp/material_outline.md。
3. Intelligent Style Profile Matching (Human-in-the-loop)
Key improvements: Instead of directly using a fixed Profile, intelligently match based on user intent and have the user confirm.
"$PYTHON_BIN" scripts/match_profile.py \
--intent "用小红书风格写,轻松一点" \
--output /tmp/selected_profile.json
The script will:
- Analyze user intent keywords ("Xiaohongshu", "relaxed")
- Match the tags, suitable_platforms, and tone of all Profiles
- Sort by match score and display the top 5
- Have the user confirm the selection (enter the number)
- Return the selected Profile
Output example:
🎯 根据您的需求,推荐以下风格:
1. [xiaohongshu-casual] 小红书轻松版
匹配原因:适合小红书平台, 风格特点:轻松, 风格特点:口语化
说明:适合日常分享类内容,语气轻松亲切
标签:轻松, 口语化, 亲切
平台:小红书
2. [default] 默认风格
匹配原因:适合小红书平台
平台:小红书, 公众号, 通用
请选择要使用的风格(输入序号),或输入 0 退出:
> 1
✅ 已选择:[xiaohongshu-casual] 小红书轻松版
If there is no match at all:
⚠️ 未找到精确匹配,以下是所有可用风格:
1. [default] 默认风格
理性克制,适合通用内容
2. [tech-article] 技术文章风格
专业严谨,适合技术博客
请选择要使用的风格(输入序号),或输入 0 退出:
Read the selected Profile from the returned JSON:
# 读取选定的 Profile
profile_id=$(jq -r '.profile_id' /tmp/selected_profile.json)
4. Assemble the Compiler Prompt
Read /tmp/active_profile.json, extract the style parameters from it, combine them with the platform rules (see references/platform_templates.md), and assemble the final Prompt.
Use the following Compiler template:
你是一位专业的自媒体内容创作者,拥有鲜明的个人写作风格。
## 你的写作风格指令(必须严格遵守,不可违背)
**叙事节奏**:{narrative_rhythm}
**金句位置**:{key_phrase_placement}
**排版符号**:{formatting_symbols}
**标点习惯**:{punctuation_habits}
**段落结构**:{paragraph_structure}
**情感基调**:{emotional_tone}
**修辞手法**:{rhetorical_devices}
**开篇风格**:{opening_style}
**结尾风格**:{closing_style}
## 当次创作任务
**目标平台**:{platform}
**平台规范**:{platform_rules}
## 素材大纲(核心事实,保持中立使用,不可凭空添加)
{material_outline}
## 输出要求
基于以上素材,完全按照你的写作风格,为{platform}创作一篇文章。
- 素材中的事实不可歪曲,但表达方式完全按你的风格来
- 严格遵守平台字数和格式规范
- 直接输出正文,无需说明你在做什么
Replace {...} with the actual values, then directly call the LLM to execute.
5. Output the draft, record the log, and automatically save to disk
First save the final body text returned by the LLM to a temporary file /tmp/generated_body.md, then record this generation log (for Reflection Skill traceability):
"$PYTHON_BIN" scripts/log_generation.py \
--profile-id <profile_id> \
--platform <platform> \
--topic "<核心主题一句话>" \
--output /tmp/generation_log.json
Next, automatically save the final body text to the specified path (default outputs/):
"$PYTHON_BIN" scripts/save_generation.py \
--profile-id <profile_id> \
--log-json /tmp/generation_log.json \
--title "<标题>" \
--content-file /tmp/generated_body.md \
--output-dir outputs
Default filename rule:
outputs/{profile_id}_{generation_id}_{title}.md
Where generation_id comes from /tmp/generation_log.json. After execution, return two pieces of information to the user:
generation_id(for the Reflection Skill to track effectiveness)- The absolute path of the final body text file (for direct viewing/publishing)
Platform specification quick reference
See references/platform_templates.mdfor detailed templates. The core specifications are as follows:
| Platform | Length | Special requirements |
|---|---|---|
| Twitter / X | Each paragraph ≤140 characters, total ≤2000 characters | The first sentence is the hook, the ending encourages sharing |
| Xiaohongshu | 300-800 characters | Use numbers/questions in the title, a moderate amount of emoji in the body, and encourage saving at the end |
| WeChat Official Account | 800-3000 characters | Has subheadings for sections, complete introduction-development-turn-conclusion, and provokes thought at the end |
| General long-form | Free | Follow the style Profile, with a complete structure |
Auxiliary tools
List all available Profiles:
"$PYTHON_BIN" ../pmem-style-extraction/scripts/list_profiles.py --format detailed
View generation logs:
"$PYTHON_BIN" scripts/log_generation.py --list
Save the final body text to outputs/:
"$PYTHON_BIN" scripts/save_generation.py \
--profile-id <profile_id> \
--log-json /tmp/generation_log.json \
--title "<标题>" \
--content-file /tmp/generated_body.md
Usage examples
The simplest usage:
用户:"帮我写一篇小红书,素材是这篇文章:[粘贴文章]"
Agent:
1. 脱水 → 提取核心事实
2. 智能匹配 Profile(意图:"小红书")→ 展示匹配结果 → 用户选择
3. 组装 Compiler Prompt(小红书规范)
4. 输出文稿 + 记录日志 + 自动保存到 outputs/
Specify style characteristics:
用户:"用轻松点的风格,写一篇关于AI的推特长文,素材:[要点列表]"
Agent:
智能匹配(意图:"轻松 推特")→ 展示推荐 Profile → 用户确认 → 生成
Generate from URL:
用户:"把这篇文章改写成公众号风格:https://example.com/article"
Agent:获取网页内容 → 脱水 → 匹配风格 → 用户确认 → 生成
Notes
- The information dehydration step must be executed independently to ensure that the facts in the material are not contaminated by style
- You must use match_profile.py for intelligent matching, have the user confirm the selection, and do not directly use a fixed profile_id
- The user's intent is usually vague ("Xiaohongshu", "a bit more relaxed") rather than a technical profile_id
- All
{...}placeholders in the Compiler Prompt must be fully replaced before sending to the LLM - If a dimension in the Profile is empty, skip that line; do not write "none" or a default value
- Be sure to tell the user the generation log ID, to facilitate subsequent Reflection attribution
- Before running the script, first ensure that
$PYTHON_BINis available and thatpowermem