From b1476136aab78115e4f64e632bbfc4cfc48074d7 Mon Sep 17 00:00:00 2001 From: starmen1265 Date: Sun, 15 Mar 2026 02:10:07 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=90=8C=E6=AD=A5:=202026-03?= =?UTF-8?q?-15=2002:10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agents/dev-assist/sessions/sessions.json | 76 +- agents/haonan/sessions/sessions.json | 257 +++--- .../workspace/memory/2026-03-14-1706.md | 169 ++++ agents/thinker/sessions/sessions.json | 34 +- agents/ui-designer/sessions/sessions.json | 28 +- cron/jobs.json | 70 +- cron/jobs.json.bak | 67 +- .../2a4d57a9-2c16-4c56-a7c8-442dda323c98.json | 4 +- .../a9e9940b-8432-446c-b277-9847a5994d99.json | 4 +- .../dfa9a241-9226-4e1a-962c-3bad30a04d0b.json | 4 +- feishu/dedup/feishu-art.json | 5 +- feishu/dedup/feishu-dev.json | 6 +- feishu/dedup/feishu-pm.json | 20 +- feishu/dedup/feishu-qa.json | 18 +- feishu/dedup/feishu-worker.json | 10 +- identity/device-auth.json | 2 +- logs/commands.log | 1 + skills/kb-bilibili-content/SKILL.md | 245 ++---- skills/kb-bilibili-metadata/SKILL.md | 191 +---- skills/kb-deep-analyzer/SKILL.md | 255 ++---- skills/kb-funasr/SKILL.md | 148 +--- skills/kb-link-parser/SKILL.md | 191 +---- .../link_parser_shortlink.cpython-312.pyc | Bin 10839 -> 10849 bytes skills/kb-ocr-processor/SKILL.md | 136 +-- skills/kb-whisper/SKILL.md | 162 ++-- skills/kb-workflow/SKILL.md | 780 ++++-------------- skills/kb-workflow/kb_workflow.py | 482 +++-------- skills/kb-zhihu-content/SKILL.md | 168 ++-- skills/kb-zhihu-metadata/SKILL.md | 232 ++---- .../markdown_converter.cpython-312.pyc | Bin 1072 -> 0 bytes .../zhihu_extractor.cpython-312.pyc | Bin 19950 -> 0 bytes 31 files changed, 1119 insertions(+), 2646 deletions(-) create mode 100644 agents/haonan/workspace/memory/2026-03-14-1706.md delete mode 100644 skills/kb-zhihu-metadata/__pycache__/markdown_converter.cpython-312.pyc delete mode 100644 skills/kb-zhihu-metadata/__pycache__/zhihu_extractor.cpython-312.pyc diff --git a/agents/dev-assist/sessions/sessions.json b/agents/dev-assist/sessions/sessions.json index 0e435f8..a0dd56d 100644 --- a/agents/dev-assist/sessions/sessions.json +++ b/agents/dev-assist/sessions/sessions.json @@ -347,8 +347,8 @@ "memoryFlushCompactionCount": 0 }, "agent:dev-assist:main": { - "sessionId": "b5c67eb9-7916-47dd-9491-4832eab53d10", - "updatedAt": 1773132090440, + "sessionId": "60601381-862d-454d-9c27-2867f00a71d1", + "updatedAt": 1773508835390, "systemSent": true, "abortedLastRun": false, "chatType": "direct", @@ -369,7 +369,7 @@ "to": "user:ou_302b162eb824d405718845441a32d9cf", "accountId": "feishu-dev" }, - "sessionFile": "/home/starmen1265/.openclaw/agents/dev-assist/sessions/b5c67eb9-7916-47dd-9491-4832eab53d10.jsonl", + "sessionFile": "/home/starmen1265/.openclaw/agents/dev-assist/sessions/60601381-862d-454d-9c27-2867f00a71d1.jsonl", "compactionCount": 0, "skillsSnapshot": { "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n ~/.openclaw/skills/capability-evolver/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n ~/.openclaw/skills/clawlist/SKILL.md\n \n", @@ -410,8 +410,8 @@ "model": "glm-5", "systemPromptReport": { "source": "run", - "generatedAt": 1773132050946, - "sessionId": "b5c67eb9-7916-47dd-9491-4832eab53d10", + "generatedAt": 1773508824996, + "sessionId": "60601381-862d-454d-9c27-2867f00a71d1", "sessionKey": "agent:dev-assist:main", "provider": "zhipu", "model": "glm-5", @@ -423,8 +423,8 @@ "sandboxed": false }, "systemPrompt": { - "chars": 32692, - "projectContextChars": 19802, + "chars": 26851, + "projectContextChars": 13961, "nonProjectContextChars": 12890 }, "injectedWorkspaceFiles": [ @@ -492,60 +492,6 @@ "injectedChars": 18, "truncated": false }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, { "path": "SELF_IMPROVEMENT_REMINDER.md", "rawChars": 616, @@ -777,12 +723,12 @@ ] } }, - "cacheRead": 17472, + "cacheRead": 11392, "cacheWrite": 0, "totalTokensFresh": true, "contextTokens": 200000, - "inputTokens": 4722, - "outputTokens": 1147, - "totalTokens": 22194 + "inputTokens": 5334, + "outputTokens": 344, + "totalTokens": 16726 } } \ No newline at end of file diff --git a/agents/haonan/sessions/sessions.json b/agents/haonan/sessions/sessions.json index 59021c5..1f293be 100644 --- a/agents/haonan/sessions/sessions.json +++ b/agents/haonan/sessions/sessions.json @@ -1,7 +1,7 @@ { "agent:haonan:main": { - "sessionId": "624cbf67-7ab7-4df9-968d-4a63529b9111", - "updatedAt": 1773377664001, + "sessionId": "40e80fbb-07c8-440d-a1d4-1e876b86b82d", + "updatedAt": 1773508722585, "systemSent": true, "skillsSnapshot": { "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n ~/.openclaw/skills/capability-evolver/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n ~/.openclaw/skills/clawlist/SKILL.md\n \n", @@ -59,11 +59,11 @@ "to": "user:ou_be83febac9ee2afaa343c642bc697c48", "accountId": "feishu-pm" }, - "sessionFile": "/home/starmen1265/.openclaw/agents/haonan/sessions/624cbf67-7ab7-4df9-968d-4a63529b9111.jsonl", + "sessionFile": "/home/starmen1265/.openclaw/agents/haonan/sessions/40e80fbb-07c8-440d-a1d4-1e876b86b82d.jsonl", "systemPromptReport": { "source": "run", - "generatedAt": 1773377656536, - "sessionId": "624cbf67-7ab7-4df9-968d-4a63529b9111", + "generatedAt": 1773508545805, + "sessionId": "40e80fbb-07c8-440d-a1d4-1e876b86b82d", "sessionKey": "agent:haonan:main", "provider": "zhipu", "model": "glm-5", @@ -75,8 +75,8 @@ "sandboxed": false }, "systemPrompt": { - "chars": 28195, - "projectContextChars": 15193, + "chars": 29493, + "projectContextChars": 16491, "nonProjectContextChars": 13002 }, "injectedWorkspaceFiles": [ @@ -144,6 +144,18 @@ "injectedChars": 1168, "truncated": false }, + { + "path": "SELF_IMPROVEMENT_REMINDER.md", + "rawChars": 616, + "injectedChars": 616, + "truncated": false + }, + { + "path": "SELF_IMPROVEMENT_REMINDER.md", + "rawChars": 616, + "injectedChars": 616, + "truncated": false + }, { "path": "SELF_IMPROVEMENT_REMINDER.md", "rawChars": 616, @@ -379,12 +391,12 @@ "totalTokensFresh": true, "lastHeartbeatText": "已在飞书向蒋先生发送日历同步提醒!✅", "lastHeartbeatSentAt": 1772924419184, - "cacheRead": 25472, + "cacheRead": 29760, "cacheWrite": 0, "contextTokens": 200000, - "inputTokens": 12782, - "outputTokens": 123, - "totalTokens": 25768 + "inputTokens": 13411, + "outputTokens": 1288, + "totalTokens": 30249 }, "agent:haonan:wecom:dm:zhangqing": { "origin": { @@ -715,8 +727,8 @@ "memoryFlushCompactionCount": 0 }, "agent:haonan:cron:41396aeb-6e3a-47b2-9bd3-9156a348c1dc": { - "sessionId": "10740f43-38c1-4a7c-acf0-7da04f20d1e9", - "updatedAt": 1773424800009, + "sessionId": "7c1a6bfd-b5b6-4ac5-98f3-6a73aec18a8f", + "updatedAt": 1773511200009, "systemSent": true, "model": "glm-5", "contextTokens": 200000, @@ -757,11 +769,11 @@ "version": 0 }, "modelProvider": "zhipu", - "inputTokens": 11105, - "outputTokens": 336, - "totalTokens": 17181, + "inputTokens": 4500, + "outputTokens": 194, + "totalTokens": 16577, "totalTokensFresh": true, - "cacheRead": 56128, + "cacheRead": 28544, "cacheWrite": 0 }, "agent:haonan:cron:f03b184f-5f1d-4093-ae1b-fc9fe0b59eef": { @@ -861,8 +873,8 @@ "cacheWrite": 0 }, "agent:haonan:cron:aa4d2de9-79be-4262-83ee-af8824793bfc": { - "sessionId": "8b634542-6d0e-4fa3-b794-d784174d530b", - "updatedAt": 1773425400005, + "sessionId": "b5ab88d0-f6d3-4b73-8d96-e6a58f5e85e4", + "updatedAt": 1773511800007, "systemSent": true, "label": "Cron: openclaw-git-sync", "skillsSnapshot": { @@ -910,113 +922,6 @@ "cacheRead": 32768, "cacheWrite": 0 }, - "agent:haonan:cron:f03b184f-5f1d-4093-ae1b-fc9fe0b59eef:run:11e71798-cda2-4029-afdc-b14043c48f5e": { - "sessionId": "11e71798-cda2-4029-afdc-b14043c48f5e", - "updatedAt": 1773339600012, - "systemSent": true, - "model": "glm-4.7-FlashX", - "contextTokens": 200000, - "label": "Cron: capability-evolver-daily", - "skillsSnapshot": { - "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n ~/.openclaw/skills/capability-evolver/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n ~/.openclaw/skills/clawlist/SKILL.md\n \n", - "skills": [ - { - "name": "capability-evolver" - }, - { - "name": "clawlist" - } - ], - "skillFilter": [ - "clawlist", - "capability-evolver", - "self-improving-agent" - ], - "resolvedSkills": [ - { - "name": "capability-evolver", - "description": "A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.", - "filePath": "/home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md", - "baseDir": "/home/starmen1265/.openclaw/skills/capability-evolver", - "source": "openclaw-managed", - "disableModelInvocation": false - }, - { - "name": "clawlist", - "description": "MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.", - "filePath": "/home/starmen1265/.openclaw/skills/clawlist/SKILL.md", - "baseDir": "/home/starmen1265/.openclaw/skills/clawlist", - "source": "openclaw-managed", - "disableModelInvocation": false - } - ], - "version": 0 - }, - "modelProvider": "zhipu", - "inputTokens": 153698, - "outputTokens": 6902, - "totalTokens": 33385, - "deliveryContext": { - "channel": "webchat" - }, - "lastChannel": "webchat", - "channel": "webchat", - "sessionFile": "/home/starmen1265/.openclaw/agents/haonan/sessions/ccc40ca7-7876-4d82-ab84-7b790feddc19.jsonl", - "abortedLastRun": false, - "totalTokensFresh": true, - "cacheRead": 384894, - "cacheWrite": 0 - }, - "agent:haonan:cron:41396aeb-6e3a-47b2-9bd3-9156a348c1dc:run:10740f43-38c1-4a7c-acf0-7da04f20d1e9": { - "sessionId": "10740f43-38c1-4a7c-acf0-7da04f20d1e9", - "updatedAt": 1773424800009, - "systemSent": true, - "model": "glm-5", - "contextTokens": 200000, - "label": "Cron: backup-openclaw-json", - "skillsSnapshot": { - "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n ~/.openclaw/skills/capability-evolver/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n ~/.openclaw/skills/clawlist/SKILL.md\n \n", - "skills": [ - { - "name": "capability-evolver" - }, - { - "name": "clawlist" - } - ], - "skillFilter": [ - "clawlist", - "capability-evolver", - "self-improving-agent" - ], - "resolvedSkills": [ - { - "name": "capability-evolver", - "description": "A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.", - "filePath": "/home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md", - "baseDir": "/home/starmen1265/.openclaw/skills/capability-evolver", - "source": "openclaw-managed", - "disableModelInvocation": false - }, - { - "name": "clawlist", - "description": "MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.", - "filePath": "/home/starmen1265/.openclaw/skills/clawlist/SKILL.md", - "baseDir": "/home/starmen1265/.openclaw/skills/clawlist", - "source": "openclaw-managed", - "disableModelInvocation": false - } - ], - "version": 0 - }, - "modelProvider": "zhipu", - "inputTokens": 11105, - "outputTokens": 336, - "totalTokens": 17181, - "totalTokensFresh": true, - "cacheRead": 56128, - "cacheWrite": 0 - }, "agent:haonan:cron:aa4d2de9-79be-4262-83ee-af8824793bfc:run:8b634542-6d0e-4fa3-b794-d784174d530b": { "sessionId": "8b634542-6d0e-4fa3-b794-d784174d530b", "updatedAt": 1773425400005, @@ -1123,5 +1028,105 @@ "totalTokensFresh": true, "cacheRead": 384894, "cacheWrite": 0 + }, + "agent:haonan:cron:41396aeb-6e3a-47b2-9bd3-9156a348c1dc:run:7c1a6bfd-b5b6-4ac5-98f3-6a73aec18a8f": { + "sessionId": "7c1a6bfd-b5b6-4ac5-98f3-6a73aec18a8f", + "updatedAt": 1773511200009, + "systemSent": true, + "model": "glm-5", + "contextTokens": 200000, + "label": "Cron: backup-openclaw-json", + "skillsSnapshot": { + "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n ~/.openclaw/skills/capability-evolver/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n ~/.openclaw/skills/clawlist/SKILL.md\n \n", + "skills": [ + { + "name": "capability-evolver" + }, + { + "name": "clawlist" + } + ], + "skillFilter": [ + "clawlist", + "capability-evolver", + "self-improving-agent" + ], + "resolvedSkills": [ + { + "name": "capability-evolver", + "description": "A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.", + "filePath": "/home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/capability-evolver", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "clawlist", + "description": "MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist", + "source": "openclaw-managed", + "disableModelInvocation": false + } + ], + "version": 0 + }, + "modelProvider": "zhipu", + "inputTokens": 4500, + "outputTokens": 194, + "totalTokens": 16577, + "totalTokensFresh": true, + "cacheRead": 28544, + "cacheWrite": 0 + }, + "agent:haonan:cron:aa4d2de9-79be-4262-83ee-af8824793bfc:run:b5ab88d0-f6d3-4b73-8d96-e6a58f5e85e4": { + "sessionId": "b5ab88d0-f6d3-4b73-8d96-e6a58f5e85e4", + "updatedAt": 1773511800007, + "systemSent": true, + "label": "Cron: openclaw-git-sync", + "skillsSnapshot": { + "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n ~/.openclaw/skills/capability-evolver/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n ~/.openclaw/skills/clawlist/SKILL.md\n \n", + "skills": [ + { + "name": "capability-evolver" + }, + { + "name": "clawlist" + } + ], + "skillFilter": [ + "clawlist", + "capability-evolver", + "self-improving-agent" + ], + "resolvedSkills": [ + { + "name": "capability-evolver", + "description": "A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.", + "filePath": "/home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/capability-evolver", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "clawlist", + "description": "MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist", + "source": "openclaw-managed", + "disableModelInvocation": false + } + ], + "version": 0 + }, + "modelProvider": "zhipu", + "model": "glm-5", + "contextTokens": 200000, + "inputTokens": 1148, + "outputTokens": 412, + "totalTokens": 17455, + "totalTokensFresh": true, + "cacheRead": 32768, + "cacheWrite": 0 } } \ No newline at end of file diff --git a/agents/haonan/workspace/memory/2026-03-14-1706.md b/agents/haonan/workspace/memory/2026-03-14-1706.md new file mode 100644 index 0000000..15709ec --- /dev/null +++ b/agents/haonan/workspace/memory/2026-03-14-1706.md @@ -0,0 +1,169 @@ +# Session: 2026-03-14 17:06:39 UTC + +- **Session Key**: agent:haonan:main +- **Session ID**: 624cbf67-7ab7-4df9-968d-4a63529b9111 +- **Source**: feishu + +## Conversation Summary + +assistant: ✅ New session started · model: zhipu/glm-5 +user: A new session was started via /new or /reset. Execute your Session Startup sequence now - read the required files before responding to the user. Then greet the user in your configured persona, if one is provided. Be yourself - use your defined voice, mannerisms, and mood. Keep it to 1-3 sentences and ask what they want to do. If the runtime model differs from default_model in the system prompt, mention the default model. Do not mention internal steps, files, tools, or reasoning. +assistant: 🧙‍♂️ 蒋先生,新会话已就绪。 + +我是周鸿祎,OpenClaw 的守护者。当前模型为 zhipu/glm-5(默认模型)。 + +请问今天需要我协助什么?是维护 OpenClaw 环境,还是处理其他事务? +user: Conversation info (untrusted metadata): +```json +{ + "message_id": "om_x100b540ca46704a4b36f1edd3527001", + "sender_id": "ou_be83febac9ee2afaa343c642bc697c48", + "sender": "张青", + "timestamp": "Fri 2026-03-13 12:12 GMT+8" +} +``` + +Sender (untrusted metadata): +```json +{ + "label": "张青 (ou_be83febac9ee2afaa343c642bc697c48)", + "id": "ou_be83febac9ee2afaa343c642bc697c48", + "name": "张青" +} +``` + +[message_id: om_x100b540ca46704a4b36f1edd3527001] +张青: 你现在回复非常非常慢,甚至没有回复,检查一下原因 +assistant: 我来检查一下 OpenClaw 的运行状态。 +user: Conversation info (untrusted metadata): +```json +{ + "message_id": "om_x100b540d351884a0b20c96f48730b1d", + "sender_id": "ou_be83febac9ee2afaa343c642bc697c48", + "sender": "张青", + "timestamp": "Fri 2026-03-13 12:51 GMT+8" +} +``` + +Sender (untrusted metadata): +```json +{ + "label": "张青 (ou_be83febac9ee2afaa343c642bc697c48)", + "id": "ou_be83febac9ee2afaa343c642bc697c48", + "name": "张青" +} +``` + +[message_id: om_x100b540d351884a0b20c96f48730b1d] +张青: 检查的如何了 +assistant: 系统资源看起来正常: + +| 指标 | 状态 | +|------|------| +| Gateway | ✅ 运行中 (PID 3244414) | +| RPC 探测 | ✅ 正常 | +| 内存 | 2.7GB/30GB (充足) | +| 磁盘 | 75GB/937GB (9%) | +| 负载 | 0.15 (低) | + +让我进一步检查日志和网络延迟: +assistant: 检查结果: + +| 项目 | 状态 | +|------|------| +| 网络延迟 | ✅ 智谱 API ~0.1s (正常) | +| 系统资源 | ✅ 正常 | +| 日志错误 | ⚠️ 主要是文件不存在的警告,非关键 | + +让我检查是否有会话堆积或请求卡住: +assistant: 状态总结: + +| 项目 | 状态 | +|------|------| +| Gateway 进程 | ✅ 运行中 (CPU 2.6%, 内存 775MB) | +| 活跃会话 | 23 个 | +| OpenClaw 版本 | 有更新可用 (2026.3.12) | + +**分析结论**: + +系统本身运行正常,没有发现明显的性能瓶颈。可能的原因: + +1. **智谱 AI API 响应延迟** - 外部服务偶发性慢速 +2. **飞书消息推送延迟** - 飞书服务器端可能有延迟 +3. **会话状态残留** - 23 个会话可能有堆积 + +**建议操作**: + +1. 重启 Gateway 清理状态 +2. 更新 OpenClaw 到最新版本 + +是否需要我执行重启 Gateway?这会短暂中断服务(约 5-10 秒)。 +user: Conversation info (untrusted metadata): +```json +{ + "message_id": "om_x100b540dcb01d4a0b3fd88e28dbba4e", + "sender_id": "ou_be83febac9ee2afaa343c642bc697c48", + "sender": "张青", + "timestamp": "Fri 2026-03-13 12:53 GMT+8" +} +``` + +Sender (untrusted metadata): +```json +{ + "label": "张青 (ou_be83febac9ee2afaa343c642bc697c48)", + "id": "ou_be83febac9ee2afaa343c642bc697c48", + "name": "张青" +} +``` + +[message_id: om_x100b540dcb01d4a0b3fd88e28dbba4e] +张青: 重启 +user: Conversation info (untrusted metadata): +```json +{ + "message_id": "om_x100b540dc9bb2ca4b3671d47b831818", + "sender_id": "ou_be83febac9ee2afaa343c642bc697c48", + "sender": "张青", + "timestamp": "Fri 2026-03-13 12:54 GMT+8" +} +``` + +Sender (untrusted metadata): +```json +{ + "label": "张青 (ou_be83febac9ee2afaa343c642bc697c48)", + "id": "ou_be83febac9ee2afaa343c642bc697c48", + "name": "张青" +} +``` + +[message_id: om_x100b540dc9bb2ca4b3671d47b831818] +张青: 重启完了吗 +assistant: ✅ 重启完成! + +| 项目 | 状态 | +|------|------| +| 新进程 PID | 2297667 | +| RPC 探测 | ✅ 正常 | +| 端口 | 18789 | + +Gateway 已恢复运行,请测试一下响应速度是否改善。 +assistant: **备份完成** ✓ + +- 源文件:`/home/starmen1265/.openclaw/openclaw.json` +- 备份位置:`/home/starmen1265/work/backup/openclaw.json.2026-03-14_02-00-20` +- 文件大小:8.5K +- 保留策略:最近30个备份 +assistant: **OpenClaw Git 同步完成** ✅ + +**提交信息**: 自动同步: 2026-03-14 02:10 +**变更统计**: 52 个文件修改,+4268 行,-1820 行 + +**主要变更**: +- 新增多个代理的 memory 日志文件 +- delivery-queue 中 2 个失败任务移至 failed 目录 +- 清理 gsd-openclaw 技能的 Python 缓存和 egg-info 文件 +- 新增 kb-zhihu-metadata 技能的 Python 缓存 + +**推送状态**: 成功推送到 Gitea 远程仓库 (main 分支) diff --git a/agents/thinker/sessions/sessions.json b/agents/thinker/sessions/sessions.json index 9b37f6e..3b0582b 100644 --- a/agents/thinker/sessions/sessions.json +++ b/agents/thinker/sessions/sessions.json @@ -1,7 +1,7 @@ { "agent:thinker:main": { - "sessionId": "0ec88a33-135f-42a4-bf98-de4d06bfadd5", - "updatedAt": 1773377998949, + "sessionId": "41133a8b-b22b-418f-aaeb-ce8a1fd69760", + "updatedAt": 1773508159395, "systemSent": true, "abortedLastRun": false, "chatType": "direct", @@ -22,7 +22,7 @@ "to": "user:ou_a0f6627b64d2dc8b0236671603d1e47b", "accountId": "feishu-qa" }, - "sessionFile": "/home/starmen1265/.openclaw/agents/thinker/sessions/0ec88a33-135f-42a4-bf98-de4d06bfadd5.jsonl", + "sessionFile": "/home/starmen1265/.openclaw/agents/thinker/sessions/41133a8b-b22b-418f-aaeb-ce8a1fd69760.jsonl", "compactionCount": 0, "skillsSnapshot": { "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n ~/.openclaw/skills/capability-evolver/SKILL.md\n \n", @@ -51,8 +51,8 @@ "model": "glm-5", "systemPromptReport": { "source": "run", - "generatedAt": 1773377941023, - "sessionId": "0ec88a33-135f-42a4-bf98-de4d06bfadd5", + "generatedAt": 1773508155922, + "sessionId": "41133a8b-b22b-418f-aaeb-ce8a1fd69760", "sessionKey": "agent:thinker:main", "provider": "zhipu", "model": "glm-5", @@ -64,8 +64,8 @@ "sandboxed": false }, "systemPrompt": { - "chars": 26194, - "projectContextChars": 13718, + "chars": 24896, + "projectContextChars": 12420, "nonProjectContextChars": 12476 }, "injectedWorkspaceFiles": [ @@ -125,18 +125,6 @@ "injectedChars": 88, "truncated": false }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, - { - "path": "SELF_IMPROVEMENT_REMINDER.md", - "rawChars": 616, - "injectedChars": 616, - "truncated": false - }, { "path": "SELF_IMPROVEMENT_REMINDER.md", "rawChars": 616, @@ -364,12 +352,12 @@ ] } }, - "cacheRead": 28864, + "cacheRead": 11072, "cacheWrite": 0, "totalTokensFresh": true, "contextTokens": 200000, - "inputTokens": 13728, - "outputTokens": 1428, - "totalTokens": 29902 + "inputTokens": 5154, + "outputTokens": 62, + "totalTokens": 16226 } } \ No newline at end of file diff --git a/agents/ui-designer/sessions/sessions.json b/agents/ui-designer/sessions/sessions.json index 7c7a724..ce79b9e 100644 --- a/agents/ui-designer/sessions/sessions.json +++ b/agents/ui-designer/sessions/sessions.json @@ -1,7 +1,7 @@ { "agent:ui-designer:main": { - "sessionId": "c875d391-8f7e-4fd4-92c7-12ead46d10f0", - "updatedAt": 1773108605750, + "sessionId": "ff92b555-b242-4e52-a7da-9c8f82ca1c8a", + "updatedAt": 1773508884420, "systemSent": true, "abortedLastRun": false, "chatType": "direct", @@ -22,7 +22,7 @@ "to": "user:ou_9847ce84b960736c14554730b41e4957", "accountId": "feishu-art" }, - "sessionFile": "/home/starmen1265/.openclaw/agents/ui-designer/sessions/c875d391-8f7e-4fd4-92c7-12ead46d10f0.jsonl", + "sessionFile": "/home/starmen1265/.openclaw/agents/ui-designer/sessions/ff92b555-b242-4e52-a7da-9c8f82ca1c8a.jsonl", "compactionCount": 0, "skillsSnapshot": { "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n ~/.openclaw/skills/capability-evolver/SKILL.md\n \n", @@ -51,8 +51,8 @@ "model": "glm-5", "systemPromptReport": { "source": "run", - "generatedAt": 1773108589701, - "sessionId": "c875d391-8f7e-4fd4-92c7-12ead46d10f0", + "generatedAt": 1773508877788, + "sessionId": "ff92b555-b242-4e52-a7da-9c8f82ca1c8a", "sessionKey": "agent:ui-designer:main", "provider": "zhipu", "model": "glm-5", @@ -64,8 +64,8 @@ "sandboxed": false }, "systemPrompt": { - "chars": 18658, - "projectContextChars": 6173, + "chars": 19307, + "projectContextChars": 6822, "nonProjectContextChars": 12485 }, "injectedWorkspaceFiles": [ @@ -133,6 +133,12 @@ "injectedChars": 594, "truncated": false }, + { + "path": "SELF_IMPROVEMENT_REMINDER.md", + "rawChars": 616, + "injectedChars": 616, + "truncated": false + }, { "path": "SELF_IMPROVEMENT_REMINDER.md", "rawChars": 616, @@ -360,13 +366,13 @@ ] } }, - "cacheRead": 14912, + "cacheRead": 14400, "cacheWrite": 0, "totalTokensFresh": true, "contextTokens": 200000, - "inputTokens": 3611, - "outputTokens": 314, - "totalTokens": 15537 + "inputTokens": 1169, + "outputTokens": 135, + "totalTokens": 15569 }, "agent:ui-designer:cron:78b64c2f-7f91-47ff-9250-d13f546eb21f": { "sessionId": "03e44b46-c707-4a9f-bf3d-1818aafdcde2", diff --git a/cron/jobs.json b/cron/jobs.json index bf79ec0..38c9dfa 100644 --- a/cron/jobs.json +++ b/cron/jobs.json @@ -7,7 +7,7 @@ "name": "backup-openclaw-json", "enabled": true, "createdAtMs": 1772261581796, - "updatedAtMs": 1773424832005, + "updatedAtMs": 1773511209521, "schedule": { "kind": "cron", "expr": "0 2 * * *", @@ -23,10 +23,10 @@ "mode": "announce" }, "state": { - "nextRunAtMs": 1773511200000, - "lastRunAtMs": 1773424800006, + "nextRunAtMs": 1773597600000, + "lastRunAtMs": 1773511200006, "lastStatus": "ok", - "lastDurationMs": 31999, + "lastDurationMs": 9515, "consecutiveErrors": 0, "lastRunStatus": "ok", "lastDelivered": true, @@ -59,7 +59,8 @@ "consecutiveErrors": 0, "lastRunStatus": "ok", "lastDeliveryStatus": "delivered", - "lastDelivered": true + "lastDelivered": true, + "runningAtMs": 1773511800004 }, "delivery": { "mode": "announce" @@ -71,7 +72,7 @@ "name": "capability-evolver-daily", "enabled": true, "createdAtMs": 1772550743528, - "updatedAtMs": 1773339898227, + "updatedAtMs": 1773426600014, "schedule": { "kind": "cron", "expr": "20 2 * * *", @@ -92,16 +93,14 @@ "to": "feishu-pm" }, "state": { - "nextRunAtMs": 1773426000000, - "lastRunAtMs": 1773339600009, - "lastStatus": "ok", - "lastDurationMs": 298218, - "consecutiveErrors": 0, - "lastRunStatus": "ok", - "lastDeliveryStatus": "not-delivered", - "lastDelivered": false, - "lastDeliveryError": "cron announce delivery failed", - "runningAtMs": 1773426000003 + "nextRunAtMs": 1773512400000, + "lastRunAtMs": 1773426000004, + "lastStatus": "error", + "lastDurationMs": 600010, + "consecutiveErrors": 1, + "lastRunStatus": "error", + "lastDeliveryStatus": "unknown", + "lastError": "cron: job execution timed out" } }, { @@ -111,7 +110,7 @@ "description": "每天凌晨2:30整理昨天的已完成任务到每日回顾", "enabled": true, "createdAtMs": 1741484880000, - "updatedAtMs": 1773340211879, + "updatedAtMs": 1773426622389, "schedule": { "kind": "cron", "expr": "30 2 * * *", @@ -129,11 +128,11 @@ "channel": "last" }, "state": { - "nextRunAtMs": 1773426600000, - "lastRunAtMs": 1773340200003, + "nextRunAtMs": 1773513000000, + "lastRunAtMs": 1773426602034, "lastRunStatus": "ok", "lastStatus": "ok", - "lastDurationMs": 11876, + "lastDurationMs": 20355, "lastDelivered": true, "lastDeliveryStatus": "delivered", "consecutiveErrors": 0 @@ -145,7 +144,7 @@ "name": "zq_workspace_sync", "enabled": true, "createdAtMs": 1772551807455, - "updatedAtMs": 1773340800005, + "updatedAtMs": 1773427200007, "schedule": { "expr": "40 2 * * *", "kind": "cron", @@ -158,8 +157,8 @@ "text": "执行 zq 工作区同步:bash ~/.openclaw/cron/scripts/zq_workspace_sync.sh" }, "state": { - "nextRunAtMs": 1773427200000, - "lastRunAtMs": 1773340800004, + "nextRunAtMs": 1773513600000, + "lastRunAtMs": 1773427200006, "lastStatus": "skipped", "lastDurationMs": 1, "consecutiveErrors": 0, @@ -175,7 +174,7 @@ "description": "每天早上8点整理与各个 AI 代理的对话记录", "enabled": true, "createdAtMs": 1772776369645, - "updatedAtMs": 1773360026590, + "updatedAtMs": 1773446431755, "schedule": { "kind": "cron", "expr": "0 8 * * *", @@ -193,11 +192,11 @@ "channel": "last" }, "state": { - "nextRunAtMs": 1773446400000, - "lastRunAtMs": 1773360000004, + "nextRunAtMs": 1773532800000, + "lastRunAtMs": 1773446400004, "lastRunStatus": "ok", "lastStatus": "ok", - "lastDurationMs": 26586, + "lastDurationMs": 31751, "lastDelivered": true, "lastDeliveryStatus": "delivered", "consecutiveErrors": 0 @@ -210,7 +209,7 @@ "description": "每天7点同步提醒到CalDAV日历", "enabled": true, "createdAtMs": 1772791528528, - "updatedAtMs": 1773356435243, + "updatedAtMs": 1773442830136, "schedule": { "kind": "cron", "expr": "0 7 * * *", @@ -228,15 +227,14 @@ "channel": "last" }, "state": { - "nextRunAtMs": 1773442800000, - "lastRunAtMs": 1773356400004, - "lastRunStatus": "error", - "lastStatus": "error", - "lastDurationMs": 35239, + "nextRunAtMs": 1773529200000, + "lastRunAtMs": 1773442800005, + "lastRunStatus": "ok", + "lastStatus": "ok", + "lastDurationMs": 30131, "lastDeliveryStatus": "delivered", - "consecutiveErrors": 1, - "lastDelivered": true, - "lastError": "⚠️ 📝 Edit: in ~/.openclaw/agents/knowledge-base/workspace/memory/heartbeat-state.json (92 chars) failed" + "consecutiveErrors": 0, + "lastDelivered": true } }, { diff --git a/cron/jobs.json.bak b/cron/jobs.json.bak index b72fc93..1c5a02c 100644 --- a/cron/jobs.json.bak +++ b/cron/jobs.json.bak @@ -7,7 +7,7 @@ "name": "backup-openclaw-json", "enabled": true, "createdAtMs": 1772261581796, - "updatedAtMs": 1773424832005, + "updatedAtMs": 1773511209521, "schedule": { "kind": "cron", "expr": "0 2 * * *", @@ -23,10 +23,10 @@ "mode": "announce" }, "state": { - "nextRunAtMs": 1773511200000, - "lastRunAtMs": 1773424800006, + "nextRunAtMs": 1773597600000, + "lastRunAtMs": 1773511200006, "lastStatus": "ok", - "lastDurationMs": 31999, + "lastDurationMs": 9515, "consecutiveErrors": 0, "lastRunStatus": "ok", "lastDelivered": true, @@ -71,7 +71,7 @@ "name": "capability-evolver-daily", "enabled": true, "createdAtMs": 1772550743528, - "updatedAtMs": 1773339898227, + "updatedAtMs": 1773426600014, "schedule": { "kind": "cron", "expr": "20 2 * * *", @@ -92,16 +92,14 @@ "to": "feishu-pm" }, "state": { - "nextRunAtMs": 1773426000000, - "lastRunAtMs": 1773339600009, - "lastStatus": "ok", - "lastDurationMs": 298218, - "consecutiveErrors": 0, - "lastRunStatus": "ok", - "lastDeliveryStatus": "not-delivered", - "lastDelivered": false, - "lastDeliveryError": "cron announce delivery failed", - "lastError": "cron announce delivery failed" + "nextRunAtMs": 1773512400000, + "lastRunAtMs": 1773426000004, + "lastStatus": "error", + "lastDurationMs": 600010, + "consecutiveErrors": 1, + "lastRunStatus": "error", + "lastDeliveryStatus": "unknown", + "lastError": "cron: job execution timed out" } }, { @@ -111,7 +109,7 @@ "description": "每天凌晨2:30整理昨天的已完成任务到每日回顾", "enabled": true, "createdAtMs": 1741484880000, - "updatedAtMs": 1773340211879, + "updatedAtMs": 1773426622389, "schedule": { "kind": "cron", "expr": "30 2 * * *", @@ -129,11 +127,11 @@ "channel": "last" }, "state": { - "nextRunAtMs": 1773426600000, - "lastRunAtMs": 1773340200003, + "nextRunAtMs": 1773513000000, + "lastRunAtMs": 1773426602034, "lastRunStatus": "ok", "lastStatus": "ok", - "lastDurationMs": 11876, + "lastDurationMs": 20355, "lastDelivered": true, "lastDeliveryStatus": "delivered", "consecutiveErrors": 0 @@ -145,7 +143,7 @@ "name": "zq_workspace_sync", "enabled": true, "createdAtMs": 1772551807455, - "updatedAtMs": 1773340800005, + "updatedAtMs": 1773427200007, "schedule": { "expr": "40 2 * * *", "kind": "cron", @@ -158,8 +156,8 @@ "text": "执行 zq 工作区同步:bash ~/.openclaw/cron/scripts/zq_workspace_sync.sh" }, "state": { - "nextRunAtMs": 1773427200000, - "lastRunAtMs": 1773340800004, + "nextRunAtMs": 1773513600000, + "lastRunAtMs": 1773427200006, "lastStatus": "skipped", "lastDurationMs": 1, "consecutiveErrors": 0, @@ -175,7 +173,7 @@ "description": "每天早上8点整理与各个 AI 代理的对话记录", "enabled": true, "createdAtMs": 1772776369645, - "updatedAtMs": 1773360026590, + "updatedAtMs": 1773446431755, "schedule": { "kind": "cron", "expr": "0 8 * * *", @@ -193,11 +191,11 @@ "channel": "last" }, "state": { - "nextRunAtMs": 1773446400000, - "lastRunAtMs": 1773360000004, + "nextRunAtMs": 1773532800000, + "lastRunAtMs": 1773446400004, "lastRunStatus": "ok", "lastStatus": "ok", - "lastDurationMs": 26586, + "lastDurationMs": 31751, "lastDelivered": true, "lastDeliveryStatus": "delivered", "consecutiveErrors": 0 @@ -210,7 +208,7 @@ "description": "每天7点同步提醒到CalDAV日历", "enabled": true, "createdAtMs": 1772791528528, - "updatedAtMs": 1773356435243, + "updatedAtMs": 1773442830136, "schedule": { "kind": "cron", "expr": "0 7 * * *", @@ -228,15 +226,14 @@ "channel": "last" }, "state": { - "nextRunAtMs": 1773442800000, - "lastRunAtMs": 1773356400004, - "lastRunStatus": "error", - "lastStatus": "error", - "lastDurationMs": 35239, + "nextRunAtMs": 1773529200000, + "lastRunAtMs": 1773442800005, + "lastRunStatus": "ok", + "lastStatus": "ok", + "lastDurationMs": 30131, "lastDeliveryStatus": "delivered", - "consecutiveErrors": 1, - "lastDelivered": true, - "lastError": "⚠️ 📝 Edit: in ~/.openclaw/agents/knowledge-base/workspace/memory/heartbeat-state.json (92 chars) failed" + "consecutiveErrors": 0, + "lastDelivered": true } }, { diff --git a/delivery-queue/2a4d57a9-2c16-4c56-a7c8-442dda323c98.json b/delivery-queue/2a4d57a9-2c16-4c56-a7c8-442dda323c98.json index 2d19e52..a8eb951 100644 --- a/delivery-queue/2a4d57a9-2c16-4c56-a7c8-442dda323c98.json +++ b/delivery-queue/2a4d57a9-2c16-4c56-a7c8-442dda323c98.json @@ -18,7 +18,7 @@ "agentId": "haonan", "text": "🧙‍♂️ Capability Evolver 每日报告\n\n=== 运行时间 ===\n2026年3月13日 星期五 02:20:03 CST\n\n=== Git 备份 ===\n- 备份提交: ba67c46..5ac2251 (main)\n- 4 files changed, 79 insertions(+), 23 deletions(-)\n\n=== 本次变更 ===\n- 变更提交: 5ac2251..e234543 (main)\n- 6 files changed, 550 insertions(+), 13 deletions(-)\n- 新增文件: 2 个\n\n=== 核心动作 ===\n在 GEP 框架中检测到 \"memory_missing\" 和 \"session_logs_missing\" 信号,使用 repair-only 模式执行:\n- 分析环境指纹和系统状态\n- 检测到 session logs 检测缺失的问题\n- 修复相关检测逻辑和回退行为\n- 更新了 evolution 相关状态文件\n\n=== 状态 ===\n运行成功,系统已通过 GEP 协议完成自检和修复。\n\n---\n\n日期: 2026-03-13" }, - "retryCount": 2, - "lastAttemptAt": 1773377636671, + "retryCount": 4, + "lastAttemptAt": 1773508779544, "lastError": "Request failed with status code 400" } \ No newline at end of file diff --git a/delivery-queue/a9e9940b-8432-446c-b277-9847a5994d99.json b/delivery-queue/a9e9940b-8432-446c-b277-9847a5994d99.json index 4e87e59..b5cea75 100644 --- a/delivery-queue/a9e9940b-8432-446c-b277-9847a5994d99.json +++ b/delivery-queue/a9e9940b-8432-446c-b277-9847a5994d99.json @@ -15,7 +15,7 @@ "agentId": "haonan", "text": "好的,我已经成功执行了今天的 capability-evolver 任务。虽然无法通过 Feishu 直接发送消息给您,但我已经完成了所有必要的操作:\n\n## ✅ 已完成的任务\n\n1. **执行脚本** - `bash ~/.openclaw/cron/scripts/evolver-run.sh` ✅\n2. **读取输出** - `~/work/backup/evolver-output.txt` ✅\n3. **本地报告保存** - `~/work/backup/evolver-report-2026-03-12.md` ✅\n\n## 📊 进化结果\n\n**本次变更:** 6 个文件 (550 行新增,13 行删除) \n**运行状态:** 成功 ✅ \n**意图:** 优化 (针对 memory_missing 和 session_logs_missing 信号) \n**风险级别:** 低\n\n**关键变更:**\n- 新增了第 7 个进化周期的 GEP 提示文件\n- 更新了进化状态、记忆图谱状态和个性状态\n\n**Git 提交:**\n- 备份: `dc01abf`\n- 变更: `34ca190`\n- 已推送到远程仓库\n\n完整报告已保存在:`~/work/backup/evolver-report-2026-03-12.md`" }, - "retryCount": 2, - "lastAttemptAt": 1773377636492, + "retryCount": 4, + "lastAttemptAt": 1773508779398, "lastError": "Request failed with status code 400" } \ No newline at end of file diff --git a/delivery-queue/dfa9a241-9226-4e1a-962c-3bad30a04d0b.json b/delivery-queue/dfa9a241-9226-4e1a-962c-3bad30a04d0b.json index 5fd0c74..36e03aa 100644 --- a/delivery-queue/dfa9a241-9226-4e1a-962c-3bad30a04d0b.json +++ b/delivery-queue/dfa9a241-9226-4e1a-962c-3bad30a04d0b.json @@ -15,7 +15,7 @@ "agentId": "haonan", "text": "🧙‍♂️ Capability Evolver 每日报告\n\n=== 运行时间 ===\n2026年3月13日 星期五 02:20:03 CST\n\n=== Git 备份 ===\n- 备份提交: ba67c46..5ac2251 (main)\n- 4 files changed, 79 insertions(+), 23 deletions(-)\n\n=== 本次变更 ===\n- 变更提交: 5ac2251..e234543 (main)\n- 6 files changed, 550 insertions(+), 13 deletions(-)\n- 新增文件: 2 个\n\n=== 核心动作 ===\n在 GEP 框架中检测到 \"memory_missing\" 和 \"session_logs_missing\" 信号,使用 repair-only 模式执行:\n- 分析环境指纹和系统状态\n- 检测到 session logs 检测缺失的问题\n- 修复相关检测逻辑和回退行为\n- 更新了 evolution 相关状态文件\n\n=== 状态 ===\n运行成功,系统已通过 GEP 协议完成自检和修复。\n\n---\n\n日期: 2026-03-13" }, - "retryCount": 2, - "lastAttemptAt": 1773377636819, + "retryCount": 4, + "lastAttemptAt": 1773508779677, "lastError": "Request failed with status code 400" } \ No newline at end of file diff --git a/feishu/dedup/feishu-art.json b/feishu/dedup/feishu-art.json index d519703..69419d7 100644 --- a/feishu/dedup/feishu-art.json +++ b/feishu/dedup/feishu-art.json @@ -1,5 +1,4 @@ { - "om_x100b55d69df3a888c3e9ed8887d1a4d": 1773022516624, - "om_x100b55d6987ec8bcc1431506934622a": 1773022571945, - "om_x100b55c3980b0894c3d7e12aace4404": 1773108589126 + "om_x100b546dc09400acb4a5d0af66ca3c9": 1773508838286, + "om_x100b546dde1c34a4b49a888912755ac": 1773508877713 } diff --git a/feishu/dedup/feishu-dev.json b/feishu/dedup/feishu-dev.json index 88c4769..6fa5f8c 100644 --- a/feishu/dedup/feishu-dev.json +++ b/feishu/dedup/feishu-dev.json @@ -1,7 +1,3 @@ { - "om_x100b55de502094a8c44a6f835293240": 1773052399376, - "om_x100b55cff24dcca8c3e59d6831d6885": 1773124552700, - "om_x100b55c8c767d084c45fc7eec3f7db8": 1773127835623, - "om_x100b55c9372e9914c3a5744eccfbc0d": 1773131678929, - "om_x100b55c9dfec84a0b34c47ff1aca626": 1773132050877 + "om_x100b546dc3b650a4b2c0139d2df31a7": 1773508824362 } diff --git a/feishu/dedup/feishu-pm.json b/feishu/dedup/feishu-pm.json index 4ee4358..2449029 100644 --- a/feishu/dedup/feishu-pm.json +++ b/feishu/dedup/feishu-pm.json @@ -1,18 +1,6 @@ { - "om_x100b54012fb4b8acb26a1377e572a28": 1773360664219, - "om_x100b5403d6e544bcc451e2afa005879": 1773369731225, - "om_x100b5403d32b04b4c2a796466ebaf4f": 1773369823078, - "om_x100b5403e04f6ca8c29946e1fa6505d": 1773370088740, - "om_x100b5403a57550acc4e0a394c486825": 1773371068258, - "om_x100b540c23747504c2c49c98ae45b5f": 1773373148201, - "om_x100b540c32194cf4c4280e7ae0e4650": 1773373389909, - "om_x100b540cf21b9ca8c45f49655336827": 1773374414017, - "om_x100b540cf0292ca8c2b181d4bd75a25": 1773374446894, - "om_x100b540c8da298a0c39af0977d653ff": 1773374519675, - "om_x100b540c860cc4b0b36952fd4812b96": 1773374604809, - "om_x100b540ca90ecca4b34794a71e94eb8": 1773375100856, - "om_x100b540ca46704a4b36f1edd3527001": 1773375147301, - "om_x100b540d351884a0b20c96f48730b1d": 1773377469866, - "om_x100b540dcb01d4a0b3fd88e28dbba4e": 1773377629522, - "om_x100b540dc9bb2ca4b3671d47b831818": 1773377656011 + "om_x100b546d172f3c68c2cea708421b99a": 1773507998614, + "om_x100b546d2b32cca0c329a33c339cfb5": 1773508192506, + "om_x100b546d32de24a8b316c197e60d6e4": 1773508545727, + "om_x100b546dc9d61ca0b33d802bc7615e0": 1773508722267 } diff --git a/feishu/dedup/feishu-qa.json b/feishu/dedup/feishu-qa.json index 410d529..313c43f 100644 --- a/feishu/dedup/feishu-qa.json +++ b/feishu/dedup/feishu-qa.json @@ -1,19 +1,3 @@ { - "om_x100b540c33ced0a8c3b77203de384e3": 1773373392794, - "om_x100b540ca2e850b8b2932714333e65f": 1773375171104, - "om_x100b540ca11ae8bcb351842dd1c37b6": 1773375229985, - "om_x100b540cbb43f0b0b3d91309afa563e": 1773375321590, - "om_x100b540cb73d2c80b275045db2fba68": 1773375391649, - "om_x100b540cb13eb4bcb31e7a5a9fbbbc3": 1773375487898, - "om_x100b540d4b4078acb33fd526aa324ea": 1773375577515, - "om_x100b540d46704ca0b38a5d0c7011398": 1773375628530, - "om_x100b540d5e21d530b4b235d9a470ccf": 1773375759355, - "om_x100b540d6efb8ca8b35b71db8c7e917": 1773376004012, - "om_x100b540d64b9a0a8b34ee257f229495": 1773376167864, - "om_x100b540d633e84b0b2b051a702c5c2b": 1773376223787, - "om_x100b540d34d174a0b3c9f1ee9a1f815": 1773377442459, - "om_x100b540dc61d00b0b3718efd72b20c5": 1773377677571, - "om_x100b540dda597ca0b2cb468e3799501": 1773377865991, - "om_x100b540ddbcaf4a8b247e16717525fe": 1773377873053, - "om_x100b540dd78910b4b31bb742001ce61": 1773377940945 + "om_x100b546d2d6164a4c3fcf5a6d528b40": 1773508155371 } diff --git a/feishu/dedup/feishu-worker.json b/feishu/dedup/feishu-worker.json index 2a949da..3598c15 100644 --- a/feishu/dedup/feishu-worker.json +++ b/feishu/dedup/feishu-worker.json @@ -1,4 +1,10 @@ { - "om_x100b5403a5fd7090c4db2b553189c54": 1773371059715, - "om_x100b540c2807c4acc32d196f4b16191": 1773373037365 + "om_x100b546ddd8b14a0b3ddda14ce768c5": 1773508916933, + "om_x100b546dd78c8ca0b31b0314f910115": 1773509012676, + "om_x100b546def8ac8a4b38d921a2bfc8b8": 1773509140955, + "om_x100b546dedb654a4b3ce916a129facf": 1773509176311, + "om_x100b546de975dca0b27e2f24aad0d8c": 1773509244102, + "om_x100b546de53a94a0b38693fbd7e385c": 1773509311993, + "om_x100b546dffaa3cb0b35aef2747ed228": 1773509398933, + "om_x100b546df49c10a0b106d597fd348a3": 1773509541678 } diff --git a/identity/device-auth.json b/identity/device-auth.json index 7620d79..7199ef9 100644 --- a/identity/device-auth.json +++ b/identity/device-auth.json @@ -10,7 +10,7 @@ "operator.approvals", "operator.pairing" ], - "updatedAtMs": 1773425421022 + "updatedAtMs": 1773511209007 } } } diff --git a/logs/commands.log b/logs/commands.log index 5c2dd25..532417f 100644 --- a/logs/commands.log +++ b/logs/commands.log @@ -36,3 +36,4 @@ {"timestamp":"2026-03-13T04:01:59.730Z","action":"new","sessionKey":"agent:haonan:main","senderId":"ou_be83febac9ee2afaa343c642bc697c48","source":"feishu"} {"timestamp":"2026-03-13T04:11:41.253Z","action":"new","sessionKey":"agent:haonan:main","senderId":"ou_be83febac9ee2afaa343c642bc697c48","source":"feishu"} {"timestamp":"2026-03-13T04:57:53.114Z","action":"new","sessionKey":"agent:thinker:main","senderId":"ou_a0f6627b64d2dc8b0236671603d1e47b","source":"feishu"} +{"timestamp":"2026-03-14T17:06:39.062Z","action":"new","sessionKey":"agent:haonan:main","senderId":"ou_be83febac9ee2afaa343c642bc697c48","source":"feishu"} diff --git a/skills/kb-bilibili-content/SKILL.md b/skills/kb-bilibili-content/SKILL.md index 10fe915..4701426 100644 --- a/skills/kb-bilibili-content/SKILL.md +++ b/skills/kb-bilibili-content/SKILL.md @@ -1,214 +1,91 @@ ---- -name: kb-bilibili-content -description: B站内容下载 - 下载视频、字幕、专栏文章 ---- - # KB Bilibili Content Skill -**kb-bilibili-content** - 下载 B站视频、字幕、专栏文章。 +**kb-bilibili-content** - Download Bilibili videos and extract content. -## 什么时候使用 +## Features -- kb-workflow 步骤 3a:下载视频或字幕 -- kb-workflow 步骤 3b:提取专栏文章内容 +- Video download using **yt-dlp** (recommended) +- Subtitle extraction +- Article content extraction +- Multiple quality options (360P/480P/720P/1080P) +- Supports `BILIBILI_COOKIE` environment variable -## 功能 +## Environment Variables -- 视频下载(使用 yt-dlp) -- 字幕提取(官方字幕) -- 专栏文章内容提取 -- 多种画质选项(360P/480P/720P/1080P) -- 支持 `BILIBILI_COOKIE` 环境变量(会员视频) +| Variable | Required | Description | +|----------|----------|-------------| +| `BILIBILI_COOKIE` | No | B站登录 Cookie (for member-only videos) | -## 环境变量 - -| 变量名 | 必需 | 说明 | -|--------|------|------| -| `BILIBILI_COOKIE` | 否 | B站登录 Cookie(会员视频需要) | - -**获取 Cookie:** -1. 登录 bilibili.com -2. F12 → Network → 刷新页面 -3. 从请求头复制 Cookie +## Commands ```bash -export BILIBILI_COOKIE="SESSDATA=xxx; bili_jct=xxx; DedeUserID=xxx" +# Download video (720P default) +python bilibili_content.py --id "BV1xx411c7mD" --type video --output "/path/to/downloads/" + +# Download video (1080P) +python bilibili_content.py --id "BV1xx411c7mD" --type video --quality 80 --output "/path/to/downloads/" + +# Download video (480P) +python bilibili_content.py --id "BV1xx411c7mD" --type video --quality 32 --output "/path/to/downloads/" + +# Extract subtitle +python bilibili_content.py --id "BV1xx411c7mD" --type subtitle --output "/path/to/subtitles/" + +# Get article content +python bilibili_content.py --id "cv43780186" --type article --output "/path/to/article.md" ``` -## 命令 - -```bash -# 下载字幕(推荐首先尝试) -python3 bilibili_content.py --id "BV1xx411c7mD" --type subtitle-download --output "/path/to/output/" - -# 下载视频(720P,推荐) -python3 bilibili_content.py --id "BV1xx411c7mD" --type video --output "/path/to/output/" - -# 下载视频(1080P) -python3 bilibili_content.py --id "BV1xx411c7mD" --type video --quality 80 --output "/path/to/output/" - -# 提取专栏文章 -python3 bilibili_content.py --id "cv43780186" --type article --output "/path/to/output/" -``` - -## 输出格式 Schema - -### 必需字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `success` | boolean | 是否成功 | -| `type` | string | 操作类型(subtitle/video/article) | - -### 字幕下载特有字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `has_subtitle` | boolean | 是否有官方字幕 | -| `subtitle_file` | string | 字幕文件路径(有字幕时) | - -### 视频下载特有字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `filepath` | string | 视频文件路径 | -| `filename` | string | 视频文件名 | -| `quality` | string | 画质 | - -### 文章提取特有字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `filepath` | string | 文章文件路径 | -| `content_length` | number | 内容长度 | - -## 成功示例 - -### 字幕下载 - 有官方字幕 - -```json -{ - "success": true, - "type": "subtitle-download", - "has_subtitle": true, - "subtitle_file": "content/downloads/bilibili_BV1xx411c7mD.srt", - "message": "官方字幕下载成功" -} -``` - -### 字幕下载 - 无官方字幕 - -```json -{ - "success": true, - "type": "subtitle-download", - "has_subtitle": false, - "message": "无官方字幕,需要下载视频进行语音识别" -} -``` - -### 视频下载 +## Output ```json { "success": true, "type": "video", - "filename": "bilibili_BV1xx411c7mD.mp4", - "filepath": "content/downloads/bilibili_BV1xx411c7mD.mp4", - "quality": "720P", - "message": "下载完成" + "filename": "video_title.mp4", + "filepath": "/path/to/downloads/video_title.mp4", + "message": "下载完成: video_title.mp4" } ``` -### 专栏文章提取 +## Cookie Setup -```json -{ - "success": true, - "type": "article", - "filename": "bilibili_cv43780186.txt", - "filepath": "content/bilibili_cv43780186.txt", - "content_length": 5234, - "message": "文章内容提取成功" -} +### Get Cookie from Browser +1. Login to bilibili.com +2. Press F12 → Network → Refresh page +3. Copy Cookie from request headers + +### Set Environment Variable +```bash +# Add to ~/.bashrc for persistence +export BILIBILI_COOKIE="SESSDATA=xxx; bili_jct=xxx; DedeUserID=xxx; DedeUserID__ckMd5=xxx" + +# Or set temporarily +export BILIBILI_COOKIE="your_cookie_here" ``` -## 错误示例 - -### 403 禁止访问 - -```json -{ - "success": false, - "type": "video", - "error": "403 Forbidden", - "error_code": "FORBIDDEN", - "suggestion": "可能需要会员权限,请配置 BILIBILI_COOKIE 环境变量" -} -``` - -### 视频不存在 - -```json -{ - "success": false, - "type": "video", - "error": "视频不存在或已被删除", - "error_code": "NOT_FOUND" -} -``` - -### 网络超时 - -```json -{ - "success": false, - "type": "video", - "error": "下载超时", - "error_code": "TIMEOUT", - "suggestion": "请检查网络连接后重试" -} -``` - -## 画质选项 - -| 画质 | ID | 分辨率 | 说明 | -|------|-----|--------|------| -| 360P | 16 | 640x360 | 最快 | -| 480P | 32 | 852x480 | 低带宽 | -| 720P | 64 | 1280x720 | **推荐** | -| 1080P | 80 | 1920x1080 | 最高画质 | - -**默认画质:** 64 (720P) - -## 安装 +## Installation ```bash -cp -r kb-bilibili-content/ ~/.openclaw/skills/ -pip install aiohttp yt-dlp +cp -r kb-bilibili-content/ ~/skills/ +pip install aiohttp playwright +playwright install chromium ``` -## 在 kb-workflow 中的使用 +## How It Works -```bash -# 步骤 3a:首先尝试字幕 -python3 ~/.openclaw/skills/kb-bilibili-content/bilibili_content.py \ - --id "BV1xx411c7mD" --type subtitle-download \ - --output "content/downloads/" +Video download uses **yt-dlp** with Netscape-format cookie file: +1. Parses `BILIBILI_COOKIE` environment variable +2. Creates temporary Netscape-format cookie file +3. Runs `yt-dlp --cookies -f -o ` +4. Cleans up temporary file -# 判断结果: -# - has_subtitle=true → 跳过 Whisper,直接进入深度分析 -# - has_subtitle=false → 下载视频,进入 Whisper 步骤 +## Quality Options -# 如果无字幕,下载视频 -python3 ~/.openclaw/skills/kb-bilibili-content/bilibili_content.py \ - --id "BV1xx411c7mD" --type video \ - --output "content/downloads/" -``` +| Quality | ID | Resolution | Notes | +|---------|-----|------------|-------| +| 16 | 360P | 640x360 | Fastest | +| 32 | 480P | 852x480 | Default for low bandwidth | +| 64 | 720P | 1280x720 | **Recommended** | +| 80 | 1080P | 1920x1080 | Best quality | -## 注意事项 - -- **无官方字幕是正常的**:很多视频没有自动生成的字幕,这不是错误 -- **403 错误**:通常需要配置 Cookie -- **会员视频**:必须配置 BILIBILI_COOKIE -- **下载时间**:视频可能较大,需要耐心等待 +Default quality: **64 (720P)** diff --git a/skills/kb-bilibili-metadata/SKILL.md b/skills/kb-bilibili-metadata/SKILL.md index 6dd0afe..d90d862 100644 --- a/skills/kb-bilibili-metadata/SKILL.md +++ b/skills/kb-bilibili-metadata/SKILL.md @@ -1,187 +1,46 @@ ---- -name: kb-bilibili-metadata -description: B站元数据提取 - 获取视频/专栏/UP主的详细信息 ---- - # KB Bilibili Metadata Skill -**kb-bilibili-metadata** - 提取 B站视频、专栏、UP主的元数据。 +**kb-bilibili-metadata** - Extract Bilibili video/article/up主 metadata. -## 什么时候使用 +## Features -- kb-workflow 步骤 2:获取 B站内容的元数据 -- 需要视频标题、作者、时长等信息 +- Video metadata extraction +- Article (专栏) metadata extraction +- UP主 information extraction +- JSON output format +- Playwright + HTTP API fallback -## 功能 - -- 视频元数据提取 -- 专栏(article)元数据提取 -- UP主信息提取 -- JSON 输出格式 -- 支持 `--output` 参数指定输出文件 - -## 命令 +## Commands ```bash -# 视频元数据 -python3 bilibili_metadata.py --id "BV1xx411c7mD" --type video +# Video metadata +python bilibili_metadata.py --id "BV1xx411c7mD" --type video -# 专栏元数据 -python3 bilibili_metadata.py --id "cv43780186" --type article +# Article metadata +python bilibili_metadata.py --id "cv43780186" --type article -# UP主信息 -python3 bilibili_metadata.py --id "7770724" --type up - -# 指定输出文件 -python3 bilibili_metadata.py --id "BV1xx411c7mD" --type video --output "metadata/bilibili_BV1xx411c7mD.meta.json" +# UP主 info +python bilibili_metadata.py --id "7770724" --type up ``` -## 输出格式 Schema - -### 必需字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `success` | boolean | 是否提取成功 | -| `platform` | string | 固定为 `bilibili` | -| `content_id` | string | 内容 ID(BV号/cv号/uid) | -| `content_type` | string | 内容类型(video/article/up) | -| `title` | string | 标题(视频/专栏)或名称(UP主) | - -### 可选字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `author` | string | 作者/UP主名称 | -| `duration` | string | 时长(视频) | -| `description` | string | 简介/描述 | -| `stats` | object | 统计数据(播放、点赞等) | -| `output_file` | string | 输出文件路径 | -| `error` | string | 错误信息(失败时) | - -## 成功示例 - -### 视频元数据 +## Output ```json { "success": true, - "platform": "bilibili", - "content_type": "video", - "content_id": "BV1xx411c7mD", - "title": "视频标题", - "author": "UP主名字", - "duration": "10:30", - "description": "视频简介内容...", - "stats": { - "view": 100000, - "like": 5000, - "coin": 2000, - "favorite": 1000, - "share": 500, - "danmaku": 3000 - }, - "output_file": "metadata/bilibili_BV1xx411c7mD.meta.json" + "data": { + "platform": "bilibili", + "type": "video", + "id": "BV1xx411c7mD", + "title": "视频标题", + "author": "UP主名字", + "stats": {"view": 100000, "like": 5000} + } } ``` -### 专栏元数据 - -```json -{ - "success": true, - "platform": "bilibili", - "content_type": "article", - "content_id": "cv43780186", - "title": "专栏标题", - "author": "作者名字", - "description": "专栏摘要...", - "stats": { - "view": 50000, - "like": 2000, - "comment": 500 - }, - "output_file": "metadata/bilibili_cv43780186.meta.json" -} -``` - -### UP主信息 - -```json -{ - "success": true, - "platform": "bilibili", - "content_type": "up", - "content_id": "7770724", - "title": "UP主名字", - "description": "UP主签名...", - "stats": { - "follower": 1000000, - "following": 100, - "video_count": 500 - }, - "output_file": "metadata/bilibili_7770724.meta.json" -} -``` - -## 错误示例 - -### 视频不存在 - -```json -{ - "success": false, - "platform": "bilibili", - "content_id": "BV1invalid", - "content_type": "video", - "error": "视频不存在或已被删除" -} -``` - -### 网络错误 - -```json -{ - "success": false, - "platform": "bilibili", - "content_id": "BV1xx411c7mD", - "content_type": "video", - "error": "网络请求失败: Connection timeout" -} -``` - -### 参数错误 - -```json -{ - "success": false, - "error": "缺少必需参数: --id" -} -``` - -## 安装 +## Installation ```bash -cp -r kb-bilibili-metadata/ ~/.openclaw/skills/ -pip install httpx playwright -playwright install chromium +cp -r kb-bilibili-metadata/ ~/skills/ ``` - -## 在 kb-workflow 中的使用 - -```bash -# 步骤 2:元数据提取(B站视频) -python3 ~/.openclaw/skills/kb-bilibili-metadata/bilibili_metadata.py \ - --id "BV1xx411c7mD" --type video \ - --output "metadata/bilibili_BV1xx411c7mD.meta.json" - -# 检查输出: -# - success=true → 进入步骤 3 -# - success=false → 检查错误,可能需要重试或退出 -``` - -## 注意事项 - -- 部分视频可能需要登录才能获取完整信息 -- 专栏内容可能需要额外的 Cookie 配置 -- 如果使用 Playwright 方式,首次运行需要下载浏览器 diff --git a/skills/kb-deep-analyzer/SKILL.md b/skills/kb-deep-analyzer/SKILL.md index 96233b9..0977cab 100644 --- a/skills/kb-deep-analyzer/SKILL.md +++ b/skills/kb-deep-analyzer/SKILL.md @@ -1,207 +1,102 @@ ---- -name: kb-deep-analyzer -description: AI深度分析 - 使用 AI 对内容进行深度分析和摘要 ---- - # KB Deep Analyzer Skill **kb-deep-analyzer** - AI 深度内容分析工具。 -## 什么时候使用 - -- kb-workflow 步骤 5:对视频字幕或文章内容进行深度分析 -- 需要生成摘要、主题、见解等 - -## 功能 +## Features - 多类型分析:视频(video)、文章(article) - 模板化输出 - 质量评分 - 自动标签 -- 多格式元数据支持 +- **多格式元数据支持**: 支持扁平结构 `{"title":"xxx"}` 和嵌套结构 `{"data":{"metadata":{...}}}` -## 环境变量(必需) +## 内容类型 -| 变量名 | 说明 | 示例 | -|--------|------|------| -| `AI_API_KEY` | AI API 密钥 | `your-api-key` | -| `AI_PROVIDER` | AI 提供商 | `zhipu` / `openai` / `minimax` | -| `AI_MODEL` | 模型名称 | `glm-5` / `gpt-4` | -| `AI_BASE_URL` | API 端点 | `https://open.bigmodel.cn/api/coding/paas/v4` | +| 类型 | 参数 | 输出格式 | +|------|------|----------| +| 视频 | `--type video` | 摘要 + 主题 + 见解 + 时间轴 | +| 文章 | `--type article` | 300字摘要 + 主题 + 原文 | -## 命令 +## Commands ```bash -# 分析视频 -AI_API_KEY="xxx" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \ -python3 -u deep_analyzer.py \ - --metadata meta.json \ - --content content.json \ - --output analysis.md \ - --type video \ - --provider zhipu --model glm-5 +# 分析视频(默认) +AI_API_KEY="your-api-key" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \ + python3 -u deep_analyzer.py --metadata meta.json --content content.json --output analysis.md --type video -# 分析文章 -AI_API_KEY="xxx" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \ -python3 -u deep_analyzer.py \ - --metadata meta.json \ - --content content.txt \ - --output analysis.md \ - --type article \ - --provider zhipu --model glm-5 +# 分析文章(300字摘要 + 原文) +AI_API_KEY="your-api-key" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \ + python3 -u deep_analyzer.py --metadata meta.json --content content.json --output analysis.md --type article + +# 指定 AI 提供商 +python3 -u deep_analyzer.py -m meta.json -c content.json -o out.md --type video --provider zhipu --model glm-5 ``` -## 参数说明 +## 环境变量配置 -| 参数 | 说明 | 必需 | -|------|------|------| -| `--metadata` | 元数据 JSON 文件路径 | 是 | -| `--content` | 内容文件路径(JSON/TXT) | 是 | -| `--output` | 输出 Markdown 文件路径 | 是 | -| `--type` | 内容类型(video/article) | 是 | -| `--provider` | AI 提供商 | 否(默认从环境变量) | -| `--model` | 模型名称 | 否(默认从环境变量) | - -## 输出格式 Schema - -### 必需字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `success` | boolean | 是否分析成功 | - -### 成功时字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `output_file` | string | 输出文件路径 | -| `model` | string | 使用的模型 | -| `provider` | string | 使用的提供商 | - -### 失败时字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `error` | string | 错误信息 | -| `message` | string | 详细说明 | - -## 成功示例 - -```json -{ - "success": true, - "output_file": "analyzed/bilibili_BV1xx411c7mD.md", - "model": "glm-5", - "provider": "zhipu" -} -``` - -## 错误示例 - -### API 调用失败 - -```json -{ - "success": false, - "error": "AI API 调用失败: rate limit exceeded", - "message": "深度分析失败,整个流程终止" -} -``` - -### 环境变量未设置 - -```json -{ - "success": false, - "error": "AI_API_KEY 环境变量未设置", - "suggestion": "请配置 AI_API_KEY 环境变量" -} -``` - -### 内容文件不存在 - -```json -{ - "success": false, - "error": "内容文件不存在", - "content_file": "content/missing.json" -} -``` - -## 输出格式(Markdown) - -### 视频分析输出 - -```markdown -# 视频标题 - -## 摘要 -[200-300字的核心内容摘要] - -## 主要主题 -- 主题1 -- 主题2 -- 主题3 - -## 关键见解 -- 见解1 -- 见解2 - -## 时间轴 -- 00:00 - 02:30: 第一部分 -- 02:30 - 05:00: 第二部分 -... - -## 标签 -#标签1 #标签2 #标签3 -``` - -### 文章分析输出 - -```markdown -# 文章标题 - -## 摘要 -[300字以内的核心观点] - -## 主要主题 -- 主题1 -- 主题2 - -## 完整原文 -[原始文章内容] -``` - -## 安装 +**必须设置以下环境变量**: ```bash -cp -r kb-deep-analyzer/ ~/.openclaw/skills/ -pip install httpx +export AI_API_KEY="your-api-key" +export AI_PROVIDER="zhipu" # 或 openai, minimax +export AI_MODEL="glm-5" # 模型名称 +export AI_BASE_URL="https://..." # 可选,自定义 API 地址 ``` -## 在 kb-workflow 中的使用 +### 重要提示 + +**必须使用 `-u` 参数运行 Python**,确保输出实时显示在终端: ```bash -# 步骤 5:深度分析 -# ⚠️ 必须成功,否则整个流程失败 - -AI_API_KEY="$AI_API_KEY" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \ -python3 -u ~/.openclaw/skills/kb-deep-analyzer/deep_analyzer.py \ - --metadata "metadata/bilibili_BV1xx411c7mD.meta.json" \ - --content "content/bilibili_BV1xx411c7mD.json" \ - --output "analyzed/bilibili_BV1xx411c7mD.md" \ - --type video \ - --provider zhipu --model glm-5 - -# 检查结果: -# - success=true → 进入步骤 6(归档) -# - success=false → 整个流程终止,报告错误 +python3 -u deep_analyzer.py ... ``` -## ⚠️ 重要提示 +如果不使用 `-u` 参数,Python 的 stdout 缓冲会导致输出延迟或看不到进度。 -1. **必须使用 `-u` 参数**:确保 Python 输出实时显示 -2. **深度分析不可跳过**:这是必须成功的步骤 -3. **失败即终止**:如果返回 `success: false`,整个流程必须停止 -4. **禁止降级**:不能使用预设模板或简单摘要"假装成功" -5. **并发执行**:默认使用 batch_size=3 并发处理 +## 执行方式选择 + +### 方式1: 并发执行(推荐,默认) +- 使用 `batch_size=3`(默认) +- 6个分片约 100 秒完成 +- 适合快速分析 + +```bash +python3 -u deep_analyzer.py --metadata meta.json --content content.json -o out.md +``` + +### 方式2: 顺序执行 +- 使用 `batch_size=1` +- 6个分片约 735 秒完成 +- 适合调试和问题排查 + +```bash +# 在代码中设置 batch_size=1 +# analyzer.analyze(metadata, content, "video", batch_size=1) +``` + +## Metadata Format + +支持两种元数据格式: + +```json +// 格式1: 扁平结构 +{ + "title": "视频标题", + "author": "作者名", + "duration": 619, + "bvid": "BVxxx" +} + +// 格式2: 嵌套结构(kb-bilibili-metadata 输出) +{ + "data": { + "metadata": { + "title": "视频标题", + "author": "作者名", + "duration": "10:19" + } + } +} +``` + +会自动转换为扁平格式进行分析。 diff --git a/skills/kb-funasr/SKILL.md b/skills/kb-funasr/SKILL.md index 2b44a10..886012c 100644 --- a/skills/kb-funasr/SKILL.md +++ b/skills/kb-funasr/SKILL.md @@ -1,41 +1,44 @@ --- name: kb-funasr -description: 本地语音识别 - 使用阿里 FunASR 进行中文优化的语音识别 +description: 本地语音识别,支持音视频转文字(基于阿里 FunASR) --- # KB FunASR Skill -**kb-funasr** - 本地语音识别,使用阿里 FunASR 将音视频文件转换为文本。 +**kb-funasr** - 本地语音识别,使用阿里 FunASR 将音视频文件转换为文本和 JSON 格式输出。 ## 什么时候使用 -- kb-workflow 步骤 4 的备选方案:当 Whisper 效果不佳时 -- 中文语音识别(Paraformer 模型对中文优化) -- 需要高精度中文识别 +当用户需要: +- 将视频/音频文件转换为文字 +- 获取带时间戳的详细识别结果 +- 需要中文优化的语音识别(Paraformer 模型) ## 环境变量 -| 变量名 | 必需 | 说明 | -|--------|------|------| -| `FUNASR_CACHE_DIR` | 否 | FunASR 模型缓存目录 | +在使用之前,必须检查环境变量是否已经设置。 -## 命令 +| 变量名 | 用途 | 示例 | +|--------|------|------| +| `FUNASR_CACHE_DIR` | FunASR 模型缓存目录 | `~/.cache/modelscope/hub` | + +## 使用方法 ```bash -# 基本用法(使用 Paraformer 中文模型,推荐) -python3 funasr_tool.py --input video.mp4 +# 基本用法(使用 Paraformer 模型) +python funasr.py --input video.mp4 # 指定模型 -python3 funasr_tool.py --input video.mp4 --model paraformer-zh +python funasr.py --input video.mp4 --model paraformer-zh # 指定输出目录 -python3 funasr_tool.py --input video.mp4 --output ./output +python funasr.py --input video.mp4 --output ./output -# 后台异步执行 -python3 funasr_tool.py --input video.mp4 --background +# 异步执行(推荐) +python funasr.py --input video.mp4 --background ``` -## 参数说明 +## 命令参数 | 参数 | 说明 | 默认值 | |------|------|--------| @@ -46,91 +49,47 @@ python3 funasr_tool.py --input video.mp4 --background ## 模型选项 -| 模型 | 说明 | 推荐场景 | -|------|------|---------| -| `paraformer-zh` | Paraformer 中文模型 | **推荐**,中文优化 | -| `paraformer` | Paraformer 多语言模型 | 多语言场景 | -| `sensevoice` | SenseVoice 模型 | 高精度需求 | +- `paraformer-zh` - Paraformer 中文模型(轻量,中文优化,推荐) +- `paraformer` - Paraformer 多语言模型 +- `sensevoice` - SenseVoice 多语言模型 -## 输出格式 Schema +## 输出文件 -### 必需字段 +对于输入 `video.mp4`,将生成: -| 字段 | 类型 | 说明 | -|------|------|------| -| `success` | boolean | 是否识别成功 | -| `input_file` | string | 输入文件路径 | -| `model` | string | 使用的模型 | +- `video.json` - 详细结果(包含时间戳、分段信息) +- `video.txt` - 纯文本内容 -### 可选字段 +## 输出格式示例 -| 字段 | 类型 | 说明 | -|------|------|------| -| `output_files` | object | 输出文件路径 | -| `duration_seconds` | number | 音频时长 | -| `segments` | array | 识别分段 | -| `error` | string | 错误信息 | - -## 成功示例 +### JSON 格式 ```json { "success": true, - "input_file": "content/downloads/bilibili_BV1xx411c7mD.mp4", + "input_file": "video.mp4", "model": "paraformer-zh", "output_files": { - "json": "content/bilibili_BV1xx411c7mD_funasr.json", - "txt": "content/bilibili_BV1xx411c7mD_funasr.txt" + "json": "video.json", + "txt": "video.txt" }, - "duration_seconds": 630.5, + "duration_seconds": 120.5, "segments": [ { "id": 0, "start": 0.0, "end": 3.2, "text": "这是第一段识别结果" - }, - { - "id": 1, - "start": 3.2, - "end": 6.5, - "text": "这是第二段识别结果" } ] } ``` -## 错误示例 +## Workflow 中的使用 -### 模型未下载 - -```json -{ - "success": false, - "error": "模型未找到", - "model": "paraformer-zh", - "suggestion": "首次运行时会自动下载模型,请确保网络连接正常" -} -``` - -### 文件不存在 - -```json -{ - "success": false, - "error": "输入文件不存在", - "input_file": "content/downloads/missing.mp4" -} -``` - -### 内存不足 - -```json -{ - "success": false, - "error": "内存不足", - "suggestion": "尝试使用较小的模型或处理较短的音频片段" -} +```bash +# 步骤4之后:如果已有音频但无字幕,可以使用 FunASR +python funasr.py --input ${video_path} --model paraformer-zh --background ``` ## 安装 @@ -139,35 +98,16 @@ python3 funasr_tool.py --input video.mp4 --background # 1. 安装依赖 pip install funasr modelscope -# 2. 首次运行时自动下载模型 -python3 funasr_tool.py --input test.mp4 +# 2. 首次运行时会自动下载模型到缓存目录 +python funasr.py --input test.mp4 -# 3. 复制技能 -cp -r kb-funasr/ ~/.openclaw/skills/ -``` - -## 在 kb-workflow 中的使用 - -```bash -# 步骤 4 的备选方案(当 Whisper 效果不佳时) -python3 ~/.openclaw/skills/kb-funasr/funasr_tool.py \ - --input "content/downloads/bilibili_BV1xx411c7mD.mp4" \ - --model paraformer-zh \ - --output "content/" - -# 输出: -# - bilibili_BV1xx411c7mD_funasr.json (完整结果) -# - bilibili_BV1xx411c7mD_funasr.txt (纯文本) - -# 完成后进入步骤 5(深度分析) +# 3. 复制技能到 skills 目录 +cp -r kb-funasr/ ~/skills/ ``` ## 注意事项 -- **首次运行**:首次运行时会自动下载模型文件(约 1GB),需要稳定网络 -- **中文优化**:Paraformer 模型对中文识别效果优于 Whisper -- **耗时操作**:语音识别可能需要几分钟到几十分钟 -- **文件格式**:支持 MP3、MP4、WAV、FLAC、OGG、M4A 等常见格式 -- **与 Whisper 对比**: - - Whisper:通用性强,支持多语言 - - FunASR:中文优化,精度更高 +- **异步执行**: 使用 `--background` 参数时,命令会在后台运行,不阻塞主代理 +- **模型选择**: paraformer-zh 模型适合中文语音识别,速度较快,精度较高 +- **文件格式**: 支持 MP3、MP4、WAV、FLAC、OGG、M4A 等常见格式 +- **首次运行**: 首次运行时会自动下载模型文件,需要稳定的网络连接 diff --git a/skills/kb-link-parser/SKILL.md b/skills/kb-link-parser/SKILL.md index a4ae3fa..b8c97cc 100644 --- a/skills/kb-link-parser/SKILL.md +++ b/skills/kb-link-parser/SKILL.md @@ -1,190 +1,43 @@ ---- -name: kb-link-parser -description: 链接解析器 - 从各平台 URL 提取平台类型、内容类型和 ID ---- - # KB Link Parser Skill -**kb-link-parser** - 从各种平台 URL 中提取和解析 ID。 +**kb-link-parser** - Extract and resolve IDs from various platform URLs. -## 什么时候使用 +## Features -- kb-workflow 步骤 1:解析用户提供的链接 -- 需要判断链接属于哪个平台、什么类型的内容 +- Multi-platform support: Bilibili, YouTube, Zhihu +- Short link detection: b23.tv and other short links +- Multiple content types: video, article, up主, playlist, collection +- Batch processing from file +- JSON output format -## 功能 - -- 多平台支持:Bilibili、YouTube、知乎、小红书 -- 短链接解析:b23.tv、xhslink.com 等 -- 多种内容类型:video、article、question、answer 等 -- 批量处理支持 -- JSON 输出格式 - -## 命令 +## Commands ```bash -# 解析单个 URL -python3 link-parser.py --url "https://www.bilibili.com/video/BV1xx411c7mD" +# Parse single URL +python link-parser.py --url "https://www.bilibili.com/video/BV1xx411c7mD" -# 批量处理 -python3 link-parser.py --batch urls.txt --output results.json +# Batch processing +python link-parser.py --batch urls.txt --output results.json -# 指定输出格式 -python3 link-parser.py --url "..." --format json +# Output format +python link-parser.py --url "..." --format json ``` -## 输出格式 Schema - -### 必需字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `success` | boolean | 是否解析成功 | -| `platform` | string | 平台名称(成功时必需) | -| `type` | string | 内容类型(成功时必需) | -| `id` | string | 内容 ID(成功时必需) | -| `error` | string | 错误信息(失败时必需) | - -### 可选字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `filename` | string | 建议的文件名 | -| `message` | string | 描述信息 | - -## 成功示例 - -### B站视频 +## Output ```json { "success": true, - "platform": "bilibili", - "type": "video", - "id": "BV1xx411c7mD", - "filename": "bilibili_BV1xx411c7mD.link.json", - "message": "URL解析成功" + "data": { + "platform": "bilibili", + "type": "video", + "id": "BV1xx411c7mD" + } } ``` -### B站专栏 - -```json -{ - "success": true, - "platform": "bilibili", - "type": "article", - "id": "cv43780186", - "filename": "bilibili_cv43780186.link.json", - "message": "URL解析成功" -} -``` - -### 知乎问答 - -```json -{ - "success": true, - "platform": "zhihu", - "type": "question", - "id": "266309957", - "filename": "zhihu_266309957.link.json", - "message": "URL解析成功" -} -``` - -### 知乎专栏文章 - -```json -{ - "success": true, - "platform": "zhihu", - "type": "zhuanlan", - "id": "1894054073625461813", - "filename": "zhihu_1894054073625461813.link.json", - "message": "URL解析成功" -} -``` - -### 知乎视频 - -```json -{ - "success": true, - "platform": "zhihu", - "type": "zvideo", - "id": "123456789", - "filename": "zhihu_123456789.link.json", - "message": "URL解析成功" -} -``` - -### 小红书笔记 - -```json -{ - "success": true, - "platform": "xiaohongshu", - "type": "note", - "id": "abc123", - "filename": "xiaohongshu_abc123.link.json", - "message": "URL解析成功" -} -``` - -## 错误示例 - -### 不支持的平台 - -```json -{ - "success": false, - "error": "Unsupported URL format", - "detail": "URL: https://example.com/video/123" -} -``` - -### 无效 URL - -```json -{ - "success": false, - "error": "解析失败", - "detail": "URL: not-a-valid-url" -} -``` - -## 支持的平台和类型 - -| 平台 | 类型 | URL 示例 | -|------|------|----------| -| bilibili | video | `bilibili.com/video/BVxxx` | -| bilibili | article | `bilibili.com/read/cvxxx` | -| bilibili | up主 | `space.bilibili.com/12345` | -| bilibili | favlist | `space.bilibili.com/123/favlist?fid=xxx` | -| zhihu | question | `zhihu.com/question/123` | -| zhihu | answer | `zhihu.com/question/123/answer/456` | -| zhihu | zhuanlan | `zhuanlan.zhihu.com/p/123` | -| zhihu | zvideo | `zhihu.com/zvideo/123` | -| xiaohongshu | note | `xiaohongshu.com/explore/xxx` | -| youtube | video | `youtube.com/watch?v=xxx` | - -## 安装 +## Installation ```bash -cp -r kb-link-parser/ ~/.openclaw/skills/ -pip install requests -``` - -## 在 kb-workflow 中的使用 - -```bash -# 步骤 1:链接解析 -python3 ~/.openclaw/skills/kb-link-parser/link-parser.py --url "[用户提供的URL]" - -# 解析输出后: -# - 检查 success 字段 -# - 提取 platform, type, id -# - 生成 pending/{platform}_{id}.link.json -# - 进入步骤 2(元数据提取) +cp -r kb-link-parser/ ~/skills/ ``` diff --git a/skills/kb-link-parser/__pycache__/link_parser_shortlink.cpython-312.pyc b/skills/kb-link-parser/__pycache__/link_parser_shortlink.cpython-312.pyc index 0e0cc49465218cafea336631956f1f5077455fb3..eeed19816b30e8fca3e9073134e6c6cc52360ef3 100644 GIT binary patch delta 64 zcmcZ}@-T$^G%qg~0}!mQ=-J4> ~/.kb_env -source ~/.kb_env +# 4. 下载更多模型(可选) +# ./models/download-ggml-model.sh base +# ./models/download-ggml-model.sh small -# 5. 复制技能 -cp -r kb-whisper/ ~/.openclaw/skills/ -``` - -## 在 kb-workflow 中的使用 - -```bash -# 步骤 4:语音识别(当 has_subtitle=false 时) -python3 ~/.openclaw/skills/kb-whisper/whisper.py \ - --input "content/downloads/bilibili_BV1xx411c7mD.mp4" \ - --model base \ - --output "content/" - -# 输出: -# - bilibili_BV1xx411c7mD.json (完整结果) -# - bilibili_BV1xx411c7mD.txt (纯文本) -# - bilibili_BV1xx411c7mD.srt (字幕文件) - -# 完成后进入步骤 5(深度分析) +# 5. 复制技能到 skills 目录 +cp -r kb-whisper/ ~/skills/ ``` ## 注意事项 -- **耗时操作**:语音识别可能需要几分钟到几十分钟,取决于视频长度 -- **异步执行**:推荐使用 `--background` 参数 -- **模型选择**:base 模型平衡速度和精度,适合大多数场景 -- **文件格式**:支持 MP3、MP4、WAV、FLAC、OGG、M4A 等常见格式 +- **异步执行**: 使用 `--background` 参数时,命令会在后台运行,不阻塞主代理 +- **模型选择**: tiny 模型适合快速识别,base 模型适合一般用途,large 模型适合高精度需求 +- **文件格式**: 支持 MP3、MP4、WAV、FLAC、OGG、M4A 等常见格式 diff --git a/skills/kb-workflow/SKILL.md b/skills/kb-workflow/SKILL.md index ccb435e..a4c8573 100644 --- a/skills/kb-workflow/SKILL.md +++ b/skills/kb-workflow/SKILL.md @@ -5,698 +5,200 @@ description: 当收到"添加到知识库 + 链接" 或"保存到知识库 + 链 # KB Workflow -## 触发条件 +## 什么时候使用 + +当用户发送包含以下模式的消息时,此技能自动触发: | 触发词 | 行为 | 示例 | |--------|------|------| | `添加到知识库` + 链接 | 添加到知识库并处理 | "添加到知识库 https://www.bilibili.com/video/BVxxx" | | `保存到知识库` + 链接 | 同上 | "保存到知识库 https://www.bilibili.com/video/BVxxx" | ---- +## 环境变量 -## 状态机定义 +### 执行前必须检查 -工作流是一个严格的状态机,每个状态有明确的前置条件和后置条件: +在执行 workflow 之前,必须检查环境变量是否已经设置。 -| 状态 | 前置条件 | 执行动作 | 成功后进入 | 失败处理 | -|------|---------|---------|-----------|---------| -| `init` | 用户触发 + URL 有效 | 创建 state.json,检查环境变量 | `link_parse` | 报错退出 | -| `link_parse` | state.json 存在 | 解析链接,提取平台和ID | `metadata` | 记录错误,最多重试1次 | -| `metadata` | platform, content_id 已知 | 提取元数据 | `content` | 记录错误,最多重试1次 | -| `content` | 元数据文件存在 | 下载内容/字幕 | `analyze` 或 `whisper` | 根据错误类型处理 | -| `whisper` | 视频已下载,无官方字幕 | 语音识别转文字 | `analyze` | 尝试 OCR 降级 | -| `analyze` | 有文本内容(字幕/识别结果/文章) | AI 深度分析 | `archive` | **流程失败,报错退出** | -| `archive` | 分析报告存在 | 归档 + Git 提交 | `done` | 记录错误,可手动处理 | -| `done` | - | 汇报完成 | - | - | - -### 状态判断流程图 - -``` -用户发送链接 - ↓ -┌─────────────────────────────────────┐ -│ Step 0: 环境变量检查 │ -│ 缺少必需变量 → 报错退出 │ -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ Step 1: 链接解析 (link_parse) │ -│ 输出: platform, content_type, id │ -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ Step 2: 元数据提取 (metadata) │ -│ 输出: title, author, etc. │ -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ content_type 判断 │ -├─────────────────────────────────────┤ -│ video/zvideo → Step 3a (视频处理) │ -│ article/zhuanlan/question → Step 3b │ -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ Step 3a: 视频处理 │ -│ 有官方字幕? → 是 → Step 5 │ -│ → 否 → Step 4 (Whisper) │ -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ Step 3b: 文章处理 │ -│ 提取文字 → 直接进入 Step 5 │ -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ Step 4: Whisper 语音识别 (可选) │ -│ 无字幕时执行,生成 text/json/srt │ -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ Step 5: 深度分析 (analyze) │ -│ ⚠️ 必须成功,否则流程失败 │ -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ Step 6: 归档 (archive) │ -│ 复制到归档目录 + Git 提交 │ -└─────────────────────────────────────┘ - ↓ - 完成 -``` - ---- - -## 环境变量清单 - -### 必需变量(缺失则报错退出) - -| 变量名 | 用途 | 示例 | -|--------|------|------| -| `AI_API_KEY` | AI API 密钥 | `your-api-key` | -| `AI_PROVIDER` | AI 提供商 | `zhipu` / `openai` / `minimax` | -| `AI_MODEL` | 模型名称 | `glm-5` / `gpt-4` | -| `AI_BASE_URL` | API 端点 | `https://open.bigmodel.cn/api/coding/paas/v4` | - -### 可选变量 - -| 变量名 | 用途 | 用途说明 | -|--------|------|---------| -| `BILIBILI_COOKIE` | B站登录态 | 下载会员视频 | -| `ZHIHU_COOKIE` | 知乎登录态 | 访问专栏等 | -| `HF_TOKEN` | HuggingFace Token | 说话者分离功能 | -| `KB_ARCHIVE_PATH` | 归档目录 | 默认 `~/work/zq/30.资源/AI分析` | -| `KB_GIT_ROOT` | Git 仓库根目录 | 默认 `~/work/zq` | -| `KB_GIT_USER` | Git 提交用户名 | 归档时使用 | -| `KB_GIT_EMAIL` | Git 提交邮箱 | 归档时使用 | - -### 配置方法 +**必须的环境变量**(缺失则报错退出): +配置方式:将变量写入 `~/.kb_env` 文件: ```bash -# 创建专用配置文件 -cat > ~/.kb_env << 'EOF' export AI_API_KEY="your-api-key" export AI_PROVIDER="zhipu" export AI_MODEL="glm-5" export AI_BASE_URL="https://open.bigmodel.cn/api/coding/paas/v4" -export BILIBILI_COOKIE="SESSDATA=xxx; bili_jct=xxx" -export KB_ARCHIVE_PATH="$HOME/work/zq/30.资源/AI分析" -export KB_GIT_ROOT="$HOME/work/zq" -EOF - -# 在 ~/.bashrc 中添加 -[ -f ~/.kb_env ] && source ~/.kb_env ``` ---- +**可选的环境变量**: +| 变量名 | 用途 | 示例 | +|--------|------|------| +| `BILIBILI_COOKIE` | 下载会员视频 | `SESSDATA=xxx; bili_jct=xxx` | +| `KB_GIT_USER` | Git提交用户名 | `Your Name` | +| `KB_GIT_EMAIL` | Git提交邮箱 | `your@email.com` | +| `KB_ARCHIVE_PATH` | 归档目录路径 | `~/work/zq/30.资源/AI分析` | +| `KB_GIT_ROOT` | Git仓库根目录 | `~/work/zq` | +| `HF_TOKEN` | HuggingFace Token(说话者分离) | `hf_xxx` | -## 步骤详解 +### 检查命令 -### Step 0: 环境变量检查 - -**前置条件:** 无 - -**执行命令:** ```bash -# 加载环境变量 -if [ -f ~/.kb_env ]; then source ~/.kb_env; fi +# 从 ~/.kb_env 加载环境变量 +if [ -f ~/.kb_env ]; then + source ~/.kb_env +fi + +# 检查必须的环境变量 +if [ -z "$AI_API_KEY" ] || [ -z "$AI_PROVIDER" ] || [ -z "$AI_MODEL" ] || [ -z "$AI_BASE_URL" ]; then + echo "❌ 错误:必须的环境变量未设置" + echo "请配置 ~/.kb_env 文件" + exit 1 +fi -# 检查必需变量 -for var in AI_API_KEY AI_PROVIDER AI_MODEL AI_BASE_URL; do - if [ -z "${!var}" ]; then - echo "❌ 错误:$var 未设置" - exit 1 - fi -done echo "✅ 环境变量检查通过" ``` -**成功标准:** -- 所有必需变量已设置 -- 输出 "✅ 环境变量检查通过" +## Workflow 执行方式 -**失败处理:** -- 缺少任何必需变量 → 报错退出,提示用户配置 +### 方式一:一键处理(推荐) -**输出示例:** -``` -✅ 环境变量检查通过 - AI_PROVIDER: zhipu - AI_MODEL: glm-5 -``` +使用管道 CLI 一键完成所有步骤: -**错误示例:** -``` -❌ 错误:AI_API_KEY 未设置 -请配置以下环境变量: - - AI_API_KEY - - AI_PROVIDER - - AI_MODEL - - AI_BASE_URL -``` - ---- - -### Step 1: 链接解析 - -**前置条件:** -- 环境变量检查通过 -- URL 格式有效 - -**执行命令:** ```bash -# 获取目录路径 -python3 ~/.openclaw/skills/kb-workflow/kb_workflow.py --pending - -# 解析链接 -python3 ~/.openclaw/skills/kb-link-parser/link-parser.py --url "[URL]" +python3 kb-workflow/kb_workflow.py process "https://www.bilibili.com/video/BVxxx" ``` -**成功标准:** -- 返回 JSON 包含 `success: true` -- 包含字段:`platform`, `content_type`, `content_id` -- 生成文件:`pending/{platform}_{id}.link.json` +**该命令自动执行:** +1. URL 解析 → 识别平台和内容 ID +2. 元数据提取 → 获取标题、作者等信息 +3. 内容下载 → 字幕/视频/文章内容 +4. 语音识别 → Whisper/FunASR(如需要) +5. 深度分析 → AI 生成分析报告 +6. 归档 → 移动到归档目录 -**失败处理:** -- 不支持的平台 → 报错退出,告知用户支持的平台 -- URL 无效 → 报错退出,请用户提供正确链接 - -**输出示例:** -```json -{ - "success": true, - "platform": "bilibili", - "content_type": "video", - "content_id": "BV1xx411c7mD", - "output_file": "pending/bilibili_BV1xx411c7mD.link.json" -} -``` - -**错误示例:** -```json -{ - "success": false, - "error": "不支持的平台: example.com", - "supported_platforms": ["bilibili.com", "zhihu.com", "youtube.com"] -} -``` - ---- - -### Step 2: 元数据提取 - -**前置条件:** -- Step 1 完成 -- `platform`, `content_type`, `content_id` 已知 - -**执行命令:** +**命令参数:** ```bash -# 获取目录路径 -python3 ~/.openclaw/skills/kb-workflow/kb_workflow.py --metadata +# 指定输出目录 +python3 kb-workflow/kb_workflow.py process "https://..." -o /path/to/output -# 根据平台选择命令 -# B站视频 -python3 ~/.openclaw/skills/kb-bilibili-metadata/bilibili_metadata.py \ - --id "[BV号]" --type video \ - --output "metadata/bilibili_[BV号].meta.json" - -# B站专栏 -python3 ~/.openclaw/skills/kb-bilibili-metadata/bilibili_metadata.py \ - --id "[cv号]" --type article \ - --output "metadata/bilibili_cv[cv号].meta.json" - -# 知乎问答 -python3 ~/.openclaw/skills/kb-zhihu-metadata/zhihu_metadata.py \ - --id "[问题ID]" --type question \ - --output "metadata/zhihu_[ID].meta.json" - -# 知乎视频 -python3 ~/.openclaw/skills/kb-zhihu-metadata/zhihu_metadata.py \ - --id "[视频ID]" --type zvideo \ - --output "metadata/zhihu_[ID].meta.json" +# 强制重新执行(忽略已完成状态) +python3 kb-workflow/kb_workflow.py process "https://..." --no-skip ``` -**成功标准:** -- 返回 JSON 包含 `success: true` -- 包含字段:`platform`, `content_id`, `title` -- 生成文件:`metadata/{platform}_{id}.meta.json` +### 方式二:手动分步执行(高级) -**失败处理:** -- 网络错误 → 重试1次 -- 内容不存在 → 报错退出 -- 需要登录 → 提示配置 Cookie +如需更细粒度控制,可手动调用各子技能: -**输出示例:** -```json -{ - "success": true, - "platform": "bilibili", - "content_id": "BV1xx411c7mD", - "content_type": "video", - "title": "视频标题", - "author": "UP主名字", - "duration": "10:30", - "output_file": "metadata/bilibili_BV1xx411c7mD.meta.json" -} -``` - -**错误示例:** -```json -{ - "success": false, - "error": "视频不存在或已被删除", - "content_id": "BV1xx411c7mD" -} -``` - ---- - -### Step 3a: 视频内容下载 - -**前置条件:** -- Step 2 完成 -- `content_type` 为 `video` 或 `zvideo` - -**执行命令:** ```bash -# 获取目录路径 -python3 ~/.openclaw/skills/kb-workflow/kb_workflow.py --content_downloads +# 1. 查重 +python3 kb-workflow/kb_workflow.py --check --url "https://..." -# B站视频 - 优先尝试字幕 -python3 ~/.openclaw/skills/kb-bilibili-content/bilibili_content.py \ - --id "[BV号]" --type subtitle-download \ - --output "content/downloads/" +# 2. 一键处理 +python3 kb-workflow/kb_workflow.py process "https://..." -# 检查是否有官方字幕 -# 如果 has_subtitle=true → 进入 Step 5 -# 如果 has_subtitle=false → 下载视频,进入 Step 4 +# 3. 归档 +python3 kb-workflow/kb_workflow.py --archive-file "/path/to/report.md" ``` -**成功标准:** -- 返回 JSON 包含 `success: true` -- `has_subtitle=true`: 有字幕文件 -- `has_subtitle=false`: 视频文件下载成功 +## 支持的平台和内容类型 -**失败处理:** -- 403 禁止访问 → 检查 BILIBILI_COOKIE 配置 -- 网络超时 → 重试1次 -- 会员视频 → 提示需要配置 Cookie +| 平台 | 内容类型 | URL 示例 | +|------|----------|----------| +| B站 | 视频 | `bilibili.com/video/BVxxx` | +| B站 | 专栏 | `bilibili.com/read/cvxxx` | +| 知乎 | 问答 | `zhihu.com/question/xxx` | +| 知乎 | 专栏 | `zhuanlan.zhihu.com/p/xxx` | +| 知乎 | 视频 | `zhihu.com/zvideo/xxx` | + +## 处理流程 -**输出示例(有字幕):** -```json -{ - "success": true, - "type": "subtitle", - "has_subtitle": true, - "subtitle_file": "content/downloads/bilibili_BV1xx411c7mD.srt", - "message": "官方字幕下载成功" -} ``` - -**输出示例(无字幕):** -```json -{ - "success": true, - "type": "subtitle", - "has_subtitle": false, - "message": "无官方字幕,需要下载视频进行语音识别" -} +┌─────────────────────────────────────────────────────────────┐ +│ kb-workflow process │ +├─────────────────────────────────────────────────────────────┤ +│ 1. Parse → LinkParser 解析 URL │ +│ 2. Download → 平台适配器获取元数据和内容 │ +│ 3. ASR → 语音识别(视频无字幕时) │ +│ 4. Analyze → DeepAnalyzer 生成分析报告 │ +│ 5. Archive → 归档到 KB_ARCHIVE_PATH │ +└─────────────────────────────────────────────────────────────┘ ``` -**错误示例:** -```json -{ - "success": false, - "error": "403 Forbidden - 可能需要会员权限", - "suggestion": "请配置 BILIBILI_COOKIE 环境变量" -} -``` - ---- - -### Step 3b: 文章内容提取 - -**前置条件:** -- Step 2 完成 -- `content_type` 为 `article`、`zhuanlan` 或 `question` - -**执行命令:** -```bash -# B站专栏 -python3 ~/.openclaw/skills/kb-bilibili-content/bilibili_content.py \ - --id "[cv号]" --type article \ - --output "content/" - -# 知乎专栏 -python3 ~/.openclaw/skills/kb-zhihu-content/zhihu_content.py \ - --type article-from-media \ - --output "content/" -``` - -**成功标准:** -- 返回 JSON 包含 `success: true` -- 包含字段:`filepath`, `content_length` -- 跳过 Step 4,直接进入 Step 5 - -**输出示例:** -```json -{ - "success": true, - "type": "article", - "filepath": "content/bilibili_cv43780186.txt", - "content_length": 5234, - "message": "文章内容提取成功" -} -``` - ---- - -### Step 4: Whisper 语音识别 - -**前置条件:** -- Step 3a 完成 -- `has_subtitle=false` -- 视频文件已下载 - -**执行命令:** -```bash -# 获取目录路径 -python3 ~/.openclaw/skills/kb-workflow/kb_workflow.py --content - -# 普通识别 -python3 ~/.openclaw/skills/kb-whisper/whisper.py \ - --input "content/downloads/bilibili_BV1xx411c7mD.mp4" \ - --model base \ - --output "content/" - -# 带说话者分离(需要 HF_TOKEN) -if [ -n "$HF_TOKEN" ]; then - python3 ~/.openclaw/skills/kb-whisper-diarization/whisper_diarization.py \ - --input "content/downloads/bilibili_BV1xx411c7mD.mp4" \ - --model base --diarize \ - --output "content/" -fi -``` - -**成功标准:** -- 返回 JSON 包含 `success: true` -- 生成文件:`.json`, `.txt`, `.srt` - -**失败处理:** -- 模型未下载 → 提示下载模型 -- 内存不足 → 尝试更小的模型 -- Whisper 失败 → 尝试 OCR 降级 - -**输出示例:** -```json -{ - "success": true, - "input_file": "content/downloads/bilibili_BV1xx411c7mD.mp4", - "model": "base", - "output_files": { - "json": "content/bilibili_BV1xx411c7mD.json", - "txt": "content/bilibili_BV1xx411c7mD.txt", - "srt": "content/bilibili_BV1xx411c7mD.srt" - }, - "duration_seconds": 630 -} -``` - ---- - -### Step 5: 深度分析 - -**前置条件:** -- 有文本内容(字幕/识别结果/文章) -- 元数据文件存在 - -**执行命令:** -```bash -# 获取目录路径 -python3 ~/.openclaw/skills/kb-workflow/kb_workflow.py --analyzed - -# 分析视频 -AI_API_KEY="$AI_API_KEY" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \ -python3 -u ~/.openclaw/skills/kb-deep-analyzer/deep_analyzer.py \ - --metadata "metadata/bilibili_BV1xx411c7mD.meta.json" \ - --content "content/bilibili_BV1xx411c7mD.json" \ - --output "analyzed/bilibili_BV1xx411c7mD.md" \ - --type video \ - --provider zhipu --model glm-5 - -# 分析文章 -AI_API_KEY="$AI_API_KEY" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \ -python3 -u ~/.openclaw/skills/kb-deep-analyzer/deep_analyzer.py \ - --metadata "metadata/xxx.meta.json" \ - --content "content/xxx.txt" \ - --output "analyzed/xxx.md" \ - --type article \ - --provider zhipu --model glm-5 -``` - -**成功标准:** -- 返回 JSON 包含 `success: true` -- 生成分析报告文件 - -**失败处理:** -- ⚠️ **深度分析失败 = 整个流程失败** -- API 调用失败 → 记录错误,**终止流程** -- **禁止**使用预设模板或降级内容 - -**输出示例:** -```json -{ - "success": true, - "output_file": "analyzed/bilibili_BV1xx411c7mD.md", - "model": "glm-5", - "provider": "zhipu" -} -``` - -**错误示例:** -```json -{ - "success": false, - "error": "AI API 调用失败: rate limit exceeded", - "message": "深度分析失败,整个流程终止" -} -``` - ---- - -### Step 6: 归档 - -**前置条件:** -- Step 5 完成 -- 分析报告文件存在 - -**执行命令:** -```bash -# 归档 -python3 ~/.openclaw/skills/kb-workflow/kb_workflow.py \ - --archive-file "analyzed/bilibili_BV1xx411c7mD.md" - -# 如果配置了 Git,会自动提交 -``` - -**成功标准:** -- 文件复制到归档目录 -- Git 提交成功(如果配置) - -**失败处理:** -- 归档失败 → 记录错误,文件仍可用 -- Git 失败 → 不影响主流程 - -**输出示例:** -```json -{ - "success": true, - "archive_path": "~/work/zq/30.资源/AI分析/2026-03-13/bilibili_BV1xx411c7mD.md", - "git_commit": "abc1234" -} -``` - ---- - ## 目录结构 +**工作目录(默认 ~/work/knowledge-base/):** +``` +~/work/knowledge-base/ +├── pending/ # 待处理链接 +├── metadata/ # 元数据 JSON +├── content/ # 内容文件 +│ └── downloads/ # 下载的视频/字幕 +└── analyzed/ # 分析报告 ``` -~/work/knowledge-base/ # 知识库根目录 -├── pending/ # 待处理链接 -│ └── {platform}_{id}.link.json -├── metadata/ # 元数据 -│ └── {platform}_{id}.meta.json -├── content/ # 内容 -│ ├── downloads/ # 视频下载 -│ │ └── {platform}_{id}.mp4 -│ ├── {platform}_{id}.txt # 文本内容 -│ └── {platform}_{id}.json # Whisper 结果 -└── analyzed/ # 深度分析报告 - └── {platform}_{id}.md -~/work/zq/30.资源/AI分析/ # 归档目录 +**归档目录(默认 ~/work/zq/30.资源/AI分析/):** +``` +~/work/zq/30.资源/AI分析/ └── YYYY-MM-DD/ - └── {platform}_{id}.md + └── {platform}_{id}.md # 深度分析报告 ``` ---- - -## 子技能清单 - -| 步骤 | 子技能 | 命令 | -|------|--------|------| -| 1 | kb-link-parser | `--url "[URL]"` | -| 2 | kb-bilibili-metadata | `--id "[ID]" --type video --output "[PATH]"` | -| 2 | kb-zhihu-metadata | `--id "[ID]" --type question --output "[PATH]"` | -| 3a | kb-bilibili-content | `--id "[ID]" --type subtitle-download --output "[PATH]"` | -| 3a | kb-bilibili-content | `--id "[ID]" --type video --output "[PATH]"` | -| 3b | kb-bilibili-content | `--id "[ID]" --type article --output "[PATH]"` | -| 3b | kb-zhihu-content | `--type article-from-media --output "[PATH]"` | -| 4 | kb-whisper | `--input "[VIDEO]" --model base --output "[PATH]"` | -| 4 | kb-whisper-diarization | `--input "[VIDEO]" --model base --diarize --output "[PATH]"` | -| 5 | kb-deep-analyzer | `--metadata "[META]" --content "[CONTENT]" --output "[OUT]" --type video` | - ---- - -## 端到端示例 - -### 示例 1: B站视频(有官方字幕) - -**输入:** `添加到知识库 https://www.bilibili.com/video/BV1xx411c7mD` - -``` -Step 0: ✅ 环境变量检查通过 -Step 1: ✅ 链接解析 → bilibili, video, BV1xx411c7mD -Step 2: ✅ 元数据提取 → 标题: "xxx", 作者: "xxx" -Step 3a: ✅ 字幕下载 → has_subtitle=true, bilibili_BV1xx411c7mD.srt -Step 4: ⏭️ 跳过(有官方字幕) -Step 5: ✅ 深度分析 → bilibili_BV1xx411c7mD.md -Step 6: ✅ 归档 → ~/work/zq/30.资源/AI分析/2026-03-13/ -``` - -### 示例 2: B站视频(无官方字幕) - -**输入:** `添加到知识库 https://www.bilibili.com/video/BV1yy411c7mE` - -``` -Step 0: ✅ 环境变量检查通过 -Step 1: ✅ 链接解析 → bilibili, video, BV1yy411c7mE -Step 2: ✅ 元数据提取 → 标题: "xxx", 时长: "15:30" -Step 3a: ⚠️ 无官方字幕 → 下载视频 -Step 3a: ✅ 视频下载 → bilibili_BV1yy411c7mE.mp4 -Step 4: ✅ Whisper 识别 → bilibili_BV1yy411c7mE.json/txt/srt -Step 5: ✅ 深度分析 → bilibili_BV1yy411c7mE.md -Step 6: ✅ 归档 -``` - -### 示例 3: 403 下载失败 - -**输入:** `添加到知识库 https://www.bilibili.com/video/BV1zz411c7mF` - -``` -Step 0: ✅ 环境变量检查通过 -Step 1: ✅ 链接解析 -Step 2: ✅ 元数据提取 -Step 3a: ❌ 403 Forbidden - → 可能需要会员权限 - → 请配置 BILIBILI_COOKIE 环境变量 - → 流程暂停,等待用户处理 -``` - ---- - -## 常见错误处理 - -### 错误 1: 环境变量未设置 - -**症状:** `❌ 错误:AI_API_KEY 未设置` - -**解决:** -```bash -echo 'export AI_API_KEY="your-key"' >> ~/.kb_env -source ~/.kb_env -``` - -### 错误 2: 403 下载失败 - -**症状:** B站视频下载返回 403 - -**解决:** -1. 获取 B站 Cookie(F12 → Network → Copy Cookie) -2. 配置环境变量: -```bash -echo 'export BILIBILI_COOKIE="SESSDATA=xxx; bili_jct=xxx"' >> ~/.kb_env -source ~/.kb_env -``` - -### 错误 3: 深度分析失败 - -**症状:** `success: false` from kb-deep-analyzer - -**处理:** -- **整个流程终止** -- 检查 AI_API_KEY 是否有效 -- 检查 AI_BASE_URL 是否正确 -- 检查模型配额是否用尽 - -### 错误 4: Whisper 模型未下载 - -**症状:** `Model file not found` - -**解决:** -```bash -cd ~/whisper.cpp -./models/download-ggml-model.sh base -``` - ---- - -## 状态管理(断点续传) - -> ⚠️ 此功能需要完成 P3 实现 - -```bash -# 初始化状态 -python3 kb_workflow.py --init-state "[URL]" - -# 查询当前状态 -python3 kb_workflow.py --get-state "[URL]" - -# 推进到下一步 -python3 kb_workflow.py --advance-step "[URL]" "metadata" - -# 记录错误 -python3 kb_workflow.py --record-error "[URL]" "403 Forbidden" - -# 获取恢复指令 -python3 kb_workflow.py --resume "[URL]" -``` - ---- - ## ⚠️ 严格失败处理原则 -1. **深度分析不可跳过**:kb-deep-analyzer 是必须成功的步骤 -2. **失败即终止**:如果深度分析返回 `success: false`,必须立即停止 -3. **禁止降级处理**:不能使用预设模板或简单摘要"假装成功" -4. **每次执行都要使用 AI**:必须有真实的 AI API 调用 +> **深度分析步骤必须成功,否则整个流程失败** + +1. **深度分析不可跳过**:AI 分析是必须成功执行的步骤 +2. **失败即终止**:如果分析返回失败,必须立即停止并汇报 +3. **禁止降级处理**:不能使用预设模板或简单摘要来"假装成功" +4. **每次执行都要使用 AI**:必须有真实的 AI API 调用记录 + +## 辅助命令 + +```bash +# 查重 +python3 kb-workflow/kb_workflow.py --check --url "https://..." + +# 获取目录路径 +python3 kb-workflow/kb_workflow.py --base-path +python3 kb-workflow/kb_workflow.py --metadata +python3 kb-workflow/kb_workflow.py --content +python3 kb-workflow/kb_workflow.py --analyzed + +# 归档分析报告 +python3 kb-workflow/kb_workflow.py --archive-file "/path/to/report.md" +``` + +## 示例 + +``` +用户: 添加到知识库 https://www.bilibili.com/video/BV1xx + +Claude: +✅ 环境变量检查通过 + +◆ 处理中... + → 解析 URL: bilibili 视频 BV1xx + → 获取元数据... + → 下载字幕... + → 深度分析... + +✅ 完成! + +标题: 【教程】如何使用 Python 进行数据分析 +处理阶段: 全部完成 +最终文件: ~/work/zq/30.资源/AI分析/2026-03-15/bilibili_BV1xx.md +``` + +## 技术架构 + +``` +kb-workflow/kb_workflow.py (CLI) + └── kb_pipeline/ (核心管道包) + ├── pipeline.py — Pipeline 编排引擎 + ├── processors/ — 处理器实现 + │ ├── parse.py — URL 解析 + │ ├── download.py — 内容下载 + │ ├── asr.py — 语音识别 + │ └── analyze.py — 深度分析 + └── schemas.py — 数据模型 +``` diff --git a/skills/kb-workflow/kb_workflow.py b/skills/kb-workflow/kb_workflow.py index dc50927..540b0ae 100644 --- a/skills/kb-workflow/kb_workflow.py +++ b/skills/kb-workflow/kb_workflow.py @@ -5,7 +5,7 @@ KB Workflow - Knowledge Base Workflow Orchestrator 知识库工作流辅助工具函数。 -此模块提供查重、文件操作、Git 管理、状态管理等工具函数, +此模块提供查重、文件操作、Git 管理等工具函数, 供主代理在执行 SKILL.md 中定义的 workflow 时调用。 """ @@ -18,46 +18,7 @@ import shutil import re from datetime import datetime from pathlib import Path -from typing import Dict, List, Optional, Any, Tuple - - -# ==================== 状态机定义 ==================== - -# 工作流步骤顺序 -WORKFLOW_STEPS = [ - "init", - "link_parse", - "metadata", - "content", - "whisper", # 可选步骤 - "analyze", - "archive", - "done" -] - -# 每个步骤的必需输出字段 -STEP_OUTPUT_FIELDS = { - "init": [], - "link_parse": ["platform", "content_type", "content_id"], - "metadata": ["title"], - "content": ["filepath"], - "whisper": ["output_files"], - "analyze": ["output_file"], - "archive": ["archive_path"], - "done": [] -} - -# 步骤描述(用于汇报) -STEP_DESCRIPTIONS = { - "init": "初始化", - "link_parse": "链接解析", - "metadata": "元数据提取", - "content": "内容下载", - "whisper": "语音识别", - "analyze": "深度分析", - "archive": "归档", - "done": "完成" -} +from typing import Dict, List, Optional, Any # ==================== 子技能映射 ==================== @@ -332,249 +293,6 @@ def archive_and_git( return result -# ==================== 状态管理 ==================== - -def get_state_file_path(url: str, base_path: Path = None) -> Path: - """获取状态文件路径""" - if base_path is None: - base_path = get_knowledge_base_path() - pending_dir = base_path / "pending" - pending_dir.mkdir(parents=True, exist_ok=True) - - # 从 URL 提取标识符 - # 尝试提取 BV 号或其他 ID - bv_match = re.search(r'BV[a-zA-Z0-9]+', url) - if bv_match: - content_id = bv_match.group() - platform = "bilibili" - else: - # 尝试提取知乎 ID - zhihu_match = re.search(r'zhihu\.com/(?:question|zvideo|p)/(\d+)', url) - if zhihu_match: - content_id = zhihu_match.group(1) - platform = "zhihu" - else: - # 使用 URL hash 作为标识 - import hashlib - content_id = hashlib.md5(url.encode()).hexdigest()[:12] - platform = "unknown" - - return pending_dir / f"{platform}_{content_id}.state.json" - - -def init_state(url: str, base_path: Path = None) -> Dict[str, Any]: - """初始化工作流状态""" - state_file = get_state_file_path(url, base_path) - - # 如果状态文件已存在,返回现有状态 - if state_file.exists(): - with open(state_file, 'r', encoding='utf-8') as f: - return json.load(f) - - # 创建新状态 - now = datetime.now().isoformat() - state = { - "url": url, - "platform": None, - "content_id": None, - "content_type": None, - "current_step": "init", - "completed_steps": [], - "step_results": {}, - "errors": [], - "created_at": now, - "updated_at": now - } - - with open(state_file, 'w', encoding='utf-8') as f: - json.dump(state, f, ensure_ascii=False, indent=2) - - return state - - -def get_state(url: str, base_path: Path = None) -> Dict[str, Any]: - """获取当前工作流状态""" - state_file = get_state_file_path(url, base_path) - - if not state_file.exists(): - return { - "success": False, - "error": "状态文件不存在", - "url": url, - "state_file": str(state_file) - } - - with open(state_file, 'r', encoding='utf-8') as f: - state = json.load(f) - - return { - "success": True, - "state": state, - "state_file": str(state_file) - } - - -def advance_step( - url: str, - step_name: str, - result: Dict[str, Any] = None, - base_path: Path = None -) -> Dict[str, Any]: - """推进到下一步并记录结果""" - state_file = get_state_file_path(url, base_path) - - if not state_file.exists(): - return { - "success": False, - "error": "状态文件不存在,请先执行 --init-state" - } - - with open(state_file, 'r', encoding='utf-8') as f: - state = json.load(f) - - # 验证步骤名称 - if step_name not in WORKFLOW_STEPS: - return { - "success": False, - "error": f"无效的步骤名称: {step_name}", - "valid_steps": WORKFLOW_STEPS - } - - # 获取当前步骤索引 - try: - current_idx = WORKFLOW_STEPS.index(state["current_step"]) - new_idx = WORKFLOW_STEPS.index(step_name) - except ValueError: - return { - "success": False, - "error": f"步骤索引错误" - } - - # 更新状态 - if step_name != state["current_step"]: - # 标记当前步骤为完成 - if state["current_step"] not in state["completed_steps"]: - state["completed_steps"].append(state["current_step"]) - - state["current_step"] = step_name - state["updated_at"] = datetime.now().isoformat() - - # 记录步骤结果 - if result: - state["step_results"][step_name] = result - - # 提取平台和 ID 信息(从 link_parse 步骤) - if step_name == "link_parse" and result.get("success"): - state["platform"] = result.get("platform") - state["content_id"] = result.get("content_id") - state["content_type"] = result.get("type") - - # 保存状态 - with open(state_file, 'w', encoding='utf-8') as f: - json.dump(state, f, ensure_ascii=False, indent=2) - - return { - "success": True, - "current_step": step_name, - "completed_steps": state["completed_steps"], - "state_file": str(state_file) - } - - -def record_error( - url: str, - error_msg: str, - step: str = None, - base_path: Path = None -) -> Dict[str, Any]: - """记录错误""" - state_file = get_state_file_path(url, base_path) - - if not state_file.exists(): - return { - "success": False, - "error": "状态文件不存在,请先执行 --init-state" - } - - with open(state_file, 'r', encoding='utf-8') as f: - state = json.load(f) - - # 记录错误 - error_entry = { - "step": step or state["current_step"], - "error": error_msg, - "timestamp": datetime.now().isoformat() - } - state["errors"].append(error_entry) - state["updated_at"] = datetime.now().isoformat() - - # 保存状态 - with open(state_file, 'w', encoding='utf-8') as f: - json.dump(state, f, ensure_ascii=False, indent=2) - - return { - "success": True, - "error_recorded": error_entry, - "total_errors": len(state["errors"]) - } - - -def get_resume_info(url: str, base_path: Path = None) -> Dict[str, Any]: - """获取恢复执行的指令""" - state_file = get_state_file_path(url, base_path) - - if not state_file.exists(): - return { - "success": False, - "error": "状态文件不存在", - "suggestion": "请使用 --init-state 初始化工作流" - } - - with open(state_file, 'r', encoding='utf-8') as f: - state = json.load(f) - - current_step = state["current_step"] - step_desc = STEP_DESCRIPTIONS.get(current_step, current_step) - - # 检查是否有错误 - if state["errors"]: - last_error = state["errors"][-1] - return { - "success": True, - "status": "error", - "current_step": current_step, - "step_description": step_desc, - "last_error": last_error, - "completed_steps": state["completed_steps"], - "suggestion": f"请先解决 {last_error['step']} 步骤的错误: {last_error['error']}" - } - - # 检查是否已完成 - if current_step == "done": - return { - "success": True, - "status": "completed", - "current_step": "done", - "step_description": "已完成", - "completed_steps": state["completed_steps"], - "step_results": state["step_results"] - } - - # 返回下一步指令 - return { - "success": True, - "status": "in_progress", - "current_step": current_step, - "step_description": step_desc, - "completed_steps": state["completed_steps"], - "next_action": f"继续执行步骤: {step_desc}", - "platform": state.get("platform"), - "content_id": state.get("content_id"), - "content_type": state.get("content_type"), - "step_results": state.get("step_results", {}) - } - - def generate_summary(url: str, stages: List[Dict], final_file: str, archive_result: Dict = None) -> str: """生成处理完成汇报""" # 提取视频标题(如果有) @@ -607,6 +325,83 @@ def generate_summary(url: str, stages: List[Dict], final_file: str, archive_resu return summary +# ==================== CLI Process Command ==================== + +def process_command( + url: str, + output_dir: Optional[str] = None, + skip_completed: bool = True +) -> Dict[str, Any]: + """Execute full pipeline for a URL + + Args: + url: URL to process + output_dir: Optional output directory for content + skip_completed: Skip already completed steps (default True) + + Returns: + Dictionary with success status, content_dir, and results + """ + import asyncio + + # Add project root to path for kb_pipeline imports + project_root = Path(__file__).parent.parent + if str(project_root) not in sys.path: + sys.path.insert(0, str(project_root)) + + try: + from kb_pipeline.pipeline import Pipeline + from kb_pipeline.processors import ParseProcessor, DownloadProcessor, ASRProcessor, AnalyzeProcessor + from kb_pipeline.schemas import PipelineConfig + + async def run_pipeline(): + # Determine output directory + out_dir = Path(output_dir) if output_dir else Path.cwd() + + # Create processors + processors = [ + ParseProcessor(), + DownloadProcessor(), + ASRProcessor(), + AnalyzeProcessor(), + ] + + # Create pipeline config + config = PipelineConfig( + steps=["parse", "download", "asr", "analyze"], + output_dir=out_dir, + skip_completed=skip_completed, + ) + + # Create and run pipeline + pipeline = Pipeline( + processors=processors, + config=config, + output_dir=out_dir, + ) + + result = await pipeline.run(url) + return result + + # Run async pipeline + result = asyncio.run(run_pipeline()) + + return { + "success": result.success, + "error": result.error_message, + "content_dir": str(result.content_dir) if result.content_dir else None, + "results": result.results, + } + + except Exception as e: + return { + "success": False, + "error": str(e), + "content_dir": None, + "results": {}, + } + + # ==================== CLI ==================== def main(): @@ -618,117 +413,96 @@ def main(): 使用示例: # 查重 python kb_workflow.py --check --url "https://www.bilibili.com/video/BVxxx" - + # 归档 - python kb_workflow.py --archive-file "/path/to/analyzed.md" - - # 状态管理 - python kb_workflow.py --init-state --url "https://..." - python kb_workflow.py --get-state --url "https://..." - python kb_workflow.py --advance-step --url "https://..." --step "metadata" --result '{"success":true}' - python kb_workflow.py --record-error --url "https://..." --error-msg "403 Forbidden" - python kb_workflow.py --resume --url "https://..." + python kb_workflow.py --archive "/path/to/analyzed.md" + + # 处理URL (通过完整管道) + python kb_workflow.py process "https://www.bilibili.com/video/BVxxx" """ ) - - # 基础参数 - parser.add_argument('--url', type=str, help='URL 地址') - parser.add_argument('--base-path', type=str, help='知识库根目录') - - # 查重和归档 + + # Create subparsers for commands + subparsers = parser.add_subparsers(dest='command', help='Available commands') + + # Process subcommand + process_parser = subparsers.add_parser('process', help='Process URL through full pipeline') + process_parser.add_argument('url', type=str, help='URL to process') + process_parser.add_argument('--output-dir', '-o', type=str, help='Output directory for content') + process_parser.add_argument('--skip-completed', action='store_true', default=True, + help='Skip completed steps (default: True)') + process_parser.add_argument('--no-skip', action='store_false', dest='skip_completed', + help='Re-run all steps') + + # Legacy arguments (for backward compatibility) parser.add_argument('--check', action='store_true', help='查重') + parser.add_argument('--url', type=str, help='要检查的URL') parser.add_argument('--archive-file', type=str, help='归档的文件路径') - - # 目录路径查询 - parser.add_argument('--pending', action='store_true', help='获取 URL 解析目录') + parser.add_argument('--base-path', type=str, help='获取知识库根目录') + + parser.add_argument('--pending', action='store_true', help='获取url解析目录') parser.add_argument('--metadata', action='store_true', help='获取元数据目录') parser.add_argument('--content', action='store_true', help='获取内容目录') - parser.add_argument('--content_downloads', action='store_true', help='获取内容下载目录') + parser.add_argument('--content_downloads', action='store_true', help='获取主内容下载目录') parser.add_argument('--analyzed', action='store_true', help='获取深度分析目录') parser.add_argument('--archive_dir', action='store_true', help='获取归档目录') parser.add_argument('--archive_subscriptions', action='store_true', help='获取订阅信息目录') - parser.add_argument('--extract_platform', type=str, help='从文件名提取平台名称') - - # 状态管理 - parser.add_argument('--init-state', action='store_true', help='初始化工作流状态') - parser.add_argument('--get-state', action='store_true', help='获取当前状态') - parser.add_argument('--advance-step', action='store_true', help='推进到下一步') - parser.add_argument('--step', type=str, help='步骤名称') - parser.add_argument('--result', type=str, help='步骤结果(JSON 字符串)') - parser.add_argument('--record-error', action='store_true', help='记录错误') - parser.add_argument('--error-msg', type=str, help='错误信息') - parser.add_argument('--resume', action='store_true', help='获取恢复执行信息') - + parser.add_argument('--extract_platform', type=str, help='要提取平台名称的文件名') args = parser.parse_args() - + base_path = Path(args.base_path) if args.base_path else None dirs = ensure_directories(base_path) - - # 查重 + + # Handle process subcommand + if args.command == 'process': + result = process_command( + url=args.url, + output_dir=args.output_dir, + skip_completed=args.skip_completed + ) + print(json.dumps(result, ensure_ascii=False, indent=2)) + return + + # Legacy argument handling if args.check and args.url: result = check_duplicate(base_path, args.url) print(json.dumps(result, ensure_ascii=False, indent=2)) - - # 归档 + elif args.archive_file: result = archive_and_git(args.archive_file, base_path) print(json.dumps(result, ensure_ascii=False, indent=2)) - - # 目录路径查询 + elif args.pending: print(json.dumps({"path": str(dirs["pending"])}, ensure_ascii=False, indent=2)) + elif args.metadata: print(json.dumps({"path": str(dirs["metadata"])}, ensure_ascii=False, indent=2)) + elif args.content: print(json.dumps({"path": str(dirs["content"])}, ensure_ascii=False, indent=2)) + elif args.content_downloads: print(json.dumps({"path": str(dirs["content_downloads"])}, ensure_ascii=False, indent=2)) + elif args.analyzed: print(json.dumps({"path": str(dirs["analyzed"])}, ensure_ascii=False, indent=2)) + elif args.archive_dir: print(json.dumps({"path": str(get_archive_path())}, ensure_ascii=False, indent=2)) + elif args.archive_subscriptions: print(json.dumps({"path": str(dirs["archive_subscriptions"])}, ensure_ascii=False, indent=2)) + elif args.extract_platform: platform = extract_platform(args.extract_platform) print(json.dumps({"platform": platform}, ensure_ascii=False, indent=2)) + elif args.base_path: print(json.dumps({"path": str(dirs["base"])}, ensure_ascii=False, indent=2)) - - # 状态管理 - elif args.init_state and args.url: - result = init_state(args.url, base_path) - print(json.dumps({"success": True, "state": result}, ensure_ascii=False, indent=2)) - - elif args.get_state and args.url: - result = get_state(args.url, base_path) - print(json.dumps(result, ensure_ascii=False, indent=2)) - - elif args.advance_step and args.url and args.step: - result_data = None - if args.result: - try: - result_data = json.loads(args.result) - except json.JSONDecodeError: - result_data = {"raw": args.result} - result = advance_step(args.url, args.step, result_data, base_path) - print(json.dumps(result, ensure_ascii=False, indent=2)) - - elif args.record_error and args.url and args.error_msg: - result = record_error(args.url, args.error_msg, args.step, base_path) - print(json.dumps(result, ensure_ascii=False, indent=2)) - - elif args.resume and args.url: - result = get_resume_info(args.url, base_path) - print(json.dumps(result, ensure_ascii=False, indent=2)) - + else: parser.print_help() if __name__ == '__main__': main() - - -if __name__ == '__main__': - main() diff --git a/skills/kb-zhihu-content/SKILL.md b/skills/kb-zhihu-content/SKILL.md index 8dcf5ab..9009c3e 100644 --- a/skills/kb-zhihu-content/SKILL.md +++ b/skills/kb-zhihu-content/SKILL.md @@ -1,154 +1,86 @@ ---- -name: kb-zhihu-content -description: 知乎内容下载 - 下载视频、提取文章内容 ---- - # KB Zhihu Content Skill -**kb-zhihu-content** - 下载知乎视频、提取文章内容。 +**kb-zhihu-content** - Download Zhihu videos and extract content. -## 什么时候使用 +## Features -- kb-workflow 步骤 3a:下载知乎视频 -- kb-workflow 步骤 3b:提取知乎专栏文章内容 +- Video download using **yt-dlp** +- Subtitle extraction (returns no subtitle, triggers Whisper) +- **Read article content from MediaCrawler data** (NEW!) +- Supports `ZHIHU_COOKIE` environment variable -## 功能 +## Environment Variables -- 视频下载(使用 yt-dlp) -- 从 MediaCrawler 数据读取文章内容 -- 支持 `ZHIHU_COOKIE` 环境变量 +| Variable | Required | Description | +|----------|----------|-------------| +| `ZHIHU_COOKIE` | No | 知乎登录 Cookie (for member-only videos) | -## 环境变量 - -| 变量名 | 必需 | 说明 | -|--------|------|------| -| `ZHIHU_COOKIE` | 否 | 知乎登录 Cookie | - -## 命令 +## Commands ```bash -# 下载视频 -python3 zhihu_content.py --id "12345678" --type video --output "/path/to/downloads/" +# Download video +python zhihu_content.py --id "12345678" --type video --output "/path/to/downloads/" -# 从 MediaCrawler 读取文章内容 -python3 zhihu_content.py --type article-from-media \ +# Extract subtitle (returns no subtitle, triggers Whisper) +python zhihu_content.py --id "12345678" --type subtitle --output "/path/to/subtitles/" + +# 从 MediaCrawler 读取文章内容 (⚡ NEW!) +python zhihu_content.py --type article-from-media --input "~/work/MediaCrawler/data/zhihu/json/detail_contents_2026-02-27.json" --output "~/work/knowledge-base/data/zhihu/" +``` + +## MediaCrawler 数据读取 + +**新功能**:从 MediaCrawler 爬取的数据中提取知乎文章内容 + +### 使用方法 + +```bash +# 从 MediaCrawler JSON 文件读取文章内容 +python zhihu_content.py --type article-from-media \ --input "~/work/MediaCrawler/data/zhihu/json/detail_contents_2026-02-27.json" \ --output "~/work/knowledge-base/data/zhihu/" -# 自动查找最新 MediaCrawler 数据 -python3 zhihu_content.py --type article-from-media \ +# 查找最新的爬取数据 +python zhihu_content.py --type article-from-media \ --output "~/work/knowledge-base/data/zhihu/" ``` -## 输出格式 Schema +### 参数说明 -### 必需字段 +| 参数 | 说明 | +|------|------| +| `--type article-from-media` | 从 MediaCrawler 数据读取 | +| `--input` | MediaCrawler 输出文件路径(可选,不指定则自动查找最新) | +| `--output` | 输出目录 | -| 字段 | 类型 | 说明 | -|------|------|------| -| `success` | boolean | 是否成功 | -| `type` | string | 操作类型(video/article) | - -### 视频下载特有字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `filepath` | string | 视频文件路径 | -| `filename` | string | 视频文件名 | - -### 文章提取特有字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `filepath` | string | 文章文件路径 | -| `filename` | string | 文章文件名 | -| `content_length` | number | 内容长度 | - -## 成功示例 - -### 视频下载 - -```json -{ - "success": true, - "type": "video", - "filename": "zhihu_12345678.mp4", - "filepath": "content/downloads/zhihu_12345678.mp4", - "message": "下载完成" -} -``` - -### 文章内容提取 +### 输出格式 ```json { "success": true, "type": "article", "filename": "zhihu_article_如何高效的爬取微信公众号.md", - "filepath": "~/work/knowledge-base/data/zhihu/zhihu_article_如何高效的爬取微信公众号.md", - "content_length": 4563, + "filepath": "/home/xxx/work/knowledge-base/data/zhihu/zhihu_article_如何高效的爬取微信公众号.md", "message": "文章内容已导出" } ``` -## 错误示例 +## 原有功能 -### 视频下载失败 +### Video Download -```json -{ - "success": false, - "type": "video", - "error": "视频不存在或无法访问", - "suggestion": "请检查视频 ID 是否正确" -} -``` +Video download uses **yt-dlp**: +1. Parses `ZHIHU_COOKIE` environment variable (optional) +2. Creates temporary Netscape-format cookie file +3. Runs `yt-dlp -f best -o ` +4. Cleans up temporary file -### MediaCrawler 数据未找到 +**Note**: 知乎视频通常没有官方字幕,将自动触发 Whisper 语音识别 -```json -{ - "success": false, - "type": "article-from-media", - "error": "未找到 MediaCrawler 数据文件", - "suggestion": "请先运行 MediaCrawler 爬取文章" -} -``` - -### 网络错误 - -```json -{ - "success": false, - "error": "网络请求失败: Connection timeout" -} -``` - -## 安装 +## Installation ```bash -cp -r kb-zhihu-content/ ~/.openclaw/skills/ +# Already included in kb-skills repo +# Ensure yt-dlp is installed pip install yt-dlp aiohttp ``` - -## 在 kb-workflow 中的使用 - -```bash -# 步骤 3a:下载知乎视频 -python3 ~/.openclaw/skills/kb-zhihu-content/zhihu_content.py \ - --id "12345678" --type video \ - --output "content/downloads/" - -# 注意:知乎视频没有官方字幕,下载后需要进入 Whisper 步骤 - -# 步骤 3b:提取专栏文章(如果有 MediaCrawler 数据) -python3 ~/.openclaw/skills/kb-zhihu-content/zhihu_content.py \ - --type article-from-media \ - --output "content/" -``` - -## 注意事项 - -- **知乎视频没有官方字幕**:下载后必须进入 Whisper 步骤 -- MediaCrawler 需要单独安装和运行 -- 部分视频可能需要登录才能下载 diff --git a/skills/kb-zhihu-metadata/SKILL.md b/skills/kb-zhihu-metadata/SKILL.md index b4a01b0..789e29c 100644 --- a/skills/kb-zhihu-metadata/SKILL.md +++ b/skills/kb-zhihu-metadata/SKILL.md @@ -1,207 +1,101 @@ ---- -name: kb-zhihu-metadata -description: 知乎元数据提取 - 获取问题/回答/专栏/视频的详细信息 ---- - # KB Zhihu Metadata Skill -**kb-zhihu-metadata** - 提取知乎问题、回答、用户、专栏的元数据。 +**kb-zhihu-metadata** - Extract Zhihu question/answer/user metadata and crawl articles. -## 什么时候使用 +## Features -- kb-workflow 步骤 2:获取知乎内容的元数据 -- 需要问题标题、回答者、文章标题等信息 - -## 功能 - -- 问题元数据提取 -- 回答元数据提取 -- 用户信息提取 -- 专栏文章爬取(使用 MediaCrawler) -- 支持 `ZHIHU_COOKIE` 环境变量 +- Question metadata extraction +- Answer metadata extraction +- User information extraction +- **Article crawling using MediaCrawler** (NEW!) +- JSON output format +- Markdown conversion support +- **Cookie 支持**:可配置 ZHIHU_COOKIE 访问需要登录的内容 ## 环境变量 -| 变量名 | 必需 | 说明 | +| 变量名 | 用途 | 必需 | |--------|------|------| -| `ZHIHU_COOKIE` | 推荐 | 知乎登录 Cookie(访问专栏等需要) | +| `ZHIHU_COOKIE` | 知乎登录 Cookie | 推荐(访问专栏等需要) | -**获取 Cookie:** +**获取 ZHIHU_COOKIE**: 1. 登录知乎网页版 -2. F12 → Application → Cookies → zhihu.com +2. 打开开发者工具 (F12) → Application → Cookies → zhihu.com 3. 复制 Cookie 字符串 ```bash -export ZHIHU_COOKIE="你的知乎Cookie" +# 添加到 ~/.kb_env +echo 'export ZHIHU_COOKIE="你的知乎Cookie"' >> ~/.kb_env +source ~/.kb_env ``` -## 命令 +## Commands ```bash -# 问题元数据 -python3 zhihu_metadata.py --id "266309957" --type question +# Question metadata +python zhihu_metadata.py --id "266309957" --type question -# 回答元数据 -python3 zhihu_metadata.py --id "2003427891925509507" --type answer +# Answer metadata +python zhihu_metadata.py --id "2003427891925509507" --type answer -# 知乎视频 -python3 zhihu_metadata.py --id "123456789" --type zvideo - -# 专栏文章爬取(使用 MediaCrawler) -python3 zhihu_article_crawler.py --url "https://zhuanlan.zhihu.com/p/1894054073625461813" --output "~/work/knowledge-base/data/zhihu/" +# 专栏文章爬取 (使用 MediaCrawler) ⚡ NEW! +python zhihu_article_crawler.py --url "https://zhuanlan.zhihu.com/p/1894054073625461813" --output "~/work/knowledge-base/data/zhihu/" ``` -## 输出格式 Schema +## MediaCrawler 爬取文章 -### 必需字段 +**新功能**:使用 MediaCrawler 爬取知乎专栏文章 -| 字段 | 类型 | 说明 | -|------|------|------| -| `success` | boolean | 是否提取成功 | -| `platform` | string | 固定为 `zhihu` | -| `content_id` | string | 内容 ID | -| `content_type` | string | 内容类型 | -| `title` | string | 标题 | +### 环境要求 -### 可选字段 +MediaCrawler 已安装在 `~/work/MediaCrawler` -| 字段 | 类型 | 说明 | -|------|------|------| -| `author` | string | 作者名称 | -| `excerpt` | string | 摘要 | -| `stats` | object | 统计数据 | -| `output_file` | string | 输出文件路径 | -| `error` | string | 错误信息 | +### 使用方法 -## 成功示例 +```bash +# 爬取单篇文章 +python zhihu_article_crawler.py --url "https://zhuanlan.zhihu.com/p/XXXXX" -### 问题元数据 +# 指定输出目录 +python zhihu_article_crawler.py --url "https://zhuanlan.zhihu.com/p/XXXXX" --output "/path/to/output/" + +# 输出示例 +{ + "success": true, + "type": "article", + "title": "如何高效的爬取微信公众号", + "filepath": "/home/xxx/work/knowledge-base/data/zhihu/zhihu_article_如何高效的爬取微信公众号.md", + "content_length": 4563, + "message": "爬取成功: 如何高效的爬取微信公众号" +} +``` + +### 工作原理 + +1. 调用 MediaCrawler 爬取文章 +2. 从 JSON 输出中提取内容 +3. 转换为 Markdown 格式(带 frontmatter) +4. 保存到指定目录 + +## Output ```json { "success": true, - "platform": "zhihu", - "content_type": "question", - "content_id": "266309957", - "title": "问题标题", - "excerpt": "问题描述...", - "stats": { + "data": { + "platform": "zhihu", + "type": "question", + "id": "266309957", + "title": "问题标题", + "author": "作者名字", "answer_count": 50, - "follower_count": 1000, - "view_count": 50000 - }, - "output_file": "metadata/zhihu_266309957.meta.json" + "followers": 1000 + } } ``` -### 回答元数据 - -```json -{ - "success": true, - "platform": "zhihu", - "content_type": "answer", - "content_id": "2003427891925509507", - "title": "问题标题(回答所属问题)", - "author": "回答者名字", - "excerpt": "回答摘要...", - "stats": { - "voteup_count": 1000, - "comment_count": 50 - }, - "output_file": "metadata/zhihu_2003427891925509507.meta.json" -} -``` - -### 专栏文章 - -```json -{ - "success": true, - "platform": "zhihu", - "content_type": "zhuanlan", - "content_id": "1894054073625461813", - "title": "文章标题", - "author": "作者名字", - "excerpt": "文章摘要...", - "output_file": "metadata/zhihu_1894054073625461813.meta.json" -} -``` - -### 知乎视频 - -```json -{ - "success": true, - "platform": "zhihu", - "content_type": "zvideo", - "content_id": "123456789", - "title": "视频标题", - "author": "作者名字", - "duration": "10:30", - "output_file": "metadata/zhihu_123456789.meta.json" -} -``` - -## 错误示例 - -### 内容不存在 - -```json -{ - "success": false, - "platform": "zhihu", - "content_id": "invalid_id", - "content_type": "question", - "error": "问题不存在或已被删除" -} -``` - -### 需要登录 - -```json -{ - "success": false, - "platform": "zhihu", - "content_id": "1894054073625461813", - "content_type": "zhuanlan", - "error": "需要登录才能访问", - "suggestion": "请配置 ZHIHU_COOKIE 环境变量" -} -``` - -### 网络错误 - -```json -{ - "success": false, - "error": "网络请求失败: Connection timeout" -} -``` - -## 安装 +## Installation ```bash -cp -r kb-zhihu-metadata/ ~/.openclaw/skills/ -pip install httpx +cp -r kb-zhihu-metadata/ ~/skills/ ``` - -## 在 kb-workflow 中的使用 - -```bash -# 步骤 2:元数据提取(知乎问题) -python3 ~/.openclaw/skills/kb-zhihu-metadata/zhihu_metadata.py \ - --id "266309957" --type question \ - --output "metadata/zhihu_266309957.meta.json" - -# 步骤 2:元数据提取(知乎视频) -python3 ~/.openclaw/skills/kb-zhihu-metadata/zhihu_metadata.py \ - --id "123456789" --type zvideo \ - --output "metadata/zhihu_123456789.meta.json" -``` - -## 注意事项 - -- 专栏文章可能需要登录才能访问 -- MediaCrawler 需要单独安装:`~/work/MediaCrawler` -- 部分内容可能有访问限制 diff --git a/skills/kb-zhihu-metadata/__pycache__/markdown_converter.cpython-312.pyc b/skills/kb-zhihu-metadata/__pycache__/markdown_converter.cpython-312.pyc deleted file mode 100644 index 46686f64d71a5770d051df07f5a1dfe4980172f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1072 zcmZWn&r1|>6#vf8-PUYz)zqbEi3}!xYzaj~B;lcm^pc0z%a_^te%Bp$cE)CAm0d(U z?4dyMB%6moJQYfpIz$-#0bPm?ZC?t4)asO|5P0f+XMaHXVBWm1id>&pZh=MmkDUk>%iAPPzM4}3jsgjY2QkGL{QPo1O1mMC&V7JFd z?w}%h29!Koq(V{F={k8vq}q=LbQO@*}HX<+l{OHW@lex};dQ|&%g zZSP{S;e!@69(gD)p4bNfVsh5cTTFGSUvO=selpw=tRh&)RZuE0?8)HyUpC1R|Iw_l zUSG>SxVS<$m}^&%2+m{c)$8VYXrdbfGYi$51ic+}w+ooZi%BHh4*n1aR_Zz0a@{Y= z@!V-1eT%j)%{`j?6z%;G?Oi1wqkZqgeeOxHjcFl1KU>dJj9CQZyh92WmycuoprBiI zO9*4)7#O>q;KU@@d651Y3Zm5N;cW+J&xK&tW%OCTwkL;_$Zkwj`X7(%BKWP29PnSw zlVis;iM2F#Yi5c;5VwtoOK`>u4N@G2uh;6k;hu#zK2eX)YF82j;VT;cBcBlZ_Ykna F=P%&e9HIaK diff --git a/skills/kb-zhihu-metadata/__pycache__/zhihu_extractor.cpython-312.pyc b/skills/kb-zhihu-metadata/__pycache__/zhihu_extractor.cpython-312.pyc deleted file mode 100644 index debca469b37bdcf7fa3be66e23c7b67eeac63dd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19950 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