自动同步: 2026-03-15 02:10
This commit is contained in:
@@ -347,8 +347,8 @@
|
|||||||
"memoryFlushCompactionCount": 0
|
"memoryFlushCompactionCount": 0
|
||||||
},
|
},
|
||||||
"agent:dev-assist:main": {
|
"agent:dev-assist:main": {
|
||||||
"sessionId": "b5c67eb9-7916-47dd-9491-4832eab53d10",
|
"sessionId": "60601381-862d-454d-9c27-2867f00a71d1",
|
||||||
"updatedAt": 1773132090440,
|
"updatedAt": 1773508835390,
|
||||||
"systemSent": true,
|
"systemSent": true,
|
||||||
"abortedLastRun": false,
|
"abortedLastRun": false,
|
||||||
"chatType": "direct",
|
"chatType": "direct",
|
||||||
@@ -369,7 +369,7 @@
|
|||||||
"to": "user:ou_302b162eb824d405718845441a32d9cf",
|
"to": "user:ou_302b162eb824d405718845441a32d9cf",
|
||||||
"accountId": "feishu-dev"
|
"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,
|
"compactionCount": 0,
|
||||||
"skillsSnapshot": {
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n <skill>\n <name>clawlist</name>\n <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.</description>\n <location>~/.openclaw/skills/clawlist/SKILL.md</location>\n </skill>\n</available_skills>",
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n <skill>\n <name>clawlist</name>\n <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.</description>\n <location>~/.openclaw/skills/clawlist/SKILL.md</location>\n </skill>\n</available_skills>",
|
||||||
@@ -410,8 +410,8 @@
|
|||||||
"model": "glm-5",
|
"model": "glm-5",
|
||||||
"systemPromptReport": {
|
"systemPromptReport": {
|
||||||
"source": "run",
|
"source": "run",
|
||||||
"generatedAt": 1773132050946,
|
"generatedAt": 1773508824996,
|
||||||
"sessionId": "b5c67eb9-7916-47dd-9491-4832eab53d10",
|
"sessionId": "60601381-862d-454d-9c27-2867f00a71d1",
|
||||||
"sessionKey": "agent:dev-assist:main",
|
"sessionKey": "agent:dev-assist:main",
|
||||||
"provider": "zhipu",
|
"provider": "zhipu",
|
||||||
"model": "glm-5",
|
"model": "glm-5",
|
||||||
@@ -423,8 +423,8 @@
|
|||||||
"sandboxed": false
|
"sandboxed": false
|
||||||
},
|
},
|
||||||
"systemPrompt": {
|
"systemPrompt": {
|
||||||
"chars": 32692,
|
"chars": 26851,
|
||||||
"projectContextChars": 19802,
|
"projectContextChars": 13961,
|
||||||
"nonProjectContextChars": 12890
|
"nonProjectContextChars": 12890
|
||||||
},
|
},
|
||||||
"injectedWorkspaceFiles": [
|
"injectedWorkspaceFiles": [
|
||||||
@@ -492,60 +492,6 @@
|
|||||||
"injectedChars": 18,
|
"injectedChars": 18,
|
||||||
"truncated": false
|
"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",
|
"path": "SELF_IMPROVEMENT_REMINDER.md",
|
||||||
"rawChars": 616,
|
"rawChars": 616,
|
||||||
@@ -777,12 +723,12 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cacheRead": 17472,
|
"cacheRead": 11392,
|
||||||
"cacheWrite": 0,
|
"cacheWrite": 0,
|
||||||
"totalTokensFresh": true,
|
"totalTokensFresh": true,
|
||||||
"contextTokens": 200000,
|
"contextTokens": 200000,
|
||||||
"inputTokens": 4722,
|
"inputTokens": 5334,
|
||||||
"outputTokens": 1147,
|
"outputTokens": 344,
|
||||||
"totalTokens": 22194
|
"totalTokens": 16726
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"agent:haonan:main": {
|
"agent:haonan:main": {
|
||||||
"sessionId": "624cbf67-7ab7-4df9-968d-4a63529b9111",
|
"sessionId": "40e80fbb-07c8-440d-a1d4-1e876b86b82d",
|
||||||
"updatedAt": 1773377664001,
|
"updatedAt": 1773508722585,
|
||||||
"systemSent": true,
|
"systemSent": true,
|
||||||
"skillsSnapshot": {
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n <skill>\n <name>clawlist</name>\n <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.</description>\n <location>~/.openclaw/skills/clawlist/SKILL.md</location>\n </skill>\n</available_skills>",
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n <skill>\n <name>clawlist</name>\n <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.</description>\n <location>~/.openclaw/skills/clawlist/SKILL.md</location>\n </skill>\n</available_skills>",
|
||||||
@@ -59,11 +59,11 @@
|
|||||||
"to": "user:ou_be83febac9ee2afaa343c642bc697c48",
|
"to": "user:ou_be83febac9ee2afaa343c642bc697c48",
|
||||||
"accountId": "feishu-pm"
|
"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": {
|
"systemPromptReport": {
|
||||||
"source": "run",
|
"source": "run",
|
||||||
"generatedAt": 1773377656536,
|
"generatedAt": 1773508545805,
|
||||||
"sessionId": "624cbf67-7ab7-4df9-968d-4a63529b9111",
|
"sessionId": "40e80fbb-07c8-440d-a1d4-1e876b86b82d",
|
||||||
"sessionKey": "agent:haonan:main",
|
"sessionKey": "agent:haonan:main",
|
||||||
"provider": "zhipu",
|
"provider": "zhipu",
|
||||||
"model": "glm-5",
|
"model": "glm-5",
|
||||||
@@ -75,8 +75,8 @@
|
|||||||
"sandboxed": false
|
"sandboxed": false
|
||||||
},
|
},
|
||||||
"systemPrompt": {
|
"systemPrompt": {
|
||||||
"chars": 28195,
|
"chars": 29493,
|
||||||
"projectContextChars": 15193,
|
"projectContextChars": 16491,
|
||||||
"nonProjectContextChars": 13002
|
"nonProjectContextChars": 13002
|
||||||
},
|
},
|
||||||
"injectedWorkspaceFiles": [
|
"injectedWorkspaceFiles": [
|
||||||
@@ -144,6 +144,18 @@
|
|||||||
"injectedChars": 1168,
|
"injectedChars": 1168,
|
||||||
"truncated": false
|
"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",
|
"path": "SELF_IMPROVEMENT_REMINDER.md",
|
||||||
"rawChars": 616,
|
"rawChars": 616,
|
||||||
@@ -379,12 +391,12 @@
|
|||||||
"totalTokensFresh": true,
|
"totalTokensFresh": true,
|
||||||
"lastHeartbeatText": "已在飞书向蒋先生发送日历同步提醒!✅",
|
"lastHeartbeatText": "已在飞书向蒋先生发送日历同步提醒!✅",
|
||||||
"lastHeartbeatSentAt": 1772924419184,
|
"lastHeartbeatSentAt": 1772924419184,
|
||||||
"cacheRead": 25472,
|
"cacheRead": 29760,
|
||||||
"cacheWrite": 0,
|
"cacheWrite": 0,
|
||||||
"contextTokens": 200000,
|
"contextTokens": 200000,
|
||||||
"inputTokens": 12782,
|
"inputTokens": 13411,
|
||||||
"outputTokens": 123,
|
"outputTokens": 1288,
|
||||||
"totalTokens": 25768
|
"totalTokens": 30249
|
||||||
},
|
},
|
||||||
"agent:haonan:wecom:dm:zhangqing": {
|
"agent:haonan:wecom:dm:zhangqing": {
|
||||||
"origin": {
|
"origin": {
|
||||||
@@ -715,8 +727,8 @@
|
|||||||
"memoryFlushCompactionCount": 0
|
"memoryFlushCompactionCount": 0
|
||||||
},
|
},
|
||||||
"agent:haonan:cron:41396aeb-6e3a-47b2-9bd3-9156a348c1dc": {
|
"agent:haonan:cron:41396aeb-6e3a-47b2-9bd3-9156a348c1dc": {
|
||||||
"sessionId": "10740f43-38c1-4a7c-acf0-7da04f20d1e9",
|
"sessionId": "7c1a6bfd-b5b6-4ac5-98f3-6a73aec18a8f",
|
||||||
"updatedAt": 1773424800009,
|
"updatedAt": 1773511200009,
|
||||||
"systemSent": true,
|
"systemSent": true,
|
||||||
"model": "glm-5",
|
"model": "glm-5",
|
||||||
"contextTokens": 200000,
|
"contextTokens": 200000,
|
||||||
@@ -757,11 +769,11 @@
|
|||||||
"version": 0
|
"version": 0
|
||||||
},
|
},
|
||||||
"modelProvider": "zhipu",
|
"modelProvider": "zhipu",
|
||||||
"inputTokens": 11105,
|
"inputTokens": 4500,
|
||||||
"outputTokens": 336,
|
"outputTokens": 194,
|
||||||
"totalTokens": 17181,
|
"totalTokens": 16577,
|
||||||
"totalTokensFresh": true,
|
"totalTokensFresh": true,
|
||||||
"cacheRead": 56128,
|
"cacheRead": 28544,
|
||||||
"cacheWrite": 0
|
"cacheWrite": 0
|
||||||
},
|
},
|
||||||
"agent:haonan:cron:f03b184f-5f1d-4093-ae1b-fc9fe0b59eef": {
|
"agent:haonan:cron:f03b184f-5f1d-4093-ae1b-fc9fe0b59eef": {
|
||||||
@@ -861,8 +873,8 @@
|
|||||||
"cacheWrite": 0
|
"cacheWrite": 0
|
||||||
},
|
},
|
||||||
"agent:haonan:cron:aa4d2de9-79be-4262-83ee-af8824793bfc": {
|
"agent:haonan:cron:aa4d2de9-79be-4262-83ee-af8824793bfc": {
|
||||||
"sessionId": "8b634542-6d0e-4fa3-b794-d784174d530b",
|
"sessionId": "b5ab88d0-f6d3-4b73-8d96-e6a58f5e85e4",
|
||||||
"updatedAt": 1773425400005,
|
"updatedAt": 1773511800007,
|
||||||
"systemSent": true,
|
"systemSent": true,
|
||||||
"label": "Cron: openclaw-git-sync",
|
"label": "Cron: openclaw-git-sync",
|
||||||
"skillsSnapshot": {
|
"skillsSnapshot": {
|
||||||
@@ -910,113 +922,6 @@
|
|||||||
"cacheRead": 32768,
|
"cacheRead": 32768,
|
||||||
"cacheWrite": 0
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n <skill>\n <name>clawlist</name>\n <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.</description>\n <location>~/.openclaw/skills/clawlist/SKILL.md</location>\n </skill>\n</available_skills>",
|
|
||||||
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n <skill>\n <name>clawlist</name>\n <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.</description>\n <location>~/.openclaw/skills/clawlist/SKILL.md</location>\n </skill>\n</available_skills>",
|
|
||||||
"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": {
|
"agent:haonan:cron:aa4d2de9-79be-4262-83ee-af8824793bfc:run:8b634542-6d0e-4fa3-b794-d784174d530b": {
|
||||||
"sessionId": "8b634542-6d0e-4fa3-b794-d784174d530b",
|
"sessionId": "8b634542-6d0e-4fa3-b794-d784174d530b",
|
||||||
"updatedAt": 1773425400005,
|
"updatedAt": 1773425400005,
|
||||||
@@ -1123,5 +1028,105 @@
|
|||||||
"totalTokensFresh": true,
|
"totalTokensFresh": true,
|
||||||
"cacheRead": 384894,
|
"cacheRead": 384894,
|
||||||
"cacheWrite": 0
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n <skill>\n <name>clawlist</name>\n <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.</description>\n <location>~/.openclaw/skills/clawlist/SKILL.md</location>\n </skill>\n</available_skills>",
|
||||||
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n <skill>\n <name>clawlist</name>\n <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.</description>\n <location>~/.openclaw/skills/clawlist/SKILL.md</location>\n </skill>\n</available_skills>",
|
||||||
|
"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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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 分支)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"agent:thinker:main": {
|
"agent:thinker:main": {
|
||||||
"sessionId": "0ec88a33-135f-42a4-bf98-de4d06bfadd5",
|
"sessionId": "41133a8b-b22b-418f-aaeb-ce8a1fd69760",
|
||||||
"updatedAt": 1773377998949,
|
"updatedAt": 1773508159395,
|
||||||
"systemSent": true,
|
"systemSent": true,
|
||||||
"abortedLastRun": false,
|
"abortedLastRun": false,
|
||||||
"chatType": "direct",
|
"chatType": "direct",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"to": "user:ou_a0f6627b64d2dc8b0236671603d1e47b",
|
"to": "user:ou_a0f6627b64d2dc8b0236671603d1e47b",
|
||||||
"accountId": "feishu-qa"
|
"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,
|
"compactionCount": 0,
|
||||||
"skillsSnapshot": {
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n</available_skills>",
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n</available_skills>",
|
||||||
@@ -51,8 +51,8 @@
|
|||||||
"model": "glm-5",
|
"model": "glm-5",
|
||||||
"systemPromptReport": {
|
"systemPromptReport": {
|
||||||
"source": "run",
|
"source": "run",
|
||||||
"generatedAt": 1773377941023,
|
"generatedAt": 1773508155922,
|
||||||
"sessionId": "0ec88a33-135f-42a4-bf98-de4d06bfadd5",
|
"sessionId": "41133a8b-b22b-418f-aaeb-ce8a1fd69760",
|
||||||
"sessionKey": "agent:thinker:main",
|
"sessionKey": "agent:thinker:main",
|
||||||
"provider": "zhipu",
|
"provider": "zhipu",
|
||||||
"model": "glm-5",
|
"model": "glm-5",
|
||||||
@@ -64,8 +64,8 @@
|
|||||||
"sandboxed": false
|
"sandboxed": false
|
||||||
},
|
},
|
||||||
"systemPrompt": {
|
"systemPrompt": {
|
||||||
"chars": 26194,
|
"chars": 24896,
|
||||||
"projectContextChars": 13718,
|
"projectContextChars": 12420,
|
||||||
"nonProjectContextChars": 12476
|
"nonProjectContextChars": 12476
|
||||||
},
|
},
|
||||||
"injectedWorkspaceFiles": [
|
"injectedWorkspaceFiles": [
|
||||||
@@ -125,18 +125,6 @@
|
|||||||
"injectedChars": 88,
|
"injectedChars": 88,
|
||||||
"truncated": false
|
"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",
|
"path": "SELF_IMPROVEMENT_REMINDER.md",
|
||||||
"rawChars": 616,
|
"rawChars": 616,
|
||||||
@@ -364,12 +352,12 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cacheRead": 28864,
|
"cacheRead": 11072,
|
||||||
"cacheWrite": 0,
|
"cacheWrite": 0,
|
||||||
"totalTokensFresh": true,
|
"totalTokensFresh": true,
|
||||||
"contextTokens": 200000,
|
"contextTokens": 200000,
|
||||||
"inputTokens": 13728,
|
"inputTokens": 5154,
|
||||||
"outputTokens": 1428,
|
"outputTokens": 62,
|
||||||
"totalTokens": 29902
|
"totalTokens": 16226
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"agent:ui-designer:main": {
|
"agent:ui-designer:main": {
|
||||||
"sessionId": "c875d391-8f7e-4fd4-92c7-12ead46d10f0",
|
"sessionId": "ff92b555-b242-4e52-a7da-9c8f82ca1c8a",
|
||||||
"updatedAt": 1773108605750,
|
"updatedAt": 1773508884420,
|
||||||
"systemSent": true,
|
"systemSent": true,
|
||||||
"abortedLastRun": false,
|
"abortedLastRun": false,
|
||||||
"chatType": "direct",
|
"chatType": "direct",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"to": "user:ou_9847ce84b960736c14554730b41e4957",
|
"to": "user:ou_9847ce84b960736c14554730b41e4957",
|
||||||
"accountId": "feishu-art"
|
"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,
|
"compactionCount": 0,
|
||||||
"skillsSnapshot": {
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n</available_skills>",
|
"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<available_skills>\n <skill>\n <name>capability-evolver</name>\n <description>A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.</description>\n <location>~/.openclaw/skills/capability-evolver/SKILL.md</location>\n </skill>\n</available_skills>",
|
||||||
@@ -51,8 +51,8 @@
|
|||||||
"model": "glm-5",
|
"model": "glm-5",
|
||||||
"systemPromptReport": {
|
"systemPromptReport": {
|
||||||
"source": "run",
|
"source": "run",
|
||||||
"generatedAt": 1773108589701,
|
"generatedAt": 1773508877788,
|
||||||
"sessionId": "c875d391-8f7e-4fd4-92c7-12ead46d10f0",
|
"sessionId": "ff92b555-b242-4e52-a7da-9c8f82ca1c8a",
|
||||||
"sessionKey": "agent:ui-designer:main",
|
"sessionKey": "agent:ui-designer:main",
|
||||||
"provider": "zhipu",
|
"provider": "zhipu",
|
||||||
"model": "glm-5",
|
"model": "glm-5",
|
||||||
@@ -64,8 +64,8 @@
|
|||||||
"sandboxed": false
|
"sandboxed": false
|
||||||
},
|
},
|
||||||
"systemPrompt": {
|
"systemPrompt": {
|
||||||
"chars": 18658,
|
"chars": 19307,
|
||||||
"projectContextChars": 6173,
|
"projectContextChars": 6822,
|
||||||
"nonProjectContextChars": 12485
|
"nonProjectContextChars": 12485
|
||||||
},
|
},
|
||||||
"injectedWorkspaceFiles": [
|
"injectedWorkspaceFiles": [
|
||||||
@@ -133,6 +133,12 @@
|
|||||||
"injectedChars": 594,
|
"injectedChars": 594,
|
||||||
"truncated": false
|
"truncated": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "SELF_IMPROVEMENT_REMINDER.md",
|
||||||
|
"rawChars": 616,
|
||||||
|
"injectedChars": 616,
|
||||||
|
"truncated": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "SELF_IMPROVEMENT_REMINDER.md",
|
"path": "SELF_IMPROVEMENT_REMINDER.md",
|
||||||
"rawChars": 616,
|
"rawChars": 616,
|
||||||
@@ -360,13 +366,13 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cacheRead": 14912,
|
"cacheRead": 14400,
|
||||||
"cacheWrite": 0,
|
"cacheWrite": 0,
|
||||||
"totalTokensFresh": true,
|
"totalTokensFresh": true,
|
||||||
"contextTokens": 200000,
|
"contextTokens": 200000,
|
||||||
"inputTokens": 3611,
|
"inputTokens": 1169,
|
||||||
"outputTokens": 314,
|
"outputTokens": 135,
|
||||||
"totalTokens": 15537
|
"totalTokens": 15569
|
||||||
},
|
},
|
||||||
"agent:ui-designer:cron:78b64c2f-7f91-47ff-9250-d13f546eb21f": {
|
"agent:ui-designer:cron:78b64c2f-7f91-47ff-9250-d13f546eb21f": {
|
||||||
"sessionId": "03e44b46-c707-4a9f-bf3d-1818aafdcde2",
|
"sessionId": "03e44b46-c707-4a9f-bf3d-1818aafdcde2",
|
||||||
|
|||||||
+34
-36
@@ -7,7 +7,7 @@
|
|||||||
"name": "backup-openclaw-json",
|
"name": "backup-openclaw-json",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1772261581796,
|
"createdAtMs": 1772261581796,
|
||||||
"updatedAtMs": 1773424832005,
|
"updatedAtMs": 1773511209521,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
"expr": "0 2 * * *",
|
"expr": "0 2 * * *",
|
||||||
@@ -23,10 +23,10 @@
|
|||||||
"mode": "announce"
|
"mode": "announce"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773511200000,
|
"nextRunAtMs": 1773597600000,
|
||||||
"lastRunAtMs": 1773424800006,
|
"lastRunAtMs": 1773511200006,
|
||||||
"lastStatus": "ok",
|
"lastStatus": "ok",
|
||||||
"lastDurationMs": 31999,
|
"lastDurationMs": 9515,
|
||||||
"consecutiveErrors": 0,
|
"consecutiveErrors": 0,
|
||||||
"lastRunStatus": "ok",
|
"lastRunStatus": "ok",
|
||||||
"lastDelivered": true,
|
"lastDelivered": true,
|
||||||
@@ -59,7 +59,8 @@
|
|||||||
"consecutiveErrors": 0,
|
"consecutiveErrors": 0,
|
||||||
"lastRunStatus": "ok",
|
"lastRunStatus": "ok",
|
||||||
"lastDeliveryStatus": "delivered",
|
"lastDeliveryStatus": "delivered",
|
||||||
"lastDelivered": true
|
"lastDelivered": true,
|
||||||
|
"runningAtMs": 1773511800004
|
||||||
},
|
},
|
||||||
"delivery": {
|
"delivery": {
|
||||||
"mode": "announce"
|
"mode": "announce"
|
||||||
@@ -71,7 +72,7 @@
|
|||||||
"name": "capability-evolver-daily",
|
"name": "capability-evolver-daily",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1772550743528,
|
"createdAtMs": 1772550743528,
|
||||||
"updatedAtMs": 1773339898227,
|
"updatedAtMs": 1773426600014,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
"expr": "20 2 * * *",
|
"expr": "20 2 * * *",
|
||||||
@@ -92,16 +93,14 @@
|
|||||||
"to": "feishu-pm"
|
"to": "feishu-pm"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773426000000,
|
"nextRunAtMs": 1773512400000,
|
||||||
"lastRunAtMs": 1773339600009,
|
"lastRunAtMs": 1773426000004,
|
||||||
"lastStatus": "ok",
|
"lastStatus": "error",
|
||||||
"lastDurationMs": 298218,
|
"lastDurationMs": 600010,
|
||||||
"consecutiveErrors": 0,
|
"consecutiveErrors": 1,
|
||||||
"lastRunStatus": "ok",
|
"lastRunStatus": "error",
|
||||||
"lastDeliveryStatus": "not-delivered",
|
"lastDeliveryStatus": "unknown",
|
||||||
"lastDelivered": false,
|
"lastError": "cron: job execution timed out"
|
||||||
"lastDeliveryError": "cron announce delivery failed",
|
|
||||||
"runningAtMs": 1773426000003
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -111,7 +110,7 @@
|
|||||||
"description": "每天凌晨2:30整理昨天的已完成任务到每日回顾",
|
"description": "每天凌晨2:30整理昨天的已完成任务到每日回顾",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1741484880000,
|
"createdAtMs": 1741484880000,
|
||||||
"updatedAtMs": 1773340211879,
|
"updatedAtMs": 1773426622389,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
"expr": "30 2 * * *",
|
"expr": "30 2 * * *",
|
||||||
@@ -129,11 +128,11 @@
|
|||||||
"channel": "last"
|
"channel": "last"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773426600000,
|
"nextRunAtMs": 1773513000000,
|
||||||
"lastRunAtMs": 1773340200003,
|
"lastRunAtMs": 1773426602034,
|
||||||
"lastRunStatus": "ok",
|
"lastRunStatus": "ok",
|
||||||
"lastStatus": "ok",
|
"lastStatus": "ok",
|
||||||
"lastDurationMs": 11876,
|
"lastDurationMs": 20355,
|
||||||
"lastDelivered": true,
|
"lastDelivered": true,
|
||||||
"lastDeliveryStatus": "delivered",
|
"lastDeliveryStatus": "delivered",
|
||||||
"consecutiveErrors": 0
|
"consecutiveErrors": 0
|
||||||
@@ -145,7 +144,7 @@
|
|||||||
"name": "zq_workspace_sync",
|
"name": "zq_workspace_sync",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1772551807455,
|
"createdAtMs": 1772551807455,
|
||||||
"updatedAtMs": 1773340800005,
|
"updatedAtMs": 1773427200007,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"expr": "40 2 * * *",
|
"expr": "40 2 * * *",
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
@@ -158,8 +157,8 @@
|
|||||||
"text": "执行 zq 工作区同步:bash ~/.openclaw/cron/scripts/zq_workspace_sync.sh"
|
"text": "执行 zq 工作区同步:bash ~/.openclaw/cron/scripts/zq_workspace_sync.sh"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773427200000,
|
"nextRunAtMs": 1773513600000,
|
||||||
"lastRunAtMs": 1773340800004,
|
"lastRunAtMs": 1773427200006,
|
||||||
"lastStatus": "skipped",
|
"lastStatus": "skipped",
|
||||||
"lastDurationMs": 1,
|
"lastDurationMs": 1,
|
||||||
"consecutiveErrors": 0,
|
"consecutiveErrors": 0,
|
||||||
@@ -175,7 +174,7 @@
|
|||||||
"description": "每天早上8点整理与各个 AI 代理的对话记录",
|
"description": "每天早上8点整理与各个 AI 代理的对话记录",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1772776369645,
|
"createdAtMs": 1772776369645,
|
||||||
"updatedAtMs": 1773360026590,
|
"updatedAtMs": 1773446431755,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
"expr": "0 8 * * *",
|
"expr": "0 8 * * *",
|
||||||
@@ -193,11 +192,11 @@
|
|||||||
"channel": "last"
|
"channel": "last"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773446400000,
|
"nextRunAtMs": 1773532800000,
|
||||||
"lastRunAtMs": 1773360000004,
|
"lastRunAtMs": 1773446400004,
|
||||||
"lastRunStatus": "ok",
|
"lastRunStatus": "ok",
|
||||||
"lastStatus": "ok",
|
"lastStatus": "ok",
|
||||||
"lastDurationMs": 26586,
|
"lastDurationMs": 31751,
|
||||||
"lastDelivered": true,
|
"lastDelivered": true,
|
||||||
"lastDeliveryStatus": "delivered",
|
"lastDeliveryStatus": "delivered",
|
||||||
"consecutiveErrors": 0
|
"consecutiveErrors": 0
|
||||||
@@ -210,7 +209,7 @@
|
|||||||
"description": "每天7点同步提醒到CalDAV日历",
|
"description": "每天7点同步提醒到CalDAV日历",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1772791528528,
|
"createdAtMs": 1772791528528,
|
||||||
"updatedAtMs": 1773356435243,
|
"updatedAtMs": 1773442830136,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
"expr": "0 7 * * *",
|
"expr": "0 7 * * *",
|
||||||
@@ -228,15 +227,14 @@
|
|||||||
"channel": "last"
|
"channel": "last"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773442800000,
|
"nextRunAtMs": 1773529200000,
|
||||||
"lastRunAtMs": 1773356400004,
|
"lastRunAtMs": 1773442800005,
|
||||||
"lastRunStatus": "error",
|
"lastRunStatus": "ok",
|
||||||
"lastStatus": "error",
|
"lastStatus": "ok",
|
||||||
"lastDurationMs": 35239,
|
"lastDurationMs": 30131,
|
||||||
"lastDeliveryStatus": "delivered",
|
"lastDeliveryStatus": "delivered",
|
||||||
"consecutiveErrors": 1,
|
"consecutiveErrors": 0,
|
||||||
"lastDelivered": true,
|
"lastDelivered": true
|
||||||
"lastError": "⚠️ 📝 Edit: in ~/.openclaw/agents/knowledge-base/workspace/memory/heartbeat-state.json (92 chars) failed"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
+32
-35
@@ -7,7 +7,7 @@
|
|||||||
"name": "backup-openclaw-json",
|
"name": "backup-openclaw-json",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1772261581796,
|
"createdAtMs": 1772261581796,
|
||||||
"updatedAtMs": 1773424832005,
|
"updatedAtMs": 1773511209521,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
"expr": "0 2 * * *",
|
"expr": "0 2 * * *",
|
||||||
@@ -23,10 +23,10 @@
|
|||||||
"mode": "announce"
|
"mode": "announce"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773511200000,
|
"nextRunAtMs": 1773597600000,
|
||||||
"lastRunAtMs": 1773424800006,
|
"lastRunAtMs": 1773511200006,
|
||||||
"lastStatus": "ok",
|
"lastStatus": "ok",
|
||||||
"lastDurationMs": 31999,
|
"lastDurationMs": 9515,
|
||||||
"consecutiveErrors": 0,
|
"consecutiveErrors": 0,
|
||||||
"lastRunStatus": "ok",
|
"lastRunStatus": "ok",
|
||||||
"lastDelivered": true,
|
"lastDelivered": true,
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
"name": "capability-evolver-daily",
|
"name": "capability-evolver-daily",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1772550743528,
|
"createdAtMs": 1772550743528,
|
||||||
"updatedAtMs": 1773339898227,
|
"updatedAtMs": 1773426600014,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
"expr": "20 2 * * *",
|
"expr": "20 2 * * *",
|
||||||
@@ -92,16 +92,14 @@
|
|||||||
"to": "feishu-pm"
|
"to": "feishu-pm"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773426000000,
|
"nextRunAtMs": 1773512400000,
|
||||||
"lastRunAtMs": 1773339600009,
|
"lastRunAtMs": 1773426000004,
|
||||||
"lastStatus": "ok",
|
"lastStatus": "error",
|
||||||
"lastDurationMs": 298218,
|
"lastDurationMs": 600010,
|
||||||
"consecutiveErrors": 0,
|
"consecutiveErrors": 1,
|
||||||
"lastRunStatus": "ok",
|
"lastRunStatus": "error",
|
||||||
"lastDeliveryStatus": "not-delivered",
|
"lastDeliveryStatus": "unknown",
|
||||||
"lastDelivered": false,
|
"lastError": "cron: job execution timed out"
|
||||||
"lastDeliveryError": "cron announce delivery failed",
|
|
||||||
"lastError": "cron announce delivery failed"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -111,7 +109,7 @@
|
|||||||
"description": "每天凌晨2:30整理昨天的已完成任务到每日回顾",
|
"description": "每天凌晨2:30整理昨天的已完成任务到每日回顾",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1741484880000,
|
"createdAtMs": 1741484880000,
|
||||||
"updatedAtMs": 1773340211879,
|
"updatedAtMs": 1773426622389,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
"expr": "30 2 * * *",
|
"expr": "30 2 * * *",
|
||||||
@@ -129,11 +127,11 @@
|
|||||||
"channel": "last"
|
"channel": "last"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773426600000,
|
"nextRunAtMs": 1773513000000,
|
||||||
"lastRunAtMs": 1773340200003,
|
"lastRunAtMs": 1773426602034,
|
||||||
"lastRunStatus": "ok",
|
"lastRunStatus": "ok",
|
||||||
"lastStatus": "ok",
|
"lastStatus": "ok",
|
||||||
"lastDurationMs": 11876,
|
"lastDurationMs": 20355,
|
||||||
"lastDelivered": true,
|
"lastDelivered": true,
|
||||||
"lastDeliveryStatus": "delivered",
|
"lastDeliveryStatus": "delivered",
|
||||||
"consecutiveErrors": 0
|
"consecutiveErrors": 0
|
||||||
@@ -145,7 +143,7 @@
|
|||||||
"name": "zq_workspace_sync",
|
"name": "zq_workspace_sync",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1772551807455,
|
"createdAtMs": 1772551807455,
|
||||||
"updatedAtMs": 1773340800005,
|
"updatedAtMs": 1773427200007,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"expr": "40 2 * * *",
|
"expr": "40 2 * * *",
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
@@ -158,8 +156,8 @@
|
|||||||
"text": "执行 zq 工作区同步:bash ~/.openclaw/cron/scripts/zq_workspace_sync.sh"
|
"text": "执行 zq 工作区同步:bash ~/.openclaw/cron/scripts/zq_workspace_sync.sh"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773427200000,
|
"nextRunAtMs": 1773513600000,
|
||||||
"lastRunAtMs": 1773340800004,
|
"lastRunAtMs": 1773427200006,
|
||||||
"lastStatus": "skipped",
|
"lastStatus": "skipped",
|
||||||
"lastDurationMs": 1,
|
"lastDurationMs": 1,
|
||||||
"consecutiveErrors": 0,
|
"consecutiveErrors": 0,
|
||||||
@@ -175,7 +173,7 @@
|
|||||||
"description": "每天早上8点整理与各个 AI 代理的对话记录",
|
"description": "每天早上8点整理与各个 AI 代理的对话记录",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1772776369645,
|
"createdAtMs": 1772776369645,
|
||||||
"updatedAtMs": 1773360026590,
|
"updatedAtMs": 1773446431755,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
"expr": "0 8 * * *",
|
"expr": "0 8 * * *",
|
||||||
@@ -193,11 +191,11 @@
|
|||||||
"channel": "last"
|
"channel": "last"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773446400000,
|
"nextRunAtMs": 1773532800000,
|
||||||
"lastRunAtMs": 1773360000004,
|
"lastRunAtMs": 1773446400004,
|
||||||
"lastRunStatus": "ok",
|
"lastRunStatus": "ok",
|
||||||
"lastStatus": "ok",
|
"lastStatus": "ok",
|
||||||
"lastDurationMs": 26586,
|
"lastDurationMs": 31751,
|
||||||
"lastDelivered": true,
|
"lastDelivered": true,
|
||||||
"lastDeliveryStatus": "delivered",
|
"lastDeliveryStatus": "delivered",
|
||||||
"consecutiveErrors": 0
|
"consecutiveErrors": 0
|
||||||
@@ -210,7 +208,7 @@
|
|||||||
"description": "每天7点同步提醒到CalDAV日历",
|
"description": "每天7点同步提醒到CalDAV日历",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"createdAtMs": 1772791528528,
|
"createdAtMs": 1772791528528,
|
||||||
"updatedAtMs": 1773356435243,
|
"updatedAtMs": 1773442830136,
|
||||||
"schedule": {
|
"schedule": {
|
||||||
"kind": "cron",
|
"kind": "cron",
|
||||||
"expr": "0 7 * * *",
|
"expr": "0 7 * * *",
|
||||||
@@ -228,15 +226,14 @@
|
|||||||
"channel": "last"
|
"channel": "last"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1773442800000,
|
"nextRunAtMs": 1773529200000,
|
||||||
"lastRunAtMs": 1773356400004,
|
"lastRunAtMs": 1773442800005,
|
||||||
"lastRunStatus": "error",
|
"lastRunStatus": "ok",
|
||||||
"lastStatus": "error",
|
"lastStatus": "ok",
|
||||||
"lastDurationMs": 35239,
|
"lastDurationMs": 30131,
|
||||||
"lastDeliveryStatus": "delivered",
|
"lastDeliveryStatus": "delivered",
|
||||||
"consecutiveErrors": 1,
|
"consecutiveErrors": 0,
|
||||||
"lastDelivered": true,
|
"lastDelivered": true
|
||||||
"lastError": "⚠️ 📝 Edit: in ~/.openclaw/agents/knowledge-base/workspace/memory/heartbeat-state.json (92 chars) failed"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
"agentId": "haonan",
|
"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"
|
"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,
|
"retryCount": 4,
|
||||||
"lastAttemptAt": 1773377636671,
|
"lastAttemptAt": 1773508779544,
|
||||||
"lastError": "Request failed with status code 400"
|
"lastError": "Request failed with status code 400"
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"agentId": "haonan",
|
"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`"
|
"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,
|
"retryCount": 4,
|
||||||
"lastAttemptAt": 1773377636492,
|
"lastAttemptAt": 1773508779398,
|
||||||
"lastError": "Request failed with status code 400"
|
"lastError": "Request failed with status code 400"
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"agentId": "haonan",
|
"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"
|
"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,
|
"retryCount": 4,
|
||||||
"lastAttemptAt": 1773377636819,
|
"lastAttemptAt": 1773508779677,
|
||||||
"lastError": "Request failed with status code 400"
|
"lastError": "Request failed with status code 400"
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"om_x100b55d69df3a888c3e9ed8887d1a4d": 1773022516624,
|
"om_x100b546dc09400acb4a5d0af66ca3c9": 1773508838286,
|
||||||
"om_x100b55d6987ec8bcc1431506934622a": 1773022571945,
|
"om_x100b546dde1c34a4b49a888912755ac": 1773508877713
|
||||||
"om_x100b55c3980b0894c3d7e12aace4404": 1773108589126
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
{
|
{
|
||||||
"om_x100b55de502094a8c44a6f835293240": 1773052399376,
|
"om_x100b546dc3b650a4b2c0139d2df31a7": 1773508824362
|
||||||
"om_x100b55cff24dcca8c3e59d6831d6885": 1773124552700,
|
|
||||||
"om_x100b55c8c767d084c45fc7eec3f7db8": 1773127835623,
|
|
||||||
"om_x100b55c9372e9914c3a5744eccfbc0d": 1773131678929,
|
|
||||||
"om_x100b55c9dfec84a0b34c47ff1aca626": 1773132050877
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
{
|
{
|
||||||
"om_x100b54012fb4b8acb26a1377e572a28": 1773360664219,
|
"om_x100b546d172f3c68c2cea708421b99a": 1773507998614,
|
||||||
"om_x100b5403d6e544bcc451e2afa005879": 1773369731225,
|
"om_x100b546d2b32cca0c329a33c339cfb5": 1773508192506,
|
||||||
"om_x100b5403d32b04b4c2a796466ebaf4f": 1773369823078,
|
"om_x100b546d32de24a8b316c197e60d6e4": 1773508545727,
|
||||||
"om_x100b5403e04f6ca8c29946e1fa6505d": 1773370088740,
|
"om_x100b546dc9d61ca0b33d802bc7615e0": 1773508722267
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,3 @@
|
|||||||
{
|
{
|
||||||
"om_x100b540c33ced0a8c3b77203de384e3": 1773373392794,
|
"om_x100b546d2d6164a4c3fcf5a6d528b40": 1773508155371
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
{
|
{
|
||||||
"om_x100b5403a5fd7090c4db2b553189c54": 1773371059715,
|
"om_x100b546ddd8b14a0b3ddda14ce768c5": 1773508916933,
|
||||||
"om_x100b540c2807c4acc32d196f4b16191": 1773373037365
|
"om_x100b546dd78c8ca0b31b0314f910115": 1773509012676,
|
||||||
|
"om_x100b546def8ac8a4b38d921a2bfc8b8": 1773509140955,
|
||||||
|
"om_x100b546dedb654a4b3ce916a129facf": 1773509176311,
|
||||||
|
"om_x100b546de975dca0b27e2f24aad0d8c": 1773509244102,
|
||||||
|
"om_x100b546de53a94a0b38693fbd7e385c": 1773509311993,
|
||||||
|
"om_x100b546dffaa3cb0b35aef2747ed228": 1773509398933,
|
||||||
|
"om_x100b546df49c10a0b106d597fd348a3": 1773509541678
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"operator.approvals",
|
"operator.approvals",
|
||||||
"operator.pairing"
|
"operator.pairing"
|
||||||
],
|
],
|
||||||
"updatedAtMs": 1773425421022
|
"updatedAtMs": 1773511209007
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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: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: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-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"}
|
||||||
|
|||||||
@@ -1,214 +1,91 @@
|
|||||||
---
|
|
||||||
name: kb-bilibili-content
|
|
||||||
description: B站内容下载 - 下载视频、字幕、专栏文章
|
|
||||||
---
|
|
||||||
|
|
||||||
# KB Bilibili Content Skill
|
# KB Bilibili Content Skill
|
||||||
|
|
||||||
**kb-bilibili-content** - 下载 B站视频、字幕、专栏文章。
|
**kb-bilibili-content** - Download Bilibili videos and extract content.
|
||||||
|
|
||||||
## 什么时候使用
|
## Features
|
||||||
|
|
||||||
- kb-workflow 步骤 3a:下载视频或字幕
|
- Video download using **yt-dlp** (recommended)
|
||||||
- kb-workflow 步骤 3b:提取专栏文章内容
|
- Subtitle extraction
|
||||||
|
- Article content extraction
|
||||||
|
- Multiple quality options (360P/480P/720P/1080P)
|
||||||
|
- Supports `BILIBILI_COOKIE` environment variable
|
||||||
|
|
||||||
## 功能
|
## Environment Variables
|
||||||
|
|
||||||
- 视频下载(使用 yt-dlp)
|
| Variable | Required | Description |
|
||||||
- 字幕提取(官方字幕)
|
|----------|----------|-------------|
|
||||||
- 专栏文章内容提取
|
| `BILIBILI_COOKIE` | No | B站登录 Cookie (for member-only videos) |
|
||||||
- 多种画质选项(360P/480P/720P/1080P)
|
|
||||||
- 支持 `BILIBILI_COOKIE` 环境变量(会员视频)
|
|
||||||
|
|
||||||
## 环境变量
|
## Commands
|
||||||
|
|
||||||
| 变量名 | 必需 | 说明 |
|
|
||||||
|--------|------|------|
|
|
||||||
| `BILIBILI_COOKIE` | 否 | B站登录 Cookie(会员视频需要) |
|
|
||||||
|
|
||||||
**获取 Cookie:**
|
|
||||||
1. 登录 bilibili.com
|
|
||||||
2. F12 → Network → 刷新页面
|
|
||||||
3. 从请求头复制 Cookie
|
|
||||||
|
|
||||||
```bash
|
```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"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 命令
|
## Output
|
||||||
|
|
||||||
```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": "无官方字幕,需要下载视频进行语音识别"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 视频下载
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"type": "video",
|
"type": "video",
|
||||||
"filename": "bilibili_BV1xx411c7mD.mp4",
|
"filename": "video_title.mp4",
|
||||||
"filepath": "content/downloads/bilibili_BV1xx411c7mD.mp4",
|
"filepath": "/path/to/downloads/video_title.mp4",
|
||||||
"quality": "720P",
|
"message": "下载完成: video_title.mp4"
|
||||||
"message": "下载完成"
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 专栏文章提取
|
## Cookie Setup
|
||||||
|
|
||||||
```json
|
### Get Cookie from Browser
|
||||||
{
|
1. Login to bilibili.com
|
||||||
"success": true,
|
2. Press F12 → Network → Refresh page
|
||||||
"type": "article",
|
3. Copy Cookie from request headers
|
||||||
"filename": "bilibili_cv43780186.txt",
|
|
||||||
"filepath": "content/bilibili_cv43780186.txt",
|
### Set Environment Variable
|
||||||
"content_length": 5234,
|
```bash
|
||||||
"message": "文章内容提取成功"
|
# 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"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 错误示例
|
## Installation
|
||||||
|
|
||||||
### 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)
|
|
||||||
|
|
||||||
## 安装
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp -r kb-bilibili-content/ ~/.openclaw/skills/
|
cp -r kb-bilibili-content/ ~/skills/
|
||||||
pip install aiohttp yt-dlp
|
pip install aiohttp playwright
|
||||||
|
playwright install chromium
|
||||||
```
|
```
|
||||||
|
|
||||||
## 在 kb-workflow 中的使用
|
## How It Works
|
||||||
|
|
||||||
```bash
|
Video download uses **yt-dlp** with Netscape-format cookie file:
|
||||||
# 步骤 3a:首先尝试字幕
|
1. Parses `BILIBILI_COOKIE` environment variable
|
||||||
python3 ~/.openclaw/skills/kb-bilibili-content/bilibili_content.py \
|
2. Creates temporary Netscape-format cookie file
|
||||||
--id "BV1xx411c7mD" --type subtitle-download \
|
3. Runs `yt-dlp --cookies <file> -f <format> -o <output>`
|
||||||
--output "content/downloads/"
|
4. Cleans up temporary file
|
||||||
|
|
||||||
# 判断结果:
|
## Quality Options
|
||||||
# - has_subtitle=true → 跳过 Whisper,直接进入深度分析
|
|
||||||
# - has_subtitle=false → 下载视频,进入 Whisper 步骤
|
|
||||||
|
|
||||||
# 如果无字幕,下载视频
|
| Quality | ID | Resolution | Notes |
|
||||||
python3 ~/.openclaw/skills/kb-bilibili-content/bilibili_content.py \
|
|---------|-----|------------|-------|
|
||||||
--id "BV1xx411c7mD" --type video \
|
| 16 | 360P | 640x360 | Fastest |
|
||||||
--output "content/downloads/"
|
| 32 | 480P | 852x480 | Default for low bandwidth |
|
||||||
```
|
| 64 | 720P | 1280x720 | **Recommended** |
|
||||||
|
| 80 | 1080P | 1920x1080 | Best quality |
|
||||||
|
|
||||||
## 注意事项
|
Default quality: **64 (720P)**
|
||||||
|
|
||||||
- **无官方字幕是正常的**:很多视频没有自动生成的字幕,这不是错误
|
|
||||||
- **403 错误**:通常需要配置 Cookie
|
|
||||||
- **会员视频**:必须配置 BILIBILI_COOKIE
|
|
||||||
- **下载时间**:视频可能较大,需要耐心等待
|
|
||||||
|
|||||||
@@ -1,187 +1,46 @@
|
|||||||
---
|
|
||||||
name: kb-bilibili-metadata
|
|
||||||
description: B站元数据提取 - 获取视频/专栏/UP主的详细信息
|
|
||||||
---
|
|
||||||
|
|
||||||
# KB Bilibili Metadata Skill
|
# 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
|
||||||
|
|
||||||
## 功能
|
## Commands
|
||||||
|
|
||||||
- 视频元数据提取
|
|
||||||
- 专栏(article)元数据提取
|
|
||||||
- UP主信息提取
|
|
||||||
- JSON 输出格式
|
|
||||||
- 支持 `--output` 参数指定输出文件
|
|
||||||
|
|
||||||
## 命令
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 视频元数据
|
# Video metadata
|
||||||
python3 bilibili_metadata.py --id "BV1xx411c7mD" --type video
|
python bilibili_metadata.py --id "BV1xx411c7mD" --type video
|
||||||
|
|
||||||
# 专栏元数据
|
# Article metadata
|
||||||
python3 bilibili_metadata.py --id "cv43780186" --type article
|
python bilibili_metadata.py --id "cv43780186" --type article
|
||||||
|
|
||||||
# UP主信息
|
# UP主 info
|
||||||
python3 bilibili_metadata.py --id "7770724" --type up
|
python bilibili_metadata.py --id "7770724" --type up
|
||||||
|
|
||||||
# 指定输出文件
|
|
||||||
python3 bilibili_metadata.py --id "BV1xx411c7mD" --type video --output "metadata/bilibili_BV1xx411c7mD.meta.json"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 输出格式 Schema
|
## Output
|
||||||
|
|
||||||
### 必需字段
|
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
|
||||||
|------|------|------|
|
|
||||||
| `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 | 错误信息(失败时) |
|
|
||||||
|
|
||||||
## 成功示例
|
|
||||||
|
|
||||||
### 视频元数据
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"platform": "bilibili",
|
"data": {
|
||||||
"content_type": "video",
|
"platform": "bilibili",
|
||||||
"content_id": "BV1xx411c7mD",
|
"type": "video",
|
||||||
"title": "视频标题",
|
"id": "BV1xx411c7mD",
|
||||||
"author": "UP主名字",
|
"title": "视频标题",
|
||||||
"duration": "10:30",
|
"author": "UP主名字",
|
||||||
"description": "视频简介内容...",
|
"stats": {"view": 100000, "like": 5000}
|
||||||
"stats": {
|
}
|
||||||
"view": 100000,
|
|
||||||
"like": 5000,
|
|
||||||
"coin": 2000,
|
|
||||||
"favorite": 1000,
|
|
||||||
"share": 500,
|
|
||||||
"danmaku": 3000
|
|
||||||
},
|
|
||||||
"output_file": "metadata/bilibili_BV1xx411c7mD.meta.json"
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 专栏元数据
|
## Installation
|
||||||
|
|
||||||
```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"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 安装
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp -r kb-bilibili-metadata/ ~/.openclaw/skills/
|
cp -r kb-bilibili-metadata/ ~/skills/
|
||||||
pip install httpx playwright
|
|
||||||
playwright install chromium
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 在 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 方式,首次运行需要下载浏览器
|
|
||||||
|
|||||||
@@ -1,207 +1,102 @@
|
|||||||
---
|
|
||||||
name: kb-deep-analyzer
|
|
||||||
description: AI深度分析 - 使用 AI 对内容进行深度分析和摘要
|
|
||||||
---
|
|
||||||
|
|
||||||
# KB Deep Analyzer Skill
|
# KB Deep Analyzer Skill
|
||||||
|
|
||||||
**kb-deep-analyzer** - AI 深度内容分析工具。
|
**kb-deep-analyzer** - AI 深度内容分析工具。
|
||||||
|
|
||||||
## 什么时候使用
|
## Features
|
||||||
|
|
||||||
- kb-workflow 步骤 5:对视频字幕或文章内容进行深度分析
|
|
||||||
- 需要生成摘要、主题、见解等
|
|
||||||
|
|
||||||
## 功能
|
|
||||||
|
|
||||||
- 多类型分析:视频(video)、文章(article)
|
- 多类型分析:视频(video)、文章(article)
|
||||||
- 模板化输出
|
- 模板化输出
|
||||||
- 质量评分
|
- 质量评分
|
||||||
- 自动标签
|
- 自动标签
|
||||||
- 多格式元数据支持
|
- **多格式元数据支持**: 支持扁平结构 `{"title":"xxx"}` 和嵌套结构 `{"data":{"metadata":{...}}}`
|
||||||
|
|
||||||
## 环境变量(必需)
|
## 内容类型
|
||||||
|
|
||||||
| 变量名 | 说明 | 示例 |
|
| 类型 | 参数 | 输出格式 |
|
||||||
|--------|------|------|
|
|------|------|----------|
|
||||||
| `AI_API_KEY` | AI API 密钥 | `your-api-key` |
|
| 视频 | `--type video` | 摘要 + 主题 + 见解 + 时间轴 |
|
||||||
| `AI_PROVIDER` | AI 提供商 | `zhipu` / `openai` / `minimax` |
|
| 文章 | `--type article` | 300字摘要 + 主题 + 原文 |
|
||||||
| `AI_MODEL` | 模型名称 | `glm-5` / `gpt-4` |
|
|
||||||
| `AI_BASE_URL` | API 端点 | `https://open.bigmodel.cn/api/coding/paas/v4` |
|
|
||||||
|
|
||||||
## 命令
|
## Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 分析视频
|
# 分析视频(默认)
|
||||||
AI_API_KEY="xxx" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \
|
AI_API_KEY="your-api-key" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \
|
||||||
python3 -u deep_analyzer.py \
|
python3 -u deep_analyzer.py --metadata meta.json --content content.json --output analysis.md --type video
|
||||||
--metadata meta.json \
|
|
||||||
--content content.json \
|
|
||||||
--output analysis.md \
|
|
||||||
--type video \
|
|
||||||
--provider zhipu --model glm-5
|
|
||||||
|
|
||||||
# 分析文章
|
# 分析文章(300字摘要 + 原文)
|
||||||
AI_API_KEY="xxx" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \
|
AI_API_KEY="your-api-key" AI_PROVIDER="zhipu" AI_MODEL="glm-5" \
|
||||||
python3 -u deep_analyzer.py \
|
python3 -u deep_analyzer.py --metadata meta.json --content content.json --output analysis.md --type article
|
||||||
--metadata meta.json \
|
|
||||||
--content content.txt \
|
# 指定 AI 提供商
|
||||||
--output analysis.md \
|
python3 -u deep_analyzer.py -m meta.json -c content.json -o out.md --type video --provider zhipu --model glm-5
|
||||||
--type article \
|
|
||||||
--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
|
```bash
|
||||||
cp -r kb-deep-analyzer/ ~/.openclaw/skills/
|
export AI_API_KEY="your-api-key"
|
||||||
pip install httpx
|
export AI_PROVIDER="zhipu" # 或 openai, minimax
|
||||||
|
export AI_MODEL="glm-5" # 模型名称
|
||||||
|
export AI_BASE_URL="https://..." # 可选,自定义 API 地址
|
||||||
```
|
```
|
||||||
|
|
||||||
## 在 kb-workflow 中的使用
|
### 重要提示
|
||||||
|
|
||||||
|
**必须使用 `-u` 参数运行 Python**,确保输出实时显示在终端:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 步骤 5:深度分析
|
python3 -u deep_analyzer.py ...
|
||||||
# ⚠️ 必须成功,否则整个流程失败
|
|
||||||
|
|
||||||
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 → 整个流程终止,报告错误
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## ⚠️ 重要提示
|
如果不使用 `-u` 参数,Python 的 stdout 缓冲会导致输出延迟或看不到进度。
|
||||||
|
|
||||||
1. **必须使用 `-u` 参数**:确保 Python 输出实时显示
|
## 执行方式选择
|
||||||
2. **深度分析不可跳过**:这是必须成功的步骤
|
|
||||||
3. **失败即终止**:如果返回 `success: false`,整个流程必须停止
|
### 方式1: 并发执行(推荐,默认)
|
||||||
4. **禁止降级**:不能使用预设模板或简单摘要"假装成功"
|
- 使用 `batch_size=3`(默认)
|
||||||
5. **并发执行**:默认使用 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
会自动转换为扁平格式进行分析。
|
||||||
|
|||||||
+44
-104
@@ -1,41 +1,44 @@
|
|||||||
---
|
---
|
||||||
name: kb-funasr
|
name: kb-funasr
|
||||||
description: 本地语音识别 - 使用阿里 FunASR 进行中文优化的语音识别
|
description: 本地语音识别,支持音视频转文字(基于阿里 FunASR)
|
||||||
---
|
---
|
||||||
|
|
||||||
# KB FunASR Skill
|
# 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
|
```bash
|
||||||
# 基本用法(使用 Paraformer 中文模型,推荐)
|
# 基本用法(使用 Paraformer 模型)
|
||||||
python3 funasr_tool.py --input video.mp4
|
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 多语言模型
|
||||||
| `paraformer-zh` | Paraformer 中文模型 | **推荐**,中文优化 |
|
- `sensevoice` - SenseVoice 多语言模型
|
||||||
| `paraformer` | Paraformer 多语言模型 | 多语言场景 |
|
|
||||||
| `sensevoice` | SenseVoice 模型 | 高精度需求 |
|
|
||||||
|
|
||||||
## 输出格式 Schema
|
## 输出文件
|
||||||
|
|
||||||
### 必需字段
|
对于输入 `video.mp4`,将生成:
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
- `video.json` - 详细结果(包含时间戳、分段信息)
|
||||||
|------|------|------|
|
- `video.txt` - 纯文本内容
|
||||||
| `success` | boolean | 是否识别成功 |
|
|
||||||
| `input_file` | string | 输入文件路径 |
|
|
||||||
| `model` | string | 使用的模型 |
|
|
||||||
|
|
||||||
### 可选字段
|
## 输出格式示例
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
### JSON 格式
|
||||||
|------|------|------|
|
|
||||||
| `output_files` | object | 输出文件路径 |
|
|
||||||
| `duration_seconds` | number | 音频时长 |
|
|
||||||
| `segments` | array | 识别分段 |
|
|
||||||
| `error` | string | 错误信息 |
|
|
||||||
|
|
||||||
## 成功示例
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"input_file": "content/downloads/bilibili_BV1xx411c7mD.mp4",
|
"input_file": "video.mp4",
|
||||||
"model": "paraformer-zh",
|
"model": "paraformer-zh",
|
||||||
"output_files": {
|
"output_files": {
|
||||||
"json": "content/bilibili_BV1xx411c7mD_funasr.json",
|
"json": "video.json",
|
||||||
"txt": "content/bilibili_BV1xx411c7mD_funasr.txt"
|
"txt": "video.txt"
|
||||||
},
|
},
|
||||||
"duration_seconds": 630.5,
|
"duration_seconds": 120.5,
|
||||||
"segments": [
|
"segments": [
|
||||||
{
|
{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"start": 0.0,
|
"start": 0.0,
|
||||||
"end": 3.2,
|
"end": 3.2,
|
||||||
"text": "这是第一段识别结果"
|
"text": "这是第一段识别结果"
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"start": 3.2,
|
|
||||||
"end": 6.5,
|
|
||||||
"text": "这是第二段识别结果"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 错误示例
|
## Workflow 中的使用
|
||||||
|
|
||||||
### 模型未下载
|
```bash
|
||||||
|
# 步骤4之后:如果已有音频但无字幕,可以使用 FunASR
|
||||||
```json
|
python funasr.py --input ${video_path} --model paraformer-zh --background
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "模型未找到",
|
|
||||||
"model": "paraformer-zh",
|
|
||||||
"suggestion": "首次运行时会自动下载模型,请确保网络连接正常"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 文件不存在
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "输入文件不存在",
|
|
||||||
"input_file": "content/downloads/missing.mp4"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 内存不足
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "内存不足",
|
|
||||||
"suggestion": "尝试使用较小的模型或处理较短的音频片段"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
@@ -139,35 +98,16 @@ python3 funasr_tool.py --input video.mp4 --background
|
|||||||
# 1. 安装依赖
|
# 1. 安装依赖
|
||||||
pip install funasr modelscope
|
pip install funasr modelscope
|
||||||
|
|
||||||
# 2. 首次运行时自动下载模型
|
# 2. 首次运行时会自动下载模型到缓存目录
|
||||||
python3 funasr_tool.py --input test.mp4
|
python funasr.py --input test.mp4
|
||||||
|
|
||||||
# 3. 复制技能
|
# 3. 复制技能到 skills 目录
|
||||||
cp -r kb-funasr/ ~/.openclaw/skills/
|
cp -r kb-funasr/ ~/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(深度分析)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
- **首次运行**:首次运行时会自动下载模型文件(约 1GB),需要稳定网络
|
- **异步执行**: 使用 `--background` 参数时,命令会在后台运行,不阻塞主代理
|
||||||
- **中文优化**:Paraformer 模型对中文识别效果优于 Whisper
|
- **模型选择**: paraformer-zh 模型适合中文语音识别,速度较快,精度较高
|
||||||
- **耗时操作**:语音识别可能需要几分钟到几十分钟
|
- **文件格式**: 支持 MP3、MP4、WAV、FLAC、OGG、M4A 等常见格式
|
||||||
- **文件格式**:支持 MP3、MP4、WAV、FLAC、OGG、M4A 等常见格式
|
- **首次运行**: 首次运行时会自动下载模型文件,需要稳定的网络连接
|
||||||
- **与 Whisper 对比**:
|
|
||||||
- Whisper:通用性强,支持多语言
|
|
||||||
- FunASR:中文优化,精度更高
|
|
||||||
|
|||||||
+22
-169
@@ -1,190 +1,43 @@
|
|||||||
---
|
|
||||||
name: kb-link-parser
|
|
||||||
description: 链接解析器 - 从各平台 URL 提取平台类型、内容类型和 ID
|
|
||||||
---
|
|
||||||
|
|
||||||
# KB Link Parser Skill
|
# 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
|
||||||
|
|
||||||
## 功能
|
## Commands
|
||||||
|
|
||||||
- 多平台支持:Bilibili、YouTube、知乎、小红书
|
|
||||||
- 短链接解析:b23.tv、xhslink.com 等
|
|
||||||
- 多种内容类型:video、article、question、answer 等
|
|
||||||
- 批量处理支持
|
|
||||||
- JSON 输出格式
|
|
||||||
|
|
||||||
## 命令
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 解析单个 URL
|
# Parse single URL
|
||||||
python3 link-parser.py --url "https://www.bilibili.com/video/BV1xx411c7mD"
|
python link-parser.py --url "https://www.bilibili.com/video/BV1xx411c7mD"
|
||||||
|
|
||||||
# 批量处理
|
# Batch processing
|
||||||
python3 link-parser.py --batch urls.txt --output results.json
|
python link-parser.py --batch urls.txt --output results.json
|
||||||
|
|
||||||
# 指定输出格式
|
# Output format
|
||||||
python3 link-parser.py --url "..." --format json
|
python link-parser.py --url "..." --format json
|
||||||
```
|
```
|
||||||
|
|
||||||
## 输出格式 Schema
|
## Output
|
||||||
|
|
||||||
### 必需字段
|
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
|
||||||
|------|------|------|
|
|
||||||
| `success` | boolean | 是否解析成功 |
|
|
||||||
| `platform` | string | 平台名称(成功时必需) |
|
|
||||||
| `type` | string | 内容类型(成功时必需) |
|
|
||||||
| `id` | string | 内容 ID(成功时必需) |
|
|
||||||
| `error` | string | 错误信息(失败时必需) |
|
|
||||||
|
|
||||||
### 可选字段
|
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
|
||||||
|------|------|------|
|
|
||||||
| `filename` | string | 建议的文件名 |
|
|
||||||
| `message` | string | 描述信息 |
|
|
||||||
|
|
||||||
## 成功示例
|
|
||||||
|
|
||||||
### B站视频
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"platform": "bilibili",
|
"data": {
|
||||||
"type": "video",
|
"platform": "bilibili",
|
||||||
"id": "BV1xx411c7mD",
|
"type": "video",
|
||||||
"filename": "bilibili_BV1xx411c7mD.link.json",
|
"id": "BV1xx411c7mD"
|
||||||
"message": "URL解析成功"
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### B站专栏
|
## Installation
|
||||||
|
|
||||||
```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` |
|
|
||||||
|
|
||||||
## 安装
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp -r kb-link-parser/ ~/.openclaw/skills/
|
cp -r kb-link-parser/ ~/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(元数据提取)
|
|
||||||
```
|
```
|
||||||
|
|||||||
Binary file not shown.
@@ -1,146 +1,66 @@
|
|||||||
---
|
|
||||||
name: kb-ocr-processor
|
|
||||||
description: 视频OCR识别 - 从视频帧中提取文字
|
|
||||||
---
|
|
||||||
|
|
||||||
# KB OCR Processor Skill
|
# KB OCR Processor Skill
|
||||||
|
|
||||||
**kb-ocr-processor** - 从视频帧中提取文字,作为语音识别的补充或替代方案。
|
**kb-ocr-processor** - Extract text from video frames using OCR.
|
||||||
|
|
||||||
## 什么时候使用
|
## Features
|
||||||
|
|
||||||
- kb-workflow 步骤 4 的降级方案:当 Whisper 语音识别效果不佳时
|
- **视频截帧**: 直接从视频文件截取帧图片
|
||||||
- 音频质量差、有背景音乐干扰、多种语言混合等情况
|
- **批量处理**: 支持处理帧目录
|
||||||
|
- **双引擎**: EasyOCR / Tesseract
|
||||||
|
- **置信度评分**: 每帧识别结果带置信度
|
||||||
|
- **文本合并**: 自动合并所有帧的识别结果
|
||||||
|
|
||||||
## 功能
|
## Commands
|
||||||
|
|
||||||
- 视频截帧:直接从视频文件截取帧图片
|
|
||||||
- 批量处理:支持处理帧目录
|
|
||||||
- 双引擎:EasyOCR / Tesseract
|
|
||||||
- 置信度评分:每帧识别结果带置信度
|
|
||||||
- 文本合并:自动合并所有帧的识别结果
|
|
||||||
|
|
||||||
## 命令
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 方式1: 直接从视频截帧并 OCR(推荐)
|
# 方式1: 直接从视频截帧并OCR(推荐)
|
||||||
python3 ocr_processor.py --video ./video.mp4 --output ocr.json
|
python ocr_processor.py --video ./video.flv --output ocr.json
|
||||||
|
|
||||||
# 方式2: 处理已截取的帧目录
|
# 方式2: 处理已截取的帧目录
|
||||||
python3 ocr_processor.py --input ./frames/ --output ocr.json
|
python ocr_processor.py --input ./frames/ --output ocr.json
|
||||||
|
|
||||||
# 指定截帧帧率(默认1帧/秒)
|
# 指定截帧帧率(默认1帧/秒)
|
||||||
python3 ocr_processor.py --video ./video.mp4 --fps 2 --output ocr.json
|
python ocr_processor.py --video ./video.flv --fps 2 --output ocr.json
|
||||||
|
|
||||||
# 同时生成合并的文本文件
|
# 同时生成合并的文本文件
|
||||||
python3 ocr_processor.py --video ./video.mp4 --output ocr.json --merge
|
python ocr_processor.py --video ./video.flv --output ocr.json --merge
|
||||||
|
|
||||||
# 使用 Tesseract 引擎
|
# 使用 Tesseract 引擎
|
||||||
python3 ocr_processor.py --input ./frames/ --engine tesseract --output ocr.json
|
python ocr_processor.py --input ./frames/ --engine tesseract --output ocr.json
|
||||||
```
|
```
|
||||||
|
|
||||||
## 输出格式 Schema
|
## Workflow 中的使用
|
||||||
|
|
||||||
### 必需字段
|
```bash
|
||||||
|
# 步骤5: OCR处理(视频无字幕时)
|
||||||
|
python ocr_processor.py --video ${CONTENT_VIDEO_PATH} --output ${CONTENT_DIR}/ocr.json --merge
|
||||||
|
```
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
## Output
|
||||||
|------|------|------|
|
|
||||||
| `success` | boolean | 是否识别成功 |
|
|
||||||
| `engine` | string | 使用的 OCR 引擎 |
|
|
||||||
| `total_frames` | number | 处理的总帧数 |
|
|
||||||
|
|
||||||
### 可选字段
|
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
|
||||||
|------|------|------|
|
|
||||||
| `results` | array | 每帧的识别结果 |
|
|
||||||
| `merged_text` | string | 合并后的文本 |
|
|
||||||
| `output_file` | string | 输出文件路径 |
|
|
||||||
| `error` | string | 错误信息 |
|
|
||||||
|
|
||||||
## 成功示例
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"engine": "easyocr",
|
"engine": "easyocr",
|
||||||
"total_frames": 619,
|
"total_frames": 619,
|
||||||
"output_file": "content/bilibili_BV1xx411c7mD_ocr.json",
|
|
||||||
"results": [
|
"results": [
|
||||||
{
|
{
|
||||||
"source": "0001.jpg",
|
"source": "0001.jpg",
|
||||||
"text": "字幕文字",
|
"text": "字幕文字",
|
||||||
"confidence": 0.95
|
"confidence": 0.95
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "0002.jpg",
|
|
||||||
"text": "更多字幕文字",
|
|
||||||
"confidence": 0.92
|
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"merged_text": "字幕文字\n更多字幕文字\n..."
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 错误示例
|
## Installation
|
||||||
|
|
||||||
### 视频文件不存在
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "视频文件不存在",
|
|
||||||
"video": "./missing.mp4"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### ffmpeg 未安装
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "ffmpeg 未安装",
|
|
||||||
"suggestion": "请运行: sudo apt-get install ffmpeg"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 内存不足
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "内存不足",
|
|
||||||
"suggestion": "尝试降低帧率或处理较短的片段"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 安装
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp -r kb-ocr-processor/ ~/.openclaw/skills/
|
cp -r kb-ocr-processor/ ~/skills/
|
||||||
pip install easyocr pytesseract Pillow
|
pip install -r requirements.txt
|
||||||
|
|
||||||
# 系统依赖
|
# 依赖说明
|
||||||
sudo apt-get install ffmpeg tesseract-ocr tesseract-ocr-chi-sim tesseract-ocr-eng
|
# - easyocr: 主要OCR引擎(自动下载模型)
|
||||||
|
# - pytesseract: Tesseract引擎
|
||||||
|
# - ffmpeg: 视频截帧(apt install ffmpeg)
|
||||||
```
|
```
|
||||||
|
|
||||||
## 在 kb-workflow 中的使用
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 步骤 4 的降级方案(当 Whisper 效果不佳时)
|
|
||||||
python3 ~/.openclaw/skills/kb-ocr-processor/ocr_processor.py \
|
|
||||||
--video "content/downloads/bilibili_BV1xx411c7mD.mp4" \
|
|
||||||
--output "content/bilibili_BV1xx411c7mD_ocr.json" \
|
|
||||||
--merge
|
|
||||||
|
|
||||||
# 输出:
|
|
||||||
# - bilibili_BV1xx411c7mD_ocr.json (完整结果)
|
|
||||||
# - bilibili_BV1xx411c7mD_ocr.txt (合并文本)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
- **耗时操作**:OCR 处理需要截帧和识别,可能较慢
|
|
||||||
- **帧率选择**:1帧/秒适合大多数场景,更高帧率增加精度但耗时更长
|
|
||||||
- **引擎选择**:EasyOCR 精度较高,Tesseract 速度较快
|
|
||||||
- **适用场景**:音频质量差、背景音乐干扰、多语言混合时使用
|
|
||||||
|
|||||||
+53
-109
@@ -1,40 +1,44 @@
|
|||||||
---
|
---
|
||||||
name: kb-whisper
|
name: kb-whisper
|
||||||
description: 本地语音识别 - 使用 Whisper.cpp 将音视频转文字
|
description: 本地语音识别,支持音视频转文字(基于 Whisper.cpp)
|
||||||
---
|
---
|
||||||
|
|
||||||
# KB Whisper Skill
|
# KB Whisper Skill
|
||||||
|
|
||||||
**kb-whisper** - 本地语音识别,使用 Whisper.cpp 将音视频文件转换为文本、字幕和 JSON 格式。
|
**kb-whisper** - 本地语音识别,使用 Whisper.cpp 将音视频文件转换为文本、字幕和 JSON 格式输出。
|
||||||
|
|
||||||
## 什么时候使用
|
## 什么时候使用
|
||||||
|
|
||||||
- kb-workflow 步骤 4:视频无官方字幕时进行语音识别
|
当用户需要:
|
||||||
- 需要将音视频转为文字
|
- 将视频/音频文件转换为文字
|
||||||
|
- 生成视频字幕(SRT 格式)
|
||||||
|
- 获取带时间戳的详细识别结果
|
||||||
|
|
||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
||||||
| 变量名 | 必需 | 说明 |
|
在使用之前,必须检查环境变量是否已经设置。
|
||||||
|--------|------|------|
|
|
||||||
| `WHISPER_CPP_PATH` | 是 | whisper.cpp 安装路径 |
|
|
||||||
|
|
||||||
## 命令
|
| 变量名 | 用途 | 示例 |
|
||||||
|
|--------|------|------|
|
||||||
|
| `WHISPER_CPP_PATH` | whisper.cpp 安装路径 | `~/whisper.cpp` |
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 基本用法
|
# 基本用法
|
||||||
python3 whisper.py --input video.mp4
|
python whisper.py --input video.mp4
|
||||||
|
|
||||||
# 指定模型(推荐 base)
|
# 指定模型(默认 tiny)
|
||||||
python3 whisper.py --input video.mp4 --model base
|
python whisper.py --input video.mp4 --model base
|
||||||
|
|
||||||
# 指定输出目录
|
# 指定输出目录
|
||||||
python3 whisper.py --input video.mp4 --output ./output
|
python whisper.py --input video.mp4 --output ./output
|
||||||
|
|
||||||
# 后台异步执行
|
# 异步执行(推荐)
|
||||||
python3 whisper.py --input video.mp4 --background
|
python whisper.py --input video.mp4 --background
|
||||||
```
|
```
|
||||||
|
|
||||||
## 参数说明
|
## 命令参数
|
||||||
|
|
||||||
| 参数 | 说明 | 默认值 |
|
| 参数 | 说明 | 默认值 |
|
||||||
|------|------|--------|
|
|------|------|--------|
|
||||||
@@ -45,94 +49,51 @@ python3 whisper.py --input video.mp4 --background
|
|||||||
|
|
||||||
## 模型选项
|
## 模型选项
|
||||||
|
|
||||||
| 模型 | 速度 | 精度 | 推荐场景 |
|
- `tiny` - 最小模型,速度快,精度较低(推荐快速识别)
|
||||||
|------|------|------|---------|
|
- `base` - 基础模型,平衡速度和精度(推荐)
|
||||||
| `tiny` | 最快 | 较低 | 快速预览 |
|
- `small` - 小型模型,精度更高,速度较慢
|
||||||
| `base` | 快 | 良好 | **推荐** |
|
- `medium` - 中型模型,高精度
|
||||||
| `small` | 中等 | 高 | 精确识别 |
|
- `large` - 大型模型,最高精度,速度慢
|
||||||
| `medium` | 慢 | 很高 | 专业场景 |
|
|
||||||
| `large` | 最慢 | 最高 | 最高精度 |
|
|
||||||
|
|
||||||
## 输出格式 Schema
|
## 输出文件
|
||||||
|
|
||||||
### 必需字段
|
对于输入 `video.mp4`,将生成:
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
- `video.json` - 详细结果(包含时间戳、分段信息)
|
||||||
|------|------|------|
|
- `video.srt` - 字幕格式文件
|
||||||
| `success` | boolean | 是否识别成功 |
|
- `video.txt` - 纯文本内容
|
||||||
| `input_file` | string | 输入文件路径 |
|
|
||||||
| `model` | string | 使用的模型 |
|
|
||||||
|
|
||||||
### 可选字段
|
## 输出格式示例
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
### JSON 格式
|
||||||
|------|------|------|
|
|
||||||
| `output_files` | object | 输出文件路径 |
|
|
||||||
| `duration_seconds` | number | 音频时长 |
|
|
||||||
| `segments` | array | 识别分段 |
|
|
||||||
| `error` | string | 错误信息 |
|
|
||||||
|
|
||||||
## 成功示例
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"input_file": "content/downloads/bilibili_BV1xx411c7mD.mp4",
|
"input_file": "video.mp4",
|
||||||
"model": "base",
|
"model": "tiny",
|
||||||
"output_files": {
|
"output_files": {
|
||||||
"json": "content/bilibili_BV1xx411c7mD.json",
|
"json": "video.json",
|
||||||
"txt": "content/bilibili_BV1xx411c7mD.txt",
|
"srt": "video.srt",
|
||||||
"srt": "content/bilibili_BV1xx411c7mD.srt"
|
"txt": "video.txt"
|
||||||
},
|
},
|
||||||
"duration_seconds": 630.5,
|
"duration_seconds": 120.5,
|
||||||
"segments": [
|
"segments": [
|
||||||
{
|
{
|
||||||
"id": 0,
|
"id": 0,
|
||||||
"start": 0.0,
|
"start": 0.0,
|
||||||
"end": 3.2,
|
"end": 3.2,
|
||||||
"text": "这是第一段字幕"
|
"text": "这是第一段字幕"
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"start": 3.2,
|
|
||||||
"end": 6.5,
|
|
||||||
"text": "这是第二段字幕"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 错误示例
|
## Workflow 中的使用
|
||||||
|
|
||||||
### 模型未下载
|
```bash
|
||||||
|
# 步骤4之后:如果已有音频但无字幕,可以使用 whisper
|
||||||
```json
|
python whisper.py --input ${video_path} --model base --background
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "模型文件不存在",
|
|
||||||
"model": "base",
|
|
||||||
"suggestion": "请运行: cd ~/whisper.cpp && ./models/download-ggml-model.sh base"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 文件不存在
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "输入文件不存在",
|
|
||||||
"input_file": "content/downloads/missing.mp4"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 内存不足
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "内存不足,无法加载模型",
|
|
||||||
"suggestion": "尝试使用更小的模型(tiny/base)"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
@@ -142,39 +103,22 @@ python3 whisper.py --input video.mp4 --background
|
|||||||
git clone https://github.com/ggerganov/whisper.cpp.git ~/whisper.cpp
|
git clone https://github.com/ggerganov/whisper.cpp.git ~/whisper.cpp
|
||||||
|
|
||||||
# 2. 编译
|
# 2. 编译
|
||||||
cd ~/whisper.cpp && make
|
cd ~/whisper.cpp
|
||||||
|
make
|
||||||
|
|
||||||
# 3. 下载模型
|
# 3. 下载模型(tiny)
|
||||||
./models/download-ggml-model.sh base
|
./models/download-ggml-model.sh tiny
|
||||||
|
|
||||||
# 4. 设置环境变量
|
# 4. 下载更多模型(可选)
|
||||||
echo 'export WHISPER_CPP_PATH="$HOME/whisper.cpp"' >> ~/.kb_env
|
# ./models/download-ggml-model.sh base
|
||||||
source ~/.kb_env
|
# ./models/download-ggml-model.sh small
|
||||||
|
|
||||||
# 5. 复制技能
|
# 5. 复制技能到 skills 目录
|
||||||
cp -r kb-whisper/ ~/.openclaw/skills/
|
cp -r kb-whisper/ ~/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(深度分析)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
- **耗时操作**:语音识别可能需要几分钟到几十分钟,取决于视频长度
|
- **异步执行**: 使用 `--background` 参数时,命令会在后台运行,不阻塞主代理
|
||||||
- **异步执行**:推荐使用 `--background` 参数
|
- **模型选择**: tiny 模型适合快速识别,base 模型适合一般用途,large 模型适合高精度需求
|
||||||
- **模型选择**:base 模型平衡速度和精度,适合大多数场景
|
- **文件格式**: 支持 MP3、MP4、WAV、FLAC、OGG、M4A 等常见格式
|
||||||
- **文件格式**:支持 MP3、MP4、WAV、FLAC、OGG、M4A 等常见格式
|
|
||||||
|
|||||||
+141
-639
@@ -5,698 +5,200 @@ description: 当收到"添加到知识库 + 链接" 或"保存到知识库 + 链
|
|||||||
|
|
||||||
# KB Workflow
|
# KB Workflow
|
||||||
|
|
||||||
## 触发条件
|
## 什么时候使用
|
||||||
|
|
||||||
|
当用户发送包含以下模式的消息时,此技能自动触发:
|
||||||
|
|
||||||
| 触发词 | 行为 | 示例 |
|
| 触发词 | 行为 | 示例 |
|
||||||
|--------|------|------|
|
|--------|------|------|
|
||||||
| `添加到知识库` + 链接 | 添加到知识库并处理 | "添加到知识库 https://www.bilibili.com/video/BVxxx" |
|
| `添加到知识库` + 链接 | 添加到知识库并处理 | "添加到知识库 https://www.bilibili.com/video/BVxxx" |
|
||||||
| `保存到知识库` + 链接 | 同上 | "保存到知识库 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
|
```bash
|
||||||
# 创建专用配置文件
|
|
||||||
cat > ~/.kb_env << 'EOF'
|
|
||||||
export AI_API_KEY="your-api-key"
|
export AI_API_KEY="your-api-key"
|
||||||
export AI_PROVIDER="zhipu"
|
export AI_PROVIDER="zhipu"
|
||||||
export AI_MODEL="glm-5"
|
export AI_MODEL="glm-5"
|
||||||
export AI_BASE_URL="https://open.bigmodel.cn/api/coding/paas/v4"
|
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
|
```bash
|
||||||
# 加载环境变量
|
# 从 ~/.kb_env 加载环境变量
|
||||||
if [ -f ~/.kb_env ]; then source ~/.kb_env; fi
|
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 "✅ 环境变量检查通过"
|
echo "✅ 环境变量检查通过"
|
||||||
```
|
```
|
||||||
|
|
||||||
**成功标准:**
|
## Workflow 执行方式
|
||||||
- 所有必需变量已设置
|
|
||||||
- 输出 "✅ 环境变量检查通过"
|
|
||||||
|
|
||||||
**失败处理:**
|
### 方式一:一键处理(推荐)
|
||||||
- 缺少任何必需变量 → 报错退出,提示用户配置
|
|
||||||
|
|
||||||
**输出示例:**
|
使用管道 CLI 一键完成所有步骤:
|
||||||
```
|
|
||||||
✅ 环境变量检查通过
|
|
||||||
AI_PROVIDER: zhipu
|
|
||||||
AI_MODEL: glm-5
|
|
||||||
```
|
|
||||||
|
|
||||||
**错误示例:**
|
|
||||||
```
|
|
||||||
❌ 错误:AI_API_KEY 未设置
|
|
||||||
请配置以下环境变量:
|
|
||||||
- AI_API_KEY
|
|
||||||
- AI_PROVIDER
|
|
||||||
- AI_MODEL
|
|
||||||
- AI_BASE_URL
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 1: 链接解析
|
|
||||||
|
|
||||||
**前置条件:**
|
|
||||||
- 环境变量检查通过
|
|
||||||
- URL 格式有效
|
|
||||||
|
|
||||||
**执行命令:**
|
|
||||||
```bash
|
```bash
|
||||||
# 获取目录路径
|
python3 kb-workflow/kb_workflow.py process "https://www.bilibili.com/video/BVxxx"
|
||||||
python3 ~/.openclaw/skills/kb-workflow/kb_workflow.py --pending
|
|
||||||
|
|
||||||
# 解析链接
|
|
||||||
python3 ~/.openclaw/skills/kb-link-parser/link-parser.py --url "[URL]"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**成功标准:**
|
**该命令自动执行:**
|
||||||
- 返回 JSON 包含 `success: true`
|
1. URL 解析 → 识别平台和内容 ID
|
||||||
- 包含字段:`platform`, `content_type`, `content_id`
|
2. 元数据提取 → 获取标题、作者等信息
|
||||||
- 生成文件:`pending/{platform}_{id}.link.json`
|
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
|
```bash
|
||||||
# 获取目录路径
|
# 指定输出目录
|
||||||
python3 ~/.openclaw/skills/kb-workflow/kb_workflow.py --metadata
|
python3 kb-workflow/kb_workflow.py process "https://..." -o /path/to/output
|
||||||
|
|
||||||
# 根据平台选择命令
|
# 强制重新执行(忽略已完成状态)
|
||||||
# B站视频
|
python3 kb-workflow/kb_workflow.py process "https://..." --no-skip
|
||||||
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"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**成功标准:**
|
### 方式二:手动分步执行(高级)
|
||||||
- 返回 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
|
```bash
|
||||||
# 获取目录路径
|
# 1. 查重
|
||||||
python3 ~/.openclaw/skills/kb-workflow/kb_workflow.py --content_downloads
|
python3 kb-workflow/kb_workflow.py --check --url "https://..."
|
||||||
|
|
||||||
# B站视频 - 优先尝试字幕
|
# 2. 一键处理
|
||||||
python3 ~/.openclaw/skills/kb-bilibili-content/bilibili_content.py \
|
python3 kb-workflow/kb_workflow.py process "https://..."
|
||||||
--id "[BV号]" --type subtitle-download \
|
|
||||||
--output "content/downloads/"
|
|
||||||
|
|
||||||
# 检查是否有官方字幕
|
# 3. 归档
|
||||||
# 如果 has_subtitle=true → 进入 Step 5
|
python3 kb-workflow/kb_workflow.py --archive-file "/path/to/report.md"
|
||||||
# 如果 has_subtitle=false → 下载视频,进入 Step 4
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**成功标准:**
|
## 支持的平台和内容类型
|
||||||
- 返回 JSON 包含 `success: true`
|
|
||||||
- `has_subtitle=true`: 有字幕文件
|
|
||||||
- `has_subtitle=false`: 视频文件下载成功
|
|
||||||
|
|
||||||
**失败处理:**
|
| 平台 | 内容类型 | URL 示例 |
|
||||||
- 403 禁止访问 → 检查 BILIBILI_COOKIE 配置
|
|------|----------|----------|
|
||||||
- 网络超时 → 重试1次
|
| B站 | 视频 | `bilibili.com/video/BVxxx` |
|
||||||
- 会员视频 → 提示需要配置 Cookie
|
| 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": "官方字幕下载成功"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
**输出示例(无字幕):**
|
│ kb-workflow process │
|
||||||
```json
|
├─────────────────────────────────────────────────────────────┤
|
||||||
{
|
│ 1. Parse → LinkParser 解析 URL │
|
||||||
"success": true,
|
│ 2. Download → 平台适配器获取元数据和内容 │
|
||||||
"type": "subtitle",
|
│ 3. ASR → 语音识别(视频无字幕时) │
|
||||||
"has_subtitle": false,
|
│ 4. Analyze → DeepAnalyzer 生成分析报告 │
|
||||||
"message": "无官方字幕,需要下载视频进行语音识别"
|
│ 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/
|
└── 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. **禁止降级处理**:不能使用预设模板或简单摘要"假装成功"
|
1. **深度分析不可跳过**:AI 分析是必须成功执行的步骤
|
||||||
4. **每次执行都要使用 AI**:必须有真实的 AI API 调用
|
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 — 数据模型
|
||||||
|
```
|
||||||
|
|||||||
+128
-354
@@ -5,7 +5,7 @@ KB Workflow - Knowledge Base Workflow Orchestrator
|
|||||||
|
|
||||||
知识库工作流辅助工具函数。
|
知识库工作流辅助工具函数。
|
||||||
|
|
||||||
此模块提供查重、文件操作、Git 管理、状态管理等工具函数,
|
此模块提供查重、文件操作、Git 管理等工具函数,
|
||||||
供主代理在执行 SKILL.md 中定义的 workflow 时调用。
|
供主代理在执行 SKILL.md 中定义的 workflow 时调用。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -18,46 +18,7 @@ import shutil
|
|||||||
import re
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional, Any, Tuple
|
from typing import Dict, List, Optional, Any
|
||||||
|
|
||||||
|
|
||||||
# ==================== 状态机定义 ====================
|
|
||||||
|
|
||||||
# 工作流步骤顺序
|
|
||||||
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": "完成"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# ==================== 子技能映射 ====================
|
# ==================== 子技能映射 ====================
|
||||||
@@ -332,249 +293,6 @@ def archive_and_git(
|
|||||||
return result
|
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:
|
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
|
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 ====================
|
# ==================== CLI ====================
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@@ -618,117 +413,96 @@ def main():
|
|||||||
使用示例:
|
使用示例:
|
||||||
# 查重
|
# 查重
|
||||||
python kb_workflow.py --check --url "https://www.bilibili.com/video/BVxxx"
|
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 --archive "/path/to/analyzed.md"
|
||||||
|
|
||||||
# 状态管理
|
# 处理URL (通过完整管道)
|
||||||
python kb_workflow.py --init-state --url "https://..."
|
python kb_workflow.py process "https://www.bilibili.com/video/BVxxx"
|
||||||
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://..."
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
# 基础参数
|
# Create subparsers for commands
|
||||||
parser.add_argument('--url', type=str, help='URL 地址')
|
subparsers = parser.add_subparsers(dest='command', help='Available commands')
|
||||||
parser.add_argument('--base-path', type=str, help='知识库根目录')
|
|
||||||
|
# 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('--check', action='store_true', help='查重')
|
||||||
|
parser.add_argument('--url', type=str, help='要检查的URL')
|
||||||
parser.add_argument('--archive-file', type=str, help='归档的文件路径')
|
parser.add_argument('--archive-file', type=str, help='归档的文件路径')
|
||||||
|
parser.add_argument('--base-path', type=str, help='获取知识库根目录')
|
||||||
# 目录路径查询
|
|
||||||
parser.add_argument('--pending', action='store_true', help='获取 URL 解析目录')
|
parser.add_argument('--pending', action='store_true', help='获取url解析目录')
|
||||||
parser.add_argument('--metadata', action='store_true', help='获取元数据目录')
|
parser.add_argument('--metadata', action='store_true', help='获取元数据目录')
|
||||||
parser.add_argument('--content', 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('--analyzed', action='store_true', help='获取深度分析目录')
|
||||||
parser.add_argument('--archive_dir', 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('--archive_subscriptions', action='store_true', help='获取订阅信息目录')
|
||||||
parser.add_argument('--extract_platform', type=str, 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='获取恢复执行信息')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
base_path = Path(args.base_path) if args.base_path else None
|
base_path = Path(args.base_path) if args.base_path else None
|
||||||
dirs = ensure_directories(base_path)
|
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:
|
if args.check and args.url:
|
||||||
result = check_duplicate(base_path, args.url)
|
result = check_duplicate(base_path, args.url)
|
||||||
print(json.dumps(result, ensure_ascii=False, indent=2))
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|
||||||
|
|
||||||
# 归档
|
|
||||||
elif args.archive_file:
|
elif args.archive_file:
|
||||||
result = archive_and_git(args.archive_file, base_path)
|
result = archive_and_git(args.archive_file, base_path)
|
||||||
print(json.dumps(result, ensure_ascii=False, indent=2))
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|
||||||
|
|
||||||
# 目录路径查询
|
|
||||||
elif args.pending:
|
elif args.pending:
|
||||||
print(json.dumps({"path": str(dirs["pending"])}, ensure_ascii=False, indent=2))
|
print(json.dumps({"path": str(dirs["pending"])}, ensure_ascii=False, indent=2))
|
||||||
|
|
||||||
elif args.metadata:
|
elif args.metadata:
|
||||||
print(json.dumps({"path": str(dirs["metadata"])}, ensure_ascii=False, indent=2))
|
print(json.dumps({"path": str(dirs["metadata"])}, ensure_ascii=False, indent=2))
|
||||||
|
|
||||||
elif args.content:
|
elif args.content:
|
||||||
print(json.dumps({"path": str(dirs["content"])}, ensure_ascii=False, indent=2))
|
print(json.dumps({"path": str(dirs["content"])}, ensure_ascii=False, indent=2))
|
||||||
|
|
||||||
elif args.content_downloads:
|
elif args.content_downloads:
|
||||||
print(json.dumps({"path": str(dirs["content_downloads"])}, ensure_ascii=False, indent=2))
|
print(json.dumps({"path": str(dirs["content_downloads"])}, ensure_ascii=False, indent=2))
|
||||||
|
|
||||||
elif args.analyzed:
|
elif args.analyzed:
|
||||||
print(json.dumps({"path": str(dirs["analyzed"])}, ensure_ascii=False, indent=2))
|
print(json.dumps({"path": str(dirs["analyzed"])}, ensure_ascii=False, indent=2))
|
||||||
|
|
||||||
elif args.archive_dir:
|
elif args.archive_dir:
|
||||||
print(json.dumps({"path": str(get_archive_path())}, ensure_ascii=False, indent=2))
|
print(json.dumps({"path": str(get_archive_path())}, ensure_ascii=False, indent=2))
|
||||||
|
|
||||||
elif args.archive_subscriptions:
|
elif args.archive_subscriptions:
|
||||||
print(json.dumps({"path": str(dirs["archive_subscriptions"])}, ensure_ascii=False, indent=2))
|
print(json.dumps({"path": str(dirs["archive_subscriptions"])}, ensure_ascii=False, indent=2))
|
||||||
|
|
||||||
elif args.extract_platform:
|
elif args.extract_platform:
|
||||||
platform = extract_platform(args.extract_platform)
|
platform = extract_platform(args.extract_platform)
|
||||||
print(json.dumps({"platform": platform}, ensure_ascii=False, indent=2))
|
print(json.dumps({"platform": platform}, ensure_ascii=False, indent=2))
|
||||||
|
|
||||||
elif args.base_path:
|
elif args.base_path:
|
||||||
print(json.dumps({"path": str(dirs["base"])}, ensure_ascii=False, indent=2))
|
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:
|
else:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
|
|||||||
@@ -1,154 +1,86 @@
|
|||||||
---
|
|
||||||
name: kb-zhihu-content
|
|
||||||
description: 知乎内容下载 - 下载视频、提取文章内容
|
|
||||||
---
|
|
||||||
|
|
||||||
# KB Zhihu Content Skill
|
# KB Zhihu Content Skill
|
||||||
|
|
||||||
**kb-zhihu-content** - 下载知乎视频、提取文章内容。
|
**kb-zhihu-content** - Download Zhihu videos and extract content.
|
||||||
|
|
||||||
## 什么时候使用
|
## Features
|
||||||
|
|
||||||
- kb-workflow 步骤 3a:下载知乎视频
|
- Video download using **yt-dlp**
|
||||||
- kb-workflow 步骤 3b:提取知乎专栏文章内容
|
- Subtitle extraction (returns no subtitle, triggers Whisper)
|
||||||
|
- **Read article content from MediaCrawler data** (NEW!)
|
||||||
|
- Supports `ZHIHU_COOKIE` environment variable
|
||||||
|
|
||||||
## 功能
|
## Environment Variables
|
||||||
|
|
||||||
- 视频下载(使用 yt-dlp)
|
| Variable | Required | Description |
|
||||||
- 从 MediaCrawler 数据读取文章内容
|
|----------|----------|-------------|
|
||||||
- 支持 `ZHIHU_COOKIE` 环境变量
|
| `ZHIHU_COOKIE` | No | 知乎登录 Cookie (for member-only videos) |
|
||||||
|
|
||||||
## 环境变量
|
## Commands
|
||||||
|
|
||||||
| 变量名 | 必需 | 说明 |
|
|
||||||
|--------|------|------|
|
|
||||||
| `ZHIHU_COOKIE` | 否 | 知乎登录 Cookie |
|
|
||||||
|
|
||||||
## 命令
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 下载视频
|
# Download video
|
||||||
python3 zhihu_content.py --id "12345678" --type video --output "/path/to/downloads/"
|
python zhihu_content.py --id "12345678" --type video --output "/path/to/downloads/"
|
||||||
|
|
||||||
# 从 MediaCrawler 读取文章内容
|
# Extract subtitle (returns no subtitle, triggers Whisper)
|
||||||
python3 zhihu_content.py --type article-from-media \
|
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" \
|
--input "~/work/MediaCrawler/data/zhihu/json/detail_contents_2026-02-27.json" \
|
||||||
--output "~/work/knowledge-base/data/zhihu/"
|
--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/"
|
--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
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"type": "article",
|
"type": "article",
|
||||||
"filename": "zhihu_article_如何高效的爬取微信公众号.md",
|
"filename": "zhihu_article_如何高效的爬取微信公众号.md",
|
||||||
"filepath": "~/work/knowledge-base/data/zhihu/zhihu_article_如何高效的爬取微信公众号.md",
|
"filepath": "/home/xxx/work/knowledge-base/data/zhihu/zhihu_article_如何高效的爬取微信公众号.md",
|
||||||
"content_length": 4563,
|
|
||||||
"message": "文章内容已导出"
|
"message": "文章内容已导出"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 错误示例
|
## 原有功能
|
||||||
|
|
||||||
### 视频下载失败
|
### Video Download
|
||||||
|
|
||||||
```json
|
Video download uses **yt-dlp**:
|
||||||
{
|
1. Parses `ZHIHU_COOKIE` environment variable (optional)
|
||||||
"success": false,
|
2. Creates temporary Netscape-format cookie file
|
||||||
"type": "video",
|
3. Runs `yt-dlp -f best -o <output> <url>`
|
||||||
"error": "视频不存在或无法访问",
|
4. Cleans up temporary file
|
||||||
"suggestion": "请检查视频 ID 是否正确"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### MediaCrawler 数据未找到
|
**Note**: 知乎视频通常没有官方字幕,将自动触发 Whisper 语音识别
|
||||||
|
|
||||||
```json
|
## Installation
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"type": "article-from-media",
|
|
||||||
"error": "未找到 MediaCrawler 数据文件",
|
|
||||||
"suggestion": "请先运行 MediaCrawler 爬取文章"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 网络错误
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": false,
|
|
||||||
"error": "网络请求失败: Connection timeout"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 安装
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp -r kb-zhihu-content/ ~/.openclaw/skills/
|
# Already included in kb-skills repo
|
||||||
|
# Ensure yt-dlp is installed
|
||||||
pip install yt-dlp aiohttp
|
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 需要单独安装和运行
|
|
||||||
- 部分视频可能需要登录才能下载
|
|
||||||
|
|||||||
@@ -1,207 +1,101 @@
|
|||||||
---
|
|
||||||
name: kb-zhihu-metadata
|
|
||||||
description: 知乎元数据提取 - 获取问题/回答/专栏/视频的详细信息
|
|
||||||
---
|
|
||||||
|
|
||||||
# KB Zhihu Metadata Skill
|
# KB Zhihu Metadata Skill
|
||||||
|
|
||||||
**kb-zhihu-metadata** - 提取知乎问题、回答、用户、专栏的元数据。
|
**kb-zhihu-metadata** - Extract Zhihu question/answer/user metadata and crawl articles.
|
||||||
|
|
||||||
## 什么时候使用
|
## Features
|
||||||
|
|
||||||
- kb-workflow 步骤 2:获取知乎内容的元数据
|
- Question metadata extraction
|
||||||
- 需要问题标题、回答者、文章标题等信息
|
- Answer metadata extraction
|
||||||
|
- User information extraction
|
||||||
## 功能
|
- **Article crawling using MediaCrawler** (NEW!)
|
||||||
|
- JSON output format
|
||||||
- 问题元数据提取
|
- Markdown conversion support
|
||||||
- 回答元数据提取
|
- **Cookie 支持**:可配置 ZHIHU_COOKIE 访问需要登录的内容
|
||||||
- 用户信息提取
|
|
||||||
- 专栏文章爬取(使用 MediaCrawler)
|
|
||||||
- 支持 `ZHIHU_COOKIE` 环境变量
|
|
||||||
|
|
||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
||||||
| 变量名 | 必需 | 说明 |
|
| 变量名 | 用途 | 必需 |
|
||||||
|--------|------|------|
|
|--------|------|------|
|
||||||
| `ZHIHU_COOKIE` | 推荐 | 知乎登录 Cookie(访问专栏等需要) |
|
| `ZHIHU_COOKIE` | 知乎登录 Cookie | 推荐(访问专栏等需要) |
|
||||||
|
|
||||||
**获取 Cookie:**
|
**获取 ZHIHU_COOKIE**:
|
||||||
1. 登录知乎网页版
|
1. 登录知乎网页版
|
||||||
2. F12 → Application → Cookies → zhihu.com
|
2. 打开开发者工具 (F12) → Application → Cookies → zhihu.com
|
||||||
3. 复制 Cookie 字符串
|
3. 复制 Cookie 字符串
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export ZHIHU_COOKIE="你的知乎Cookie"
|
# 添加到 ~/.kb_env
|
||||||
|
echo 'export ZHIHU_COOKIE="你的知乎Cookie"' >> ~/.kb_env
|
||||||
|
source ~/.kb_env
|
||||||
```
|
```
|
||||||
|
|
||||||
## 命令
|
## Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 问题元数据
|
# Question metadata
|
||||||
python3 zhihu_metadata.py --id "266309957" --type question
|
python zhihu_metadata.py --id "266309957" --type question
|
||||||
|
|
||||||
# 回答元数据
|
# Answer metadata
|
||||||
python3 zhihu_metadata.py --id "2003427891925509507" --type answer
|
python zhihu_metadata.py --id "2003427891925509507" --type answer
|
||||||
|
|
||||||
# 知乎视频
|
# 专栏文章爬取 (使用 MediaCrawler) ⚡ NEW!
|
||||||
python3 zhihu_metadata.py --id "123456789" --type zvideo
|
python zhihu_article_crawler.py --url "https://zhuanlan.zhihu.com/p/1894054073625461813" --output "~/work/knowledge-base/data/zhihu/"
|
||||||
|
|
||||||
# 专栏文章爬取(使用 MediaCrawler)
|
|
||||||
python3 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
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"platform": "zhihu",
|
"data": {
|
||||||
"content_type": "question",
|
"platform": "zhihu",
|
||||||
"content_id": "266309957",
|
"type": "question",
|
||||||
"title": "问题标题",
|
"id": "266309957",
|
||||||
"excerpt": "问题描述...",
|
"title": "问题标题",
|
||||||
"stats": {
|
"author": "作者名字",
|
||||||
"answer_count": 50,
|
"answer_count": 50,
|
||||||
"follower_count": 1000,
|
"followers": 1000
|
||||||
"view_count": 50000
|
}
|
||||||
},
|
|
||||||
"output_file": "metadata/zhihu_266309957.meta.json"
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 回答元数据
|
## Installation
|
||||||
|
|
||||||
```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"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 安装
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp -r kb-zhihu-metadata/ ~/.openclaw/skills/
|
cp -r kb-zhihu-metadata/ ~/skills/
|
||||||
pip install httpx
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 在 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`
|
|
||||||
- 部分内容可能有访问限制
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user