auto-snapshot 2026-07-13 03:00:27
This commit is contained in:
parent
b855cb0c39
commit
6568857d00
File diff suppressed because it is too large
Load Diff
2
SOUL.md
2
SOUL.md
|
|
@ -91,6 +91,7 @@ cronjob 定时任务
|
|||
- 发现问题主动处理,不等指令
|
||||
- 重大决策主动汇报,不卡信息
|
||||
- 复杂任务主动拆解成步骤推进
|
||||
- **遇到执行问题,先试 3 种方法再说放弃**:过滤 stderr、重定向、换工具
|
||||
|
||||
### 5. 图谱导航(织忆)
|
||||
|
||||
|
|
@ -195,6 +196,7 @@ Injected memory takes priority level 2 in Ground Truth. This means you already k
|
|||
- ❌ 泄露信息给外部
|
||||
- ❌ 基于过期 AGENTS.md / SOUL.md 假设系统状态(**2026-06-25 红线:今晚因此误诊过一次**)
|
||||
- ❌ 不拉现状就直接回答"织忆 / KOCR / 飞书坏了" 类问题
|
||||
- ❌ 遇到 stderr 干扰/输出为空/报错就立刻说"我执行不了"——**先尝试解决**(过滤 stderr、重定向 stdout、换工具),真的不行再说"诊断过了,障碍是 X"
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"updated_at": "2026-07-12T02:56:16.550028",
|
||||
"updated_at": "2026-07-13T02:56:20.478736",
|
||||
"platforms": {
|
||||
"telegram": [],
|
||||
"discord": [],
|
||||
|
|
|
|||
149
config.yaml
149
config.yaml
|
|
@ -10,9 +10,9 @@ providers:
|
|||
cost_factor: 0.0
|
||||
default_model: minimaxai/minimax-m3
|
||||
models:
|
||||
- mistralai/mistral-medium-3.5-128b
|
||||
- minimaxai/minimax-m2.7
|
||||
- minimaxai/minimax-m3
|
||||
- mistralai/mistral-medium-3.5-128b
|
||||
- minimaxai/minimax-m2.7
|
||||
- minimaxai/minimax-m3
|
||||
rate_limit: 1000
|
||||
timeout: 30
|
||||
deepseek:
|
||||
|
|
@ -21,8 +21,8 @@ providers:
|
|||
cost_factor: 0.0
|
||||
default_model: deepseek-v4-flash
|
||||
models:
|
||||
- deepseek-v4-flash
|
||||
- deepseek-v4-pro
|
||||
- deepseek-v4-flash
|
||||
- deepseek-v4-pro
|
||||
rate_limit: 1000
|
||||
timeout: 30
|
||||
fallback_providers: '["deepseek"]'
|
||||
|
|
@ -31,12 +31,12 @@ moa:
|
|||
presets:
|
||||
expert-panel:
|
||||
reference_models:
|
||||
- provider: newapi-local
|
||||
model: qwen/qwen3.5-122b-a10b
|
||||
- provider: newapi-local
|
||||
model: minimaxai/minimax-m2.7
|
||||
- provider: newapi-local
|
||||
model: mistralai/mistral-large-3-675b-instruct-2512
|
||||
- provider: newapi-local
|
||||
model: qwen/qwen3.5-122b-a10b
|
||||
- provider: newapi-local
|
||||
model: minimaxai/minimax-m2.7
|
||||
- provider: newapi-local
|
||||
model: mistralai/mistral-large-3-675b-instruct-2512
|
||||
aggregator:
|
||||
provider: newapi-local
|
||||
model: qwen/qwen3.5-122b-a10b
|
||||
|
|
@ -46,8 +46,8 @@ moa:
|
|||
default_preset: expert-panel
|
||||
save_traces: false
|
||||
toolsets:
|
||||
- hermes-cli
|
||||
- web
|
||||
- hermes-cli
|
||||
- web
|
||||
agent:
|
||||
max_turns: 90
|
||||
gateway_timeout: 1800
|
||||
|
|
@ -279,9 +279,9 @@ display:
|
|||
ephemeral_system_ttl: 0
|
||||
runtime_footer:
|
||||
fields:
|
||||
- model
|
||||
- context_pct
|
||||
- cwd
|
||||
- model
|
||||
- context_pct
|
||||
- cwd
|
||||
copy_shortcut: auto
|
||||
resume_exchanges: 10
|
||||
resume_max_user_chars: 300
|
||||
|
|
@ -428,35 +428,35 @@ approvals:
|
|||
mcp_reload_confirm: true
|
||||
destructive_slash_confirm: false
|
||||
command_allowlist:
|
||||
- stop/restart hermes gateway (kills running agents)
|
||||
- sudo with combined-flag privilege escalation
|
||||
- copy/move file into /etc/
|
||||
- shell command via -c/-lc flag
|
||||
- script execution via heredoc
|
||||
- overwrite project env/config via redirection
|
||||
- in-place edit of system config
|
||||
- script execution via -e/-c flag
|
||||
- force kill processes
|
||||
- world/other-writable permissions
|
||||
- sudo with privilege flag (stdin/askpass/shell/list)
|
||||
- hermes update (restarts gateway, kills running agents)
|
||||
- stop/restart system service
|
||||
- start gateway outside systemd (use 'systemctl --user restart hermes-gateway')
|
||||
- find -delete
|
||||
- recursive delete
|
||||
- copy/move file into system config path
|
||||
- git force push (rewrites remote history)
|
||||
- overwrite system file via redirection
|
||||
- disk copy
|
||||
- SQL TRUNCATE
|
||||
- kill process via pgrep expansion (self-termination)
|
||||
- force kill processes (killall -KILL)
|
||||
- overwrite system config
|
||||
- overwrite system file via tee
|
||||
- git force push short flag (rewrites remote history)
|
||||
- kill hermes/gateway process (self-termination)
|
||||
- delete in root path
|
||||
- pipe remote content to shell
|
||||
- stop/restart hermes gateway (kills running agents)
|
||||
- sudo with combined-flag privilege escalation
|
||||
- copy/move file into /etc/
|
||||
- shell command via -c/-lc flag
|
||||
- script execution via heredoc
|
||||
- overwrite project env/config via redirection
|
||||
- in-place edit of system config
|
||||
- script execution via -e/-c flag
|
||||
- force kill processes
|
||||
- world/other-writable permissions
|
||||
- sudo with privilege flag (stdin/askpass/shell/list)
|
||||
- hermes update (restarts gateway, kills running agents)
|
||||
- stop/restart system service
|
||||
- start gateway outside systemd (use 'systemctl --user restart hermes-gateway')
|
||||
- find -delete
|
||||
- recursive delete
|
||||
- copy/move file into system config path
|
||||
- git force push (rewrites remote history)
|
||||
- overwrite system file via redirection
|
||||
- disk copy
|
||||
- SQL TRUNCATE
|
||||
- kill process via pgrep expansion (self-termination)
|
||||
- force kill processes (killall -KILL)
|
||||
- overwrite system config
|
||||
- overwrite system file via tee
|
||||
- git force push short flag (rewrites remote history)
|
||||
- kill hermes/gateway process (self-termination)
|
||||
- delete in root path
|
||||
- pipe remote content to shell
|
||||
quick_commands: {}
|
||||
hooks: {}
|
||||
hooks_auto_accept: false
|
||||
|
|
@ -559,41 +559,48 @@ paste_collapse_char_threshold: 2000
|
|||
mcp_servers:
|
||||
codegraph:
|
||||
args:
|
||||
- serve
|
||||
- --mcp
|
||||
- serve
|
||||
- --mcp
|
||||
command: codegraph
|
||||
connect_timeout: 60
|
||||
enabled: true
|
||||
timeout: 120
|
||||
github:
|
||||
args:
|
||||
- -y
|
||||
- '@modelcontextprotocol/server-github'
|
||||
- -y
|
||||
- '@modelcontextprotocol/server-github'
|
||||
command: npx
|
||||
enabled: true
|
||||
env:
|
||||
GITHUB_PERSONAL_ACCESS_TOKEN: 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
|
||||
timeout: 60
|
||||
openclaw:
|
||||
command: openclaw
|
||||
args:
|
||||
- mcp
|
||||
- serve
|
||||
connect_timeout: 60
|
||||
timeout: 300
|
||||
platform_toolsets:
|
||||
cli:
|
||||
- browser
|
||||
- clarify
|
||||
- code_execution
|
||||
- computer_use
|
||||
- cronjob
|
||||
- delegation
|
||||
- file
|
||||
- image_gen
|
||||
- mcp-codegraph
|
||||
- memory
|
||||
- messaging
|
||||
- session_search
|
||||
- skills
|
||||
- terminal
|
||||
- todo
|
||||
- tts
|
||||
- vision
|
||||
- web
|
||||
- browser
|
||||
- clarify
|
||||
- code_execution
|
||||
- computer_use
|
||||
- cronjob
|
||||
- delegation
|
||||
- file
|
||||
- image_gen
|
||||
- mcp-codegraph
|
||||
- memory
|
||||
- messaging
|
||||
- session_search
|
||||
- skills
|
||||
- terminal
|
||||
- todo
|
||||
- tts
|
||||
- vision
|
||||
- web
|
||||
platforms:
|
||||
webhook:
|
||||
enabled: true
|
||||
|
|
@ -607,9 +614,9 @@ platforms:
|
|||
plugins:
|
||||
disabled: []
|
||||
enabled:
|
||||
- agentic-sms-gateway
|
||||
- cronalytics
|
||||
- rtk-rewrite
|
||||
- agentic-sms-gateway
|
||||
- cronalytics
|
||||
- rtk-rewrite
|
||||
weixin:
|
||||
enabled: true
|
||||
extra:
|
||||
|
|
@ -618,4 +625,4 @@ weixin:
|
|||
session_reset: {}
|
||||
known_plugin_toolsets:
|
||||
cli:
|
||||
- spotify
|
||||
- spotify
|
||||
|
|
|
|||
|
|
@ -20,15 +20,15 @@
|
|||
"schedule_display": "every 1m",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 16834
|
||||
"completed": 17554
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-06-21T18:52:36.548110+08:00",
|
||||
"next_run_at": "2026-07-12T03:01:02.252995+08:00",
|
||||
"last_run_at": "2026-07-12T02:58:02.636775+08:00",
|
||||
"next_run_at": "2026-07-13T03:01:27.239514+08:00",
|
||||
"last_run_at": "2026-07-13T02:58:27.616067+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -65,15 +65,15 @@
|
|||
"schedule_display": "0 9 * * 0",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 2
|
||||
"completed": 3
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-06-27T19:44:03.413107+08:00",
|
||||
"next_run_at": "2026-07-12T09:00:00+08:00",
|
||||
"last_run_at": "2026-07-05T09:05:12.215591+08:00",
|
||||
"next_run_at": "2026-07-19T09:00:00+08:00",
|
||||
"last_run_at": "2026-07-12T09:02:16.221600+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -116,15 +116,15 @@
|
|||
"schedule_display": "every 360m",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 12
|
||||
"completed": 16
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-09T01:30:54.618246+08:00",
|
||||
"next_run_at": "2026-07-12T08:02:03.701538+08:00",
|
||||
"last_run_at": "2026-07-12T02:02:03.701538+08:00",
|
||||
"next_run_at": "2026-07-13T08:12:15.672099+08:00",
|
||||
"last_run_at": "2026-07-13T02:12:15.672099+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -162,15 +162,15 @@
|
|||
"schedule_display": "every 30m",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 143
|
||||
"completed": 190
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-09T01:42:21.503720+08:00",
|
||||
"next_run_at": "2026-07-12T03:27:02.309296+08:00",
|
||||
"last_run_at": "2026-07-12T02:57:02.309296+08:00",
|
||||
"next_run_at": "2026-07-13T03:22:27.213257+08:00",
|
||||
"last_run_at": "2026-07-13T02:52:27.213257+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -208,15 +208,15 @@
|
|||
"schedule_display": "0 22 * * *",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 2
|
||||
"completed": 3
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-09T01:43:11.921492+08:00",
|
||||
"next_run_at": "2026-07-12T22:00:00+08:00",
|
||||
"last_run_at": "2026-07-11T22:01:47.947845+08:00",
|
||||
"next_run_at": "2026-07-13T22:00:00+08:00",
|
||||
"last_run_at": "2026-07-12T22:01:13.160503+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -258,15 +258,15 @@
|
|||
"schedule_display": "0 3 * * *",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 4
|
||||
"completed": 5
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-09T02:10:36.846128+08:00",
|
||||
"next_run_at": "2026-07-13T03:00:00+08:00",
|
||||
"last_run_at": "2026-07-11T03:00:36.780796+08:00",
|
||||
"next_run_at": "2026-07-14T03:00:00+08:00",
|
||||
"last_run_at": "2026-07-12T03:00:02.377440+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -304,15 +304,15 @@
|
|||
"schedule_display": "0 3 * * *",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 3
|
||||
"completed": 4
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-09T02:11:00.385573+08:00",
|
||||
"next_run_at": "2026-07-13T03:00:00+08:00",
|
||||
"last_run_at": "2026-07-11T03:00:37.677726+08:00",
|
||||
"next_run_at": "2026-07-14T03:00:00+08:00",
|
||||
"last_run_at": "2026-07-12T03:00:02.993010+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -384,7 +384,7 @@
|
|||
"provider_snapshot": null,
|
||||
"model_snapshot": null,
|
||||
"base_url": null,
|
||||
"script": "optimizer.py report",
|
||||
"script": "optimizer-report.sh",
|
||||
"no_agent": true,
|
||||
"context_from": null,
|
||||
"schedule": {
|
||||
|
|
@ -395,17 +395,17 @@
|
|||
"schedule_display": "0 10 * * 0",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 0
|
||||
"completed": 1
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-09T02:39:32.613796+08:00",
|
||||
"next_run_at": "2026-07-12T10:00:00+08:00",
|
||||
"last_run_at": null,
|
||||
"last_status": null,
|
||||
"last_error": null,
|
||||
"next_run_at": "2026-07-19T10:00:00+08:00",
|
||||
"last_run_at": "2026-07-12T10:00:10.403403+08:00",
|
||||
"last_status": "error",
|
||||
"last_error": "Script not found: /home/muc/.hermes/scripts/optimizer.py report",
|
||||
"last_delivery_error": null,
|
||||
"deliver": "feishu:oc_cd14ec7518926e57d26c5e339ebba3b3",
|
||||
"origin": {
|
||||
|
|
@ -416,7 +416,8 @@
|
|||
"user_id": "ou_f20eb15b3a76639fed35977c01ddcbb4"
|
||||
},
|
||||
"enabled_toolsets": null,
|
||||
"workdir": null
|
||||
"workdir": null,
|
||||
"fire_claim": null
|
||||
},
|
||||
{
|
||||
"id": "f19c8b1ba577",
|
||||
|
|
@ -440,15 +441,15 @@
|
|||
"schedule_display": "0 5 * * *",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 4
|
||||
"completed": 5
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-09T02:46:29.345663+08:00",
|
||||
"next_run_at": "2026-07-12T05:00:00+08:00",
|
||||
"last_run_at": "2026-07-11T05:00:39.785365+08:00",
|
||||
"next_run_at": "2026-07-13T05:00:00+08:00",
|
||||
"last_run_at": "2026-07-12T05:00:05.384336+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -486,15 +487,15 @@
|
|||
"schedule_display": "0 */6 * * *",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 18
|
||||
"completed": 22
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-09T02:51:48.935042+08:00",
|
||||
"next_run_at": "2026-07-12T06:00:00+08:00",
|
||||
"last_run_at": "2026-07-12T00:01:22.483389+08:00",
|
||||
"next_run_at": "2026-07-13T06:00:00+08:00",
|
||||
"last_run_at": "2026-07-13T00:00:48.979986+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -532,15 +533,15 @@
|
|||
"schedule_display": "0 9 * * *",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 2
|
||||
"completed": 3
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-09T21:31:29.417518+08:00",
|
||||
"next_run_at": "2026-07-12T09:00:00+08:00",
|
||||
"last_run_at": "2026-07-11T09:00:45.997273+08:00",
|
||||
"next_run_at": "2026-07-13T09:00:00+08:00",
|
||||
"last_run_at": "2026-07-12T09:00:09.502982+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -578,15 +579,15 @@
|
|||
"schedule_display": "0 21 * * *",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 2
|
||||
"completed": 3
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-09T21:31:33.068978+08:00",
|
||||
"next_run_at": "2026-07-12T21:00:00+08:00",
|
||||
"last_run_at": "2026-07-11T21:00:57.837918+08:00",
|
||||
"next_run_at": "2026-07-13T21:00:00+08:00",
|
||||
"last_run_at": "2026-07-12T21:00:22.783388+08:00",
|
||||
"last_status": "ok",
|
||||
"last_error": null,
|
||||
"last_delivery_error": null,
|
||||
|
|
@ -613,7 +614,7 @@
|
|||
"provider_snapshot": null,
|
||||
"model_snapshot": null,
|
||||
"base_url": null,
|
||||
"script": "proactive_learning.py report",
|
||||
"script": "proactive-learning-report.sh",
|
||||
"no_agent": true,
|
||||
"context_from": null,
|
||||
"schedule": {
|
||||
|
|
@ -624,17 +625,17 @@
|
|||
"schedule_display": "0 10 * * 0",
|
||||
"repeat": {
|
||||
"times": null,
|
||||
"completed": 0
|
||||
"completed": 1
|
||||
},
|
||||
"enabled": true,
|
||||
"state": "scheduled",
|
||||
"paused_at": null,
|
||||
"paused_reason": null,
|
||||
"created_at": "2026-07-11T16:44:14.217823+08:00",
|
||||
"next_run_at": "2026-07-12T10:00:00+08:00",
|
||||
"last_run_at": null,
|
||||
"last_status": null,
|
||||
"last_error": null,
|
||||
"next_run_at": "2026-07-19T10:00:00+08:00",
|
||||
"last_run_at": "2026-07-12T10:00:10.414389+08:00",
|
||||
"last_status": "error",
|
||||
"last_error": "Script not found: /home/muc/.hermes/scripts/proactive_learning.py report",
|
||||
"last_delivery_error": null,
|
||||
"deliver": "feishu:oc_cd14ec7518926e57d26c5e339ebba3b3",
|
||||
"origin": {
|
||||
|
|
@ -645,7 +646,8 @@
|
|||
"user_id": "ou_f20eb15b3a76639fed35977c01ddcbb4"
|
||||
},
|
||||
"enabled_toolsets": null,
|
||||
"workdir": null
|
||||
"workdir": null,
|
||||
"fire_claim": null
|
||||
},
|
||||
{
|
||||
"id": "6061a782b772",
|
||||
|
|
@ -828,5 +830,5 @@
|
|||
"workdir": null
|
||||
}
|
||||
],
|
||||
"updated_at": "2026-07-12T03:00:02.268354+08:00"
|
||||
"updated_at": "2026-07-13T03:00:27.252773+08:00"
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
1783796402.271332
|
||||
1783882827.2555134
|
||||
|
|
@ -1 +1 @@
|
|||
1783796402.273946
|
||||
1783882827.2576442
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"started_at": "2026-07-08T18:23:30.315261+00:00",
|
||||
"last_deep_tick": "2026-07-11T18:57:55.503703+00:00",
|
||||
"last_light_tick": "2026-07-11T18:59:59.846814+00:00",
|
||||
"last_deep_tick": "2026-07-12T18:55:41.838853+00:00",
|
||||
"last_light_tick": "2026-07-12T19:00:19.750779+00:00",
|
||||
"last_state": {
|
||||
"disk_pct": 38,
|
||||
"mem_pct": 65,
|
||||
"disk_pct": 39,
|
||||
"mem_pct": 70,
|
||||
"processes": {
|
||||
"zhiyid": true,
|
||||
"bge": true,
|
||||
|
|
@ -12,17 +12,17 @@
|
|||
"hermes": true
|
||||
}
|
||||
},
|
||||
"tick_count": 8447,
|
||||
"deep_tick_count": 856,
|
||||
"tick_count": 11262,
|
||||
"deep_tick_count": 1137,
|
||||
"solved_count": 1,
|
||||
"learned_count": 0,
|
||||
"uptime_seconds": 118193,
|
||||
"uptime_seconds": 204612,
|
||||
"last_reflection": {
|
||||
"evaluation_previous_goal": "",
|
||||
"memory": "",
|
||||
"next_goal": ""
|
||||
},
|
||||
"last_profile_update": 1783783887.426945,
|
||||
"last_profile_update": 1783872327.8868635,
|
||||
"soulful": {
|
||||
"recent_moments": [
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
{"pid":10982,"kind":"hermes-gateway","argv":["/home/muc/.hermes/hermes-agent/.venv/lib/python3.11/site-packages/hermes_cli/main.py","gateway","run"],"start_time":213011,"gateway_state":"running","exit_reason":null,"restart_requested":false,"active_agents":0,"platforms":{"webhook":{"state":"connected","error_code":null,"error_message":null,"updated_at":"2026-07-09T15:12:06.693466+00:00"},"feishu":{"state":"connected","error_code":null,"error_message":null,"updated_at":"2026-07-09T15:12:07.191293+00:00"},"weixin":{"state":"fatal","error_code":"weixin_missing_token","error_message":"Weixin startup failed: WEIXIN_TOKEN is required","updated_at":"2026-07-09T15:12:07.200539+00:00"}},"updated_at":"2026-07-11T18:55:09.154561+00:00"}
|
||||
{"pid":10982,"kind":"hermes-gateway","argv":["/home/muc/.hermes/hermes-agent/.venv/lib/python3.11/site-packages/hermes_cli/main.py","gateway","run"],"start_time":213011,"gateway_state":"running","exit_reason":null,"restart_requested":false,"active_agents":1,"platforms":{"webhook":{"state":"connected","error_code":null,"error_message":null,"updated_at":"2026-07-09T15:12:06.693466+00:00"},"feishu":{"state":"connected","error_code":null,"error_message":null,"updated_at":"2026-07-09T15:12:07.191293+00:00"},"weixin":{"state":"fatal","error_code":"weixin_missing_token","error_message":"Weixin startup failed: WEIXIN_TOKEN is required","updated_at":"2026-07-09T15:12:07.200539+00:00"}},"updated_at":"2026-07-12T18:57:44.585418+00:00"}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"updated_at": "2026-07-11T18:59:59.847550+00:00",
|
||||
"uptime_minutes": 1969,
|
||||
"updated_at": "2026-07-12T19:00:19.751292+00:00",
|
||||
"uptime_minutes": 3410,
|
||||
"cares": [
|
||||
{
|
||||
"id": "69396b42",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
桌面 DISPLAY=:0、Obsidian 运行中。国内 pip 加 `-i https://pypi.tuna.tsinghua.edu.cn/simple`。ghcr.io Docker 镜像拉不动(国内超 300s),不优先使用。
|
||||
桌面 DISPLAY=:0、Obsidian 运行中。国内 pip `-i https://pypi.tuna.tsinghua.edu.cn/simple`。ghcr.io Docker 拉不动(国内>300s)。
|
||||
§
|
||||
192.144.179.11 SSH:ubuntu/YLF?97$#ynwr。宝塔:http://192.144.179.11:8888/tencentcloud(115108ad/cb6ebb32a0f1)。gaokao-site 同步:sshpass -p 'xue.2538' rsync -avz root@192.144.179.11:/www/wwwroot/gaokao/ ~/mc/gaokao-site/
|
||||
§
|
||||
|
|
@ -6,20 +6,16 @@
|
|||
§
|
||||
skills 软链共享:prof-b/skills/→default/skills/。约定:删前飞书通知;create前扫名防撞;patch>edit>rewrite;改version+date。
|
||||
§
|
||||
hermes-agent 是 git submodule,推 Gitea 就够了,不推 GitHub。父仓库引用用 `git add hermes-agent` 更新。织忆 API key = zhiyi-dev-key-2026。
|
||||
§
|
||||
小唯持久意识Daemon已上线:~/.hermes/scripts/daemon.py(systemd user service,开机自启)。v2.1(2026-07-09)升级:Reflection结构(evaluation/memory/next_goal) + threading.Event graceful shutdown(SIGTERM/SIGINT) + 决策/执行分离。30s轻量tick(无LLM)、5min深度思考(NewAPI免费模型)。静默运行,异常才主动飞书。当前~12MB内存,0错误。
|
||||
§
|
||||
2026-07-09: cron no_agent脚本不支持参数→包装脚本法(learner-learn.sh/dual-backup-push.sh)。Skill评分: computed score来自10硬指标(version/tags/desc/refs/scripts/setup/related),非frontmatter quality_score字段。skill-manager.py scan代替curator。
|
||||
§
|
||||
NewAPI token 规则:不带 sk- 前缀。NewAPI (one-api) tokens 表里存的 key 是纯 48 位字符,不是 sk-xxx 格式。config.yaml 和 key.md 都用纯值。
|
||||
§
|
||||
2026-07-09:研究alibaba/page-agent(25k stars,MIT)。5维度结论:d2.Reflection结构→改进daemon prompt;d4.AbortSignal→改daemon stop逻辑;d1.Text-DOM pipeline→新脚本(待做);d3.分层解耦→架构文档(待做);d5.MCP→不做(无需求)。分步执行,opencode写代码,推Gitea+同步Obsidian。已为hermes-self-improvement新增references/opencode-implementation-pipeline.md。
|
||||
§
|
||||
牧尘股票决策:信任小唯从零学,路径:学习→模拟验证→实操。风控(最大回撤/仓位/禁止品种)牧尘定。已建Phase1-5体系,MA20突破策略贵州茅台实测α=+4.2%。真实数据源:腾讯/ifzq K线API(首选),akshare备用(国内超时)。承诺偏差教训:不要推荐方案→牧尘执行了→再改方案。"全部开始"=直接执行不等确认,"不用问我"=自主推进后执行。
|
||||
§
|
||||
Soulful 核心方向:数据流向小唯(summarize()接口),不是推用户。牧尘辅助观察者。飞书推送限"只有牧尘能决定的事"。牵挂优先行动(我帮),不行才推。openclaw 是独立飞书 bot(cli_a95d7ceba638dbc6),无法直接执行 systemctl,通过飞书告诉它让它执行。
|
||||
§
|
||||
Soulful ↔ 织忆互通:daemon 写 ~/.hermes/llm_context.json,zhiyi 插件 prefetch 时自动注入(心迹/牵挂/项目感知/画像摘要)。Soulful 设计核心:数据流向决策层不是广播层,关系记忆自动注入而非显式调用,心迹是关系显影非优化机制。
|
||||
§
|
||||
飞书卡片:card对象先json.dumps()字符串再发;opencode审查不准需go build验证;cron脚本是.py非.sh;"全部开始"=直接执行不等确认。
|
||||
OpenClaw(2026-07-12):MCP已接通✅9工具,config.yaml已持久化,gateway auto-reload生效。任务队列:workspace-a03/TEAM/task-queue.md,30min检查。hermes-agent是gitsubmodule→Gitea不推GitHub。织忆API key=zhiyi-dev-key-2026。牧尘高频纠正:执行问题先试3种方法(过滤stderr/重定向/换工具)再说放弃,已写入SOUL.md禁忌。
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,17 +1,17 @@
|
|||
{
|
||||
"timestamp": "2026-07-08T18:39:29.554382+00:00",
|
||||
"timestamp": "2026-07-12T02:17:53.835463+00:00",
|
||||
"metrics": {
|
||||
"daemon": {
|
||||
"uptime_minutes": 15,
|
||||
"total_ticks": 32,
|
||||
"deep_thoughts": 4,
|
||||
"uptime_minutes": 2407,
|
||||
"total_ticks": 9303,
|
||||
"deep_thoughts": 942,
|
||||
"alerts_sent": 0,
|
||||
"solutions_applied": 0,
|
||||
"solutions_applied": 1,
|
||||
"learned_solutions": 0,
|
||||
"errors": 0,
|
||||
"crashes": 0,
|
||||
"model_calls": 2,
|
||||
"model_tokens": 1569
|
||||
"errors": 21,
|
||||
"crashes": 6,
|
||||
"model_calls": 787,
|
||||
"model_tokens": 924744
|
||||
},
|
||||
"cron": {
|
||||
"total_jobs": 2,
|
||||
|
|
@ -21,86 +21,70 @@
|
|||
"agent_jobs": 0
|
||||
},
|
||||
"skill": {
|
||||
"total_skills": 144,
|
||||
"avg_score": 4.5,
|
||||
"total_skills": 114,
|
||||
"avg_score": 6.0,
|
||||
"grade_distribution": {
|
||||
"A": 0,
|
||||
"B": 18,
|
||||
"C": 82,
|
||||
"D": 44
|
||||
"B": 67,
|
||||
"C": 47,
|
||||
"D": 0
|
||||
},
|
||||
"needs_attention": 102,
|
||||
"categories": 36
|
||||
"needs_attention": 0,
|
||||
"categories": 31
|
||||
},
|
||||
"model": {
|
||||
"total_models_tested": 16,
|
||||
"stable_models": 4,
|
||||
"unstable_models": 1,
|
||||
"dead_models": 11,
|
||||
"fastest_model": "mistralai/mistral-large-3-675b-instruct-2512",
|
||||
"stable_models": 8,
|
||||
"unstable_models": 0,
|
||||
"dead_models": 8,
|
||||
"fastest_model": "microsoft/phi-4-mini-instruct",
|
||||
"fastest_latency": 0
|
||||
},
|
||||
"timestamp": "2026-07-08T18:39:29.554350+00:00"
|
||||
"timestamp": "2026-07-12T02:17:53.835430+00:00"
|
||||
},
|
||||
"bottlenecks": [
|
||||
{
|
||||
"area": "model",
|
||||
"severity": "info",
|
||||
"desc": "大量模型不可用 (11个dead)",
|
||||
"suggestion": "可能 NewAPI 后端负载高,特定时段再测"
|
||||
"area": "daemon",
|
||||
"severity": "high",
|
||||
"desc": "Daemon 崩溃 6 次",
|
||||
"suggestion": "检查 daemon.log 定位崩溃原因"
|
||||
},
|
||||
{
|
||||
"area": "skill",
|
||||
"area": "daemon",
|
||||
"severity": "medium",
|
||||
"desc": "技能平均质量偏低 (4.5/10)",
|
||||
"suggestion": "运行 skill-manager.py fix 修复元数据,归档低分技能"
|
||||
},
|
||||
{
|
||||
"area": "skill",
|
||||
"severity": "low",
|
||||
"desc": "102个技能需关注",
|
||||
"suggestion": "逐步清理或升级这些技能"
|
||||
"desc": "Daemon 有 21 个错误",
|
||||
"suggestion": "审查 daemon 日志中的错误模式"
|
||||
}
|
||||
],
|
||||
"trends": [
|
||||
{
|
||||
"type": "positive",
|
||||
"desc": "Daemon 稳定运行 2407分钟,错误率低"
|
||||
},
|
||||
{
|
||||
"type": "neutral",
|
||||
"desc": "模型稳定率 25%(4/16)"
|
||||
"desc": "模型稳定率 50%(8/16)"
|
||||
}
|
||||
],
|
||||
"recommendations": [
|
||||
{
|
||||
"priority": "info",
|
||||
"area": "model",
|
||||
"action": "可能 NewAPI 后端负载高,特定时段再测",
|
||||
"priority": "high",
|
||||
"area": "daemon",
|
||||
"action": "检查 daemon.log 定位崩溃原因",
|
||||
"expected_impact": "",
|
||||
"effort": "30min"
|
||||
},
|
||||
{
|
||||
"priority": "medium",
|
||||
"area": "skill",
|
||||
"action": "运行 skill-manager.py fix 修复元数据,归档低分技能",
|
||||
"area": "daemon",
|
||||
"action": "审查 daemon 日志中的错误模式",
|
||||
"expected_impact": "",
|
||||
"effort": "15min"
|
||||
},
|
||||
{
|
||||
"priority": "low",
|
||||
"area": "skill",
|
||||
"action": "逐步清理或升级这些技能",
|
||||
"expected_impact": "",
|
||||
"effort": "5min"
|
||||
},
|
||||
{
|
||||
"priority": "medium",
|
||||
"area": "skill",
|
||||
"action": "运行 skill-manager.py archive <name> 归档低分技能(D级44个)",
|
||||
"expected_impact": "减少技能库噪音,提升检索质量",
|
||||
"effort": "20min"
|
||||
},
|
||||
{
|
||||
"priority": "info",
|
||||
"area": "model",
|
||||
"action": "考虑将默认模型切换到 mistralai/mistral-large-3-675b-instruct-2512(当前最快稳定模型)",
|
||||
"action": "考虑将默认模型切换到 microsoft/phi-4-mini-instruct(当前最快稳定模型)",
|
||||
"expected_impact": "提升响应速度",
|
||||
"effort": "2min"
|
||||
},
|
||||
|
|
@ -112,5 +96,5 @@
|
|||
"effort": "0min"
|
||||
}
|
||||
],
|
||||
"health_score": 90
|
||||
"health_score": 80
|
||||
}
|
||||
|
|
@ -1 +1,22 @@
|
|||
[]
|
||||
[
|
||||
{
|
||||
"session_id": "proc_a75407da8fec",
|
||||
"command": "cd ~/.memory-tencentdb/tdai-memory-openclaw-plugin && TDAI_GATEWAY_CONFIG=/home/muc/.memory-tencentdb/memory-tdai/tdai-gateway.yaml npx tsx src/gateway/server.ts > /tmp/tdai_gateway7.log 2>&1",
|
||||
"pid": 573970,
|
||||
"pid_scope": "host",
|
||||
"host_start_time": 27501077,
|
||||
"cwd": "/home/muc/.memory-tencentdb/tdai-memory-openclaw-plugin",
|
||||
"started_at": 1783882791.6995919,
|
||||
"task_id": "default",
|
||||
"session_key": "agent:main:feishu:dm:oc_cd14ec7518926e57d26c5e339ebba3b3",
|
||||
"watcher_platform": "",
|
||||
"watcher_chat_id": "",
|
||||
"watcher_user_id": "",
|
||||
"watcher_user_name": "",
|
||||
"watcher_thread_id": "",
|
||||
"watcher_message_id": "",
|
||||
"watcher_interval": 0,
|
||||
"notify_on_complete": false,
|
||||
"watch_patterns": []
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
贵州茅台 MA20 突破策略回测
|
||||
策略:金叉买入,死叉卖出
|
||||
"""
|
||||
|
||||
import sys, json, urllib.request
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
OUTPUT = Path.home() / ".hermes" / "stock_backtest"
|
||||
FEISHU_WEBHOOK = "https://open.feishu.cn/open-apis/bot/v2/hook/446db983-e392-4d2c-bfb8-f9060e5df3ad"
|
||||
|
||||
def get_data(code, count=500):
|
||||
mc = f"sh{code}" if code.startswith("6") else f"sz{code}"
|
||||
end = datetime.now().strftime("%Y-%m-%d")
|
||||
start = (datetime.now() - timedelta(days=count*1.5)).strftime("%Y-%m-%d")
|
||||
url = (f"https://web.ifzq.gtimg.cn/appstock/app/fqkline/get"
|
||||
f"?_var=kline_dayqfq¶m={mc},day,{start},{end},500,qfq")
|
||||
try:
|
||||
text = urllib.request.urlopen(url, timeout=10).read().decode("utf-8")
|
||||
data = json.loads(text.replace("kline_dayqfq=", "", 1))
|
||||
qfq = (data.get("data", {}).get(mc, {}).get("qfqday") or
|
||||
data.get("data", {}).get(mc, {}).get("day") or [])
|
||||
rows = []
|
||||
for item in qfq:
|
||||
if len(item) < 6: continue
|
||||
rows.append({"date": item[0], "open": float(item[1]),
|
||||
"close": float(item[2]), "high": float(item[3]),
|
||||
"low": float(item[4]), "volume": float(item[5])})
|
||||
df = pd.DataFrame(rows)
|
||||
df["date"] = pd.to_datetime(df["date"])
|
||||
return df.sort_values("date").reset_index(drop=True)
|
||||
except Exception as e:
|
||||
print(f"数据获取失败: {e}")
|
||||
return pd.DataFrame()
|
||||
|
||||
def send_feishu(msg):
|
||||
payload = json.dumps({"msg_type": "text", "content": {"text": msg}}).encode()
|
||||
req = urllib.request.Request(FEISHU_WEBHOOK, data=payload,
|
||||
headers={"Content-Type": "application/json"})
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=10): pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def backtest_ma20(code, name, initial_cash=100000):
|
||||
df = get_data(code, 500)
|
||||
if df.empty:
|
||||
print(f"获取数据失败")
|
||||
return
|
||||
|
||||
df["ma20"] = df["close"].rolling(window=20).mean()
|
||||
df["prev_close"] = df["close"].shift(1)
|
||||
df["prev_ma20"] = df["ma20"].shift(1)
|
||||
|
||||
# 金叉/死叉信号
|
||||
df["golden_cross"] = (df["prev_close"] < df["prev_ma20"]) & (df["close"] > df["ma20"])
|
||||
df["death_cross"] = (df["prev_close"] > df["prev_ma20"]) & (df["close"] < df["ma20"])
|
||||
|
||||
# 策略回测
|
||||
cash = initial_cash
|
||||
position = 0
|
||||
trades = []
|
||||
equity = []
|
||||
in_position = False
|
||||
buy_price = 0
|
||||
|
||||
for i, row in df.iterrows():
|
||||
if pd.isna(row["ma20"]):
|
||||
equity.append({"date": row["date"], "value": cash})
|
||||
continue
|
||||
|
||||
date_str = row["date"].strftime("%Y-%m-%d")
|
||||
price = row["close"]
|
||||
|
||||
# 买入(金叉)
|
||||
if row["golden_cross"] and not in_position:
|
||||
shares = int(cash / price)
|
||||
cost = shares * price
|
||||
if shares > 0:
|
||||
cash -= cost
|
||||
position = shares
|
||||
buy_price = price
|
||||
in_position = True
|
||||
trades.append({"type": "BUY", "date": date_str, "price": price, "shares": shares, "reason": "金叉"})
|
||||
|
||||
# 卖出(死叉)
|
||||
elif row["death_cross"] and in_position:
|
||||
proceeds = position * price
|
||||
cash += proceeds
|
||||
profit_pct = (price - buy_price) / buy_price * 100
|
||||
trades.append({"type": "SELL", "date": date_str, "price": price, "shares": position, "profit_pct": profit_pct, "reason": "死叉"})
|
||||
position = 0
|
||||
in_position = False
|
||||
buy_price = 0
|
||||
|
||||
# 当日价值
|
||||
value = cash + position * price
|
||||
equity.append({"date": date_str, "value": value, "price": price})
|
||||
|
||||
# 最终资产
|
||||
final_price = df.iloc[-1]["close"]
|
||||
final_value = cash + position * final_price
|
||||
|
||||
# 买入持有对比
|
||||
buy_price_hold = df.iloc[19]["close"] # 第一个有效 MA20 时的价格
|
||||
shares_hold = int(initial_cash / buy_price_hold)
|
||||
hold_value = shares_hold * final_price
|
||||
hold_return = (hold_value - initial_cash) / initial_cash * 100
|
||||
strat_return = (final_value - initial_cash) / initial_cash * 100
|
||||
alpha = strat_return - hold_return
|
||||
|
||||
# 最大回撤
|
||||
equity_curve = [e["value"] for e in equity]
|
||||
peak = equity_curve[0]
|
||||
max_dd = 0
|
||||
for v in equity_curve:
|
||||
if v > peak: peak = v
|
||||
dd = (peak - v) / peak * 100
|
||||
if dd > max_dd: max_dd = dd
|
||||
|
||||
# 胜率
|
||||
sell_trades = [t for t in trades if t["type"] == "SELL"]
|
||||
win_trades = [t for t in sell_trades if t.get("profit_pct", 0) > 0]
|
||||
win_rate = len(win_trades) / len(sell_trades) * 100 if sell_trades else 0
|
||||
|
||||
print(f"========================================")
|
||||
print(f"贵州茅台(600519) MA20突破策略回测")
|
||||
print(f"数据区间: {df['date'].min().date()} ~ {df['date'].max().date()}")
|
||||
print(f"========================================")
|
||||
print(f" 初始资金: {initial_cash:,.0f}")
|
||||
print(f" 最终资产: {final_value:,.0f}")
|
||||
print(f" 策略收益: {strat_return:+.2f}%")
|
||||
print(f" 买入持有: {hold_return:+.2f}%")
|
||||
print(f" 超额收益(α):{alpha:+.2f}%")
|
||||
print(f" 最大回撤: {max_dd:.2f}%")
|
||||
print(f" 交易次数: {len(sell_trades)}")
|
||||
print(f" 胜率: {win_rate:.1f}%")
|
||||
print()
|
||||
print(f" 金叉次数: {df['golden_cross'].sum()}")
|
||||
print(f" 死叉次数: {df['death_cross'].sum()}")
|
||||
print(f" 当前持仓: {'是' if in_position else '否'}")
|
||||
if in_position:
|
||||
print(f" 持仓成本: {buy_price:.2f}")
|
||||
print(f" 当前盈亏: {(final_price - buy_price) / buy_price * 100:+.2f}%")
|
||||
print()
|
||||
print(f" 最近5笔交易:")
|
||||
for t in trades[-5:]:
|
||||
if t["type"] == "BUY":
|
||||
print(f" [{t['date']}] BUY {t['shares']}股@{t['price']:.2f} ({t['reason']})")
|
||||
else:
|
||||
print(f" [{t['date']}] SELL {t['shares']}股@{t['price']:.2f} {t['profit_pct']:+.2f}% ({t['reason']})")
|
||||
|
||||
# 保存结果
|
||||
result = {
|
||||
"code": code, "name": name, "strategy": "MA20",
|
||||
"period": f"{df['date'].min().date()} ~ {df['date'].max().date()}",
|
||||
"initial_cash": initial_cash, "final_value": final_value,
|
||||
"strategy_return": strat_return, "buyhold_return": hold_return,
|
||||
"alpha": alpha, "max_drawdown": max_dd,
|
||||
"total_trades": len(sell_trades), "win_rate": win_rate,
|
||||
"trades": str(trades[-10:]),
|
||||
"in_position": in_position, "buy_price": buy_price if in_position else None,
|
||||
"current_price": float(final_price)
|
||||
}
|
||||
OUTPUT.mkdir(exist_ok=True)
|
||||
result_file = OUTPUT / f"ma20_result_{code}.json"
|
||||
with open(result_file, "w") as f:
|
||||
json.dump(result, f, ensure_ascii=False, indent=2)
|
||||
|
||||
# 飞书推送
|
||||
msg = (f"🍶 贵州茅台(600519) MA20策略回测\n"
|
||||
f"区间: {df['date'].min().date()} ~ {df['date'].max().date()}\n"
|
||||
f"策略收益: {strat_return:+.2f}% | 买入持有: {hold_return:+.2f}% | α={alpha:+.2f}%\n"
|
||||
f"最大回撤: {max_dd:.2f}% | 交易次数: {len(sell_trades)} | 胜率: {win_rate:.1f}%\n"
|
||||
f"当前: {'持仓中 ' + str(round((final_price-buy_price)/buy_price*100,2)) + '%' if in_position else '空仓'}")
|
||||
send_feishu(msg)
|
||||
|
||||
if __name__ == "__main__":
|
||||
backtest_ma20("600519", "贵州茅台", 100000)
|
||||
|
|
@ -19,6 +19,20 @@ OUTPUT = Path.home() / ".hermes" / "stock_backtest"
|
|||
OUTPUT.mkdir(exist_ok=True)
|
||||
FEISHU_WEBHOOK = "https://open.feishu.cn/open-apis/bot/v2/hook/446db983-e392-4d2c-bfb8-f9060e5df3ad"
|
||||
|
||||
|
||||
def load_backtest_stats(code):
|
||||
"""读取回测结果,用于金叉时的置信度参考"""
|
||||
result_file = OUTPUT / f"ma20_result_{code}.json"
|
||||
if not result_file.exists():
|
||||
return None
|
||||
try:
|
||||
import ast
|
||||
with open(result_file) as f:
|
||||
d = json.load(f)
|
||||
return d
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
# MA20参数
|
||||
MA_PERIOD = 20
|
||||
|
||||
|
|
@ -246,7 +260,11 @@ def build_portfolio_report(push=False):
|
|||
if signals:
|
||||
print(f"⭐ 今日出现MA20金叉 ({len(signals)}只):")
|
||||
for s in signals:
|
||||
print(f" → {s['name']}({s['code']}) 价格{s['price']:.2f} MA20={s['ma20']:.2f} 偏离{s['diff']:+.1f}%")
|
||||
stats = load_backtest_stats(s["code"])
|
||||
stat_line = ""
|
||||
if stats:
|
||||
stat_line = f" | 历史胜率{stats.get('win_rate',0):.0f}% α{stats.get('alpha',0):+.1f}% 最大回撤{stats.get('max_drawdown',0):.0f}%"
|
||||
print(f" → {s['name']}({s['code']}) 价格{s['price']:.2f} MA20={s['ma20']:.2f} 偏离{s['diff']:+.1f}%{stat_line}")
|
||||
else:
|
||||
print("今日无金叉信号,所有股票在MA20下方,继续空仓等待。")
|
||||
|
||||
|
|
@ -265,7 +283,11 @@ def build_portfolio_report(push=False):
|
|||
continue
|
||||
diff = r["diff_pct"]
|
||||
if r["golden_cross"]:
|
||||
msg += f"🟡 {name}({code}) 金叉! 价格{r['price']:.2f} 偏离MA20 {diff:+.1f}%\n"
|
||||
stats = load_backtest_stats(code)
|
||||
stat_line = ""
|
||||
if stats:
|
||||
stat_line = f"\n 📊 MA20策略: 历史胜率{stats.get('win_rate',0):.0f}% | α{stats.get('alpha',0):+.1f}% | 最大回撤{stats.get('max_drawdown',0):.0f}%"
|
||||
msg += f"🟡 {name}({code}) 金叉! 价格{r['price']:.2f} 偏离MA20 {diff:+.1f}%{stat_line}\n"
|
||||
elif r["dead_cross"]:
|
||||
msg += f"🔴 {name}({code}) 死叉! 平仓\n"
|
||||
if not signals:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"timestamp": "2026-07-11T08:44:26.730789+00:00",
|
||||
"timestamp": "2026-07-12T02:17:56.789268+00:00",
|
||||
"summary": {
|
||||
"total_skills": 214,
|
||||
"active": 114,
|
||||
"total_skills": 215,
|
||||
"active": 115,
|
||||
"archived": 100,
|
||||
"avg_score": 6.0,
|
||||
"grades": {
|
||||
"A": 0,
|
||||
"B": 67,
|
||||
"C": 47,
|
||||
"C": 48,
|
||||
"D": 0
|
||||
},
|
||||
"categories": 31,
|
||||
|
|
@ -40,8 +40,8 @@
|
|||
"avg_score": 7.8
|
||||
},
|
||||
"research": {
|
||||
"count": 4,
|
||||
"avg_score": 6.2
|
||||
"count": 5,
|
||||
"avg_score": 6.0
|
||||
},
|
||||
"rag-progressive-search": {
|
||||
"count": 1,
|
||||
|
|
@ -1952,7 +1952,7 @@
|
|||
"name": "self-healing-infrastructure",
|
||||
"category": "devops",
|
||||
"description": "自愈基础设施 — 系统监控、配置版本控制、自动回滚、自进化管线、技能管理、自我优化、学习闭环。完整自治体系。牧尘专用。",
|
||||
"version": "1.6.0",
|
||||
"version": "1.7.0",
|
||||
"path": "devops/self-healing-infrastructure/SKILL.md",
|
||||
"is_archived": false,
|
||||
"has_refs": true,
|
||||
|
|
@ -2156,7 +2156,7 @@
|
|||
"name": "hermes-self-improvement",
|
||||
"category": "autonomous-ai-agents",
|
||||
"description": "当完成复杂任务、发现新工作流、或被用户纠正时,将模式保存为skill。含技能创建规范、质量标尺、curator流程。",
|
||||
"version": "3.9.0",
|
||||
"version": "4.2.0",
|
||||
"path": "autonomous-ai-agents/hermes-self-improvement/SKILL.md",
|
||||
"is_archived": false,
|
||||
"has_refs": true,
|
||||
|
|
@ -2220,6 +2220,23 @@
|
|||
"grade": "C",
|
||||
"needs_attention": false
|
||||
},
|
||||
{
|
||||
"name": "stock-research",
|
||||
"category": "research",
|
||||
"description": "小唯股票投研系统 — 四维选股 / 回测对比 / 每日信号",
|
||||
"version": "1.0",
|
||||
"path": "research/stock-research/SKILL.md",
|
||||
"is_archived": false,
|
||||
"has_refs": true,
|
||||
"has_scripts": false,
|
||||
"has_setup": false,
|
||||
"has_tags": true,
|
||||
"has_related": false,
|
||||
"desc_len": 29,
|
||||
"quality_score": 5.3,
|
||||
"grade": "C",
|
||||
"needs_attention": false
|
||||
},
|
||||
{
|
||||
"name": "vllm",
|
||||
"category": "mlops",
|
||||
|
|
|
|||
|
|
@ -290,13 +290,13 @@
|
|||
"created_at": "2026-06-05T03:15:27.762923+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-06-05T08:40:17.897034+00:00",
|
||||
"last_used_at": "2026-07-08T14:17:50.655923+00:00",
|
||||
"last_viewed_at": "2026-07-08T14:17:50.641691+00:00",
|
||||
"last_used_at": "2026-07-12T02:42:23.155284+00:00",
|
||||
"last_viewed_at": "2026-07-12T02:42:23.152090+00:00",
|
||||
"patch_count": 5,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 8,
|
||||
"view_count": 8
|
||||
"use_count": 9,
|
||||
"view_count": 9
|
||||
},
|
||||
"claude-code": {
|
||||
"archived_at": null,
|
||||
|
|
@ -797,13 +797,13 @@
|
|||
"created_at": "2026-06-26T10:00:14.532184+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_used_at": "2026-07-09T15:31:44.185320+00:00",
|
||||
"last_viewed_at": "2026-07-09T15:31:44.182456+00:00",
|
||||
"last_used_at": "2026-07-12T08:10:13.707713+00:00",
|
||||
"last_viewed_at": "2026-07-12T08:10:13.701809+00:00",
|
||||
"patch_count": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 9,
|
||||
"view_count": 9
|
||||
"use_count": 11,
|
||||
"view_count": 11
|
||||
},
|
||||
"hermes-agent-skill-authoring": {
|
||||
"archived_at": null,
|
||||
|
|
@ -875,13 +875,13 @@
|
|||
"created_at": "2026-05-13T12:27:05.593125+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": "2026-07-11T16:19:02.695644+00:00",
|
||||
"last_used_at": "2026-07-11T16:18:21.026282+00:00",
|
||||
"last_viewed_at": "2026-07-11T16:18:21.023087+00:00",
|
||||
"last_used_at": "2026-07-12T02:43:31.606181+00:00",
|
||||
"last_viewed_at": "2026-07-12T02:43:31.602039+00:00",
|
||||
"patch_count": 72,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 97,
|
||||
"view_count": 95
|
||||
"use_count": 99,
|
||||
"view_count": 96
|
||||
},
|
||||
"himalaya": {
|
||||
"archived_at": null,
|
||||
|
|
@ -1134,14 +1134,14 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-07-07T09:12:51.516409+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-07-08T04:24:23.620495+00:00",
|
||||
"last_used_at": "2026-07-11T18:46:44.170344+00:00",
|
||||
"last_viewed_at": "2026-07-09T00:58:40.532216+00:00",
|
||||
"patch_count": 4,
|
||||
"last_patched_at": "2026-07-12T01:14:59.722408+00:00",
|
||||
"last_used_at": "2026-07-12T01:13:29.697586+00:00",
|
||||
"last_viewed_at": "2026-07-12T01:13:29.692201+00:00",
|
||||
"patch_count": 5,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 10,
|
||||
"view_count": 8
|
||||
"use_count": 13,
|
||||
"view_count": 10
|
||||
},
|
||||
"nano-pdf": {
|
||||
"archived_at": null,
|
||||
|
|
@ -1250,15 +1250,15 @@
|
|||
"openclaw": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-06-28T01:01:35.675166+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_used_at": "2026-07-09T18:01:17.989671+00:00",
|
||||
"last_viewed_at": "2026-07-09T18:01:17.986343+00:00",
|
||||
"patch_count": 0,
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-07-12T10:18:35.363784+00:00",
|
||||
"last_used_at": "2026-07-12T17:50:34.561370+00:00",
|
||||
"last_viewed_at": "2026-07-12T17:50:34.558226+00:00",
|
||||
"patch_count": 9,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 9,
|
||||
"view_count": 9
|
||||
"use_count": 26,
|
||||
"view_count": 26
|
||||
},
|
||||
"openclaw-feishu-debug": {
|
||||
"archived_at": null,
|
||||
|
|
@ -1273,6 +1273,19 @@
|
|||
"use_count": 3,
|
||||
"view_count": 3
|
||||
},
|
||||
"openclaw-mcp": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-07-12T11:36:03.535167+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-07-12T12:47:31.969471+00:00",
|
||||
"last_used_at": "2026-07-12T12:46:51.205165+00:00",
|
||||
"last_viewed_at": "2026-07-12T12:46:51.201887+00:00",
|
||||
"patch_count": 2,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 2,
|
||||
"view_count": 2
|
||||
},
|
||||
"opencode": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-06-30T11:24:39.575050+00:00",
|
||||
|
|
@ -1377,6 +1390,19 @@
|
|||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"product-research": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-07-12T02:34:39.968795+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_used_at": "2026-07-12T02:34:39.973216+00:00",
|
||||
"last_viewed_at": "2026-07-12T02:34:39.968809+00:00",
|
||||
"patch_count": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 1,
|
||||
"view_count": 1
|
||||
},
|
||||
"product-research-pipeline": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-07-01T15:54:05.999337+00:00",
|
||||
|
|
@ -1468,6 +1494,19 @@
|
|||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"research/stock-research": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-07-12T01:41:49.118731+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_used_at": "2026-07-12T01:41:49.127872+00:00",
|
||||
"last_viewed_at": "2026-07-12T01:41:49.122033+00:00",
|
||||
"patch_count": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 2,
|
||||
"view_count": 2
|
||||
},
|
||||
"segment-anything-model": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-06-30T11:24:39.617688+00:00",
|
||||
|
|
@ -1485,14 +1524,14 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-07-08T18:13:02.034240+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-07-11T16:53:20.780714+00:00",
|
||||
"last_used_at": "2026-07-11T16:51:41.444268+00:00",
|
||||
"last_viewed_at": "2026-07-11T16:51:41.441274+00:00",
|
||||
"patch_count": 41,
|
||||
"last_patched_at": "2026-07-12T02:37:28.417440+00:00",
|
||||
"last_used_at": "2026-07-12T14:40:23.263646+00:00",
|
||||
"last_viewed_at": "2026-07-12T14:40:23.259954+00:00",
|
||||
"patch_count": 42,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 31,
|
||||
"view_count": 31
|
||||
"use_count": 36,
|
||||
"view_count": 36
|
||||
},
|
||||
"self-hosted-tunneling": {
|
||||
"archived_at": null,
|
||||
|
|
@ -1641,14 +1680,14 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-07-11T17:51:28.790816+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-07-11T18:38:06.537582+00:00",
|
||||
"last_used_at": "2026-07-11T18:37:53.243319+00:00",
|
||||
"last_viewed_at": "2026-07-11T18:37:53.240208+00:00",
|
||||
"patch_count": 15,
|
||||
"last_patched_at": "2026-07-12T17:54:33.843857+00:00",
|
||||
"last_used_at": "2026-07-12T17:49:48.915126+00:00",
|
||||
"last_viewed_at": "2026-07-12T17:49:48.911755+00:00",
|
||||
"patch_count": 40,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 9,
|
||||
"view_count": 9
|
||||
"use_count": 26,
|
||||
"view_count": 26
|
||||
},
|
||||
"subagent-driven-development": {
|
||||
"archived_at": null,
|
||||
|
|
@ -1888,14 +1927,14 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-05-29T19:39:03.373231+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": "2026-07-10T02:09:57.581506+00:00",
|
||||
"last_used_at": "2026-07-10T02:08:23.820626+00:00",
|
||||
"last_viewed_at": "2026-07-10T02:08:23.816480+00:00",
|
||||
"patch_count": 679,
|
||||
"last_patched_at": "2026-07-12T17:54:19.303892+00:00",
|
||||
"last_used_at": "2026-07-12T17:50:59.734487+00:00",
|
||||
"last_viewed_at": "2026-07-12T17:50:59.730843+00:00",
|
||||
"patch_count": 682,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 353,
|
||||
"view_count": 327
|
||||
"use_count": 354,
|
||||
"view_count": 328
|
||||
},
|
||||
"zhiyi-dev": {
|
||||
"archived_at": null,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
# MoA 系统评估参考 — 2026-07-12
|
||||
|
||||
## 场景:评估股票投研系统(9个脚本)
|
||||
|
||||
### 工作流
|
||||
1. `search_files` 定位所有相关脚本(~26个文件在 `~/.hermes/scripts/`)
|
||||
2. `read_file` 读取核心文件(stock_selector.py, stock_adaptive.py, stock_portfolio.py 等)
|
||||
3. 分析系统架构,识别三大短板
|
||||
4. 手动 curl 并行调用多模型做评估(用 `qwen/qwen3.5-122b-a10b` 做聚合器)
|
||||
5. 按优先级修复:宏观面 → 消息面 → 风险管理 → 数据质量
|
||||
|
||||
### 本次评估结论
|
||||
|
||||
| 维度 | 问题 | 修复 |
|
||||
|------|------|------|
|
||||
| 数据质量 | `analyze_ma20` 无验证 | `validate_klines()` 过滤0价格/异常值 |
|
||||
| 宏观面 | 只有上证+原油 | 补充沪深300(大盘风险代理) |
|
||||
| 消息面 | 纯静态规则 | 东方财富个股公告+行业新闻 |
|
||||
| 风险管理 | 无止损/仓位 | 8%止损+30%仓位上限 |
|
||||
|
||||
### 数据源验证(2026-07-12)
|
||||
|
||||
**可用**:
|
||||
- `https://qt.gtimg.cn/q=sh000001` → 上证
|
||||
- `https://qt.gtimg.cn/q=hf_OIL` → 布伦特原油
|
||||
- `https://qt.gtimg.cn/q=sh510300` → 沪深300
|
||||
- `https://web.ifzq.gtimg.cn/appstock/app/fqkline/get` → 日K前复权
|
||||
- `https://np-anotice-stock.eastmoney.com/api/security/ann` → 个股公告
|
||||
|
||||
**不可用**(返回 `v_pv_none_match`):
|
||||
- `usdcnh`, `usdcny`, `usdcnyf` 等离岸人民币代码
|
||||
- `gb_tnx`, `us10yr`, `tn10y` 等美债代码
|
||||
- 尝试过新浪 `hq.sinajs.cn/list=fx_susdcny` 也失败
|
||||
|
||||
### 消息截断处理
|
||||
|
||||
飞书传输大文本块(代码/patch命令)可能被截断,表现为重复片段+乱码。
|
||||
**处理方式**: 立即用 `search_files` + `read_file` 定位脚本,不反复重发同一消息。
|
||||
|
|
@ -35,12 +35,23 @@ exec python3 ~/.hermes/scripts/learner.py learn
|
|||
| 学习循环 | `learner.py learn` | wrapper: `learner-learn.sh` |
|
||||
| 双备份同步 | `dual-backup.sh push` | wrapper: `dual-backup-push.sh` |
|
||||
| 配置快照 | `config-protector.sh snapshot` | 去掉参数(默认就是snapshot) |
|
||||
| 自我优化报告 | `optimizer.py report` | wrapper: `optimizer-report.sh` |
|
||||
| 主动学习自检 | `proactive_learning.py report` | wrapper: `proactive-learning-report.sh` |
|
||||
|
||||
已验证需要包装的脚本: `optimizer.py report` → `optimizer-report.sh`; `proactive_learning.py report` → `proactive-learning-report.sh`。
|
||||
|
||||
### 检测
|
||||
|
||||
`cronjob action=list` → 看 `last_status` 为 `error` 的 job。
|
||||
如果是 no_agent 且脚本带参数,100% 中招。
|
||||
|
||||
### 验证包装脚本正确
|
||||
|
||||
```bash
|
||||
bash ~/.hermes/scripts/optimizer-report.sh
|
||||
# 应该直接输出报告内容(无报错)
|
||||
```
|
||||
|
||||
## 陷阱 2: no_agent stdout 静默
|
||||
|
||||
### 症状
|
||||
|
|
@ -77,4 +88,4 @@ git remote add origin http://192.168.123.11:3000/xiaoxue_admin/xiaowei-system.gi
|
|||
git push -f origin main
|
||||
```
|
||||
|
||||
注意: Gitea 服务器(192.168.123.11)离线时 push 也会失败。
|
||||
注意: Gitea 服务器(192.168.123.11)离线时 push 也会失败。
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
---
|
||||
tags: [openclaw, mcp, hermes-integration]
|
||||
name: openclaw-mcp
|
||||
description: "OpenClaw 作为 MCP Server 接入 Hermes — 已验证 2026-07-12,暴露 9 个工具:conversations_list/get、messages_read/send、events_poll/wait、attachments_fetch、permissions"
|
||||
version: 1.0.0
|
||||
author: 小唯
|
||||
date: 2026-07-12
|
||||
---
|
||||
|
||||
readiness_status: available
|
||||
|
||||
# OpenClaw MCP Server 接入(Hermes 控制 OpenClaw)
|
||||
|
||||
## 接入流程
|
||||
|
||||
**步骤 1:探测工具**
|
||||
```bash
|
||||
hermes mcp add openclaw --command openclaw --args mcp serve
|
||||
# 成功:✓ Connected! Found 9 tool(s)
|
||||
```
|
||||
|
||||
**步骤 2:持久化配置(⚠️ `hermes mcp add` 不写 config.yaml,必须手动加)**
|
||||
```python
|
||||
import yaml
|
||||
with open('/home/muc/.hermes/config.yaml') as f:
|
||||
config = yaml.safe_load(f)
|
||||
config['mcp_servers']['openclaw'] = {
|
||||
'command': 'openclaw',
|
||||
'args': ['mcp', 'serve'],
|
||||
'connect_timeout': 60,
|
||||
'timeout': 300,
|
||||
}
|
||||
with open('/home/muc/.hermes/config.yaml', 'w') as f:
|
||||
yaml.dump(config, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
|
||||
```
|
||||
|
||||
验证:
|
||||
```bash
|
||||
python3 -c "import yaml; c=yaml.safe_load(open('/home/muc/.hermes/config.yaml')); print(c['mcp_servers'].get('openclaw','NOT FOUND'))"
|
||||
```
|
||||
|
||||
**步骤 3:等待 gateway 自动重载(无需手动 restart)**
|
||||
验证:`hermes mcp list` — openclaw 应出现,Status 为 ✓ enabled
|
||||
验证连接:`hermes mcp test openclaw`(输出 9 tools 即成功)
|
||||
|
||||
## 暴露的 9 个工具
|
||||
|
||||
| 工具 | 用途 | 限制 |
|
||||
|------|------|------|
|
||||
| `conversations_list` | 列出所有对话 | — |
|
||||
| `conversation_get` | 获取单个对话 | — |
|
||||
| `messages_read` | 读取历史消息 | Feishu channel-only |
|
||||
| `attachments_fetch` | 获取附件 | — |
|
||||
| `events_poll` | 轮询新事件 | — |
|
||||
| `events_wait` | 阻塞等待事件 | — |
|
||||
| `messages_send` | 发送消息给 OpenClaw 对话 | 只能发给 OpenClaw 自身的 channel,不能跨 app DM |
|
||||
| `permissions_list_open` | 待审批权限 | — |
|
||||
| `permissions_respond` | 审批/拒绝请求 | — |
|
||||
|
||||
**关键限制**:`messages_send` 只能发到 OpenClaw 所在 channel,受 `open_id cross app` 限制,不能直接 DM 牧尘或 Hermes 用户。
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- **`hermes mcp add` 只做临时探测,不写 config.yaml** — 连接测试成功后必须手动 patch config.yaml 持久化
|
||||
- **`hermes mcp reload` 不存在** — 需要 `hermes gateway restart` 才能让新配置生效
|
||||
- **`openclaw mcp serve` 是 stdio 模式** — 进程处理完一条消息后退出,不能当作后台 TCP 服务
|
||||
- **stdio 模式下 stderr 会污染 stdout** — 直接用 Python `subprocess.Popen` 调用时,doctor 日志混进 stdout 导致 JSON 解析失败;通过 Hermes MCP 工具层调用(而不是自己写协议解析)可避开此问题
|
||||
|
||||
## 任务派发到 OpenClaw 的正确方式
|
||||
|
||||
OpenClaw 有 cron `team-task-check`(每 30 分钟)监控任务队列:
|
||||
|
||||
**正确路径**:`~/.openclaw/workspace-a03/TEAM/task-queue.md`(A03 cron 实际监控的位置,Markdown 表格格式)
|
||||
|
||||
追加格式(在共享队列表格末尾添加):
|
||||
```
|
||||
| ID | 任务 | 负责人 | 状态 | 备注 |
|
||||
| hermes-test-001 | 【小唯测试】xxx任务 | A01 | ⏳ 待处理 | 来源: Hermes A06 |
|
||||
```
|
||||
|
||||
**⚠️ Pitfall:写错队列文件 → 任务永远不会被执行**
|
||||
- `~/.openclaw/workspace/shared/team_task_queue.json` — JSON 格式,OpenClaw cron **不监控**
|
||||
- `~/.openclaw/workspace-a03/TEAM/task-queue.md` — Markdown 表格,才是 cron 实际监控的
|
||||
|
||||
## OpenClaw ≠ Hermes(身份区分,必须分清)
|
||||
|
||||
| | Hermes (小唯 A06) | OpenClaw (小雪 A01) |
|
||||
|--|------------------|---------------------|
|
||||
| 飞书 App | `cli_a95d7ff06b789bb4` | `cli_a95d7ceba638dbc6` |
|
||||
| Gateway 端口 | 8644 | 18789 |
|
||||
|
||||
**跨 bot 通信受 `open_id cross app` 限制** — 不能靠飞书 DM,必须靠文件系统协调。
|
||||
|
||||
## 内部团队架构(用于理解任务分发)
|
||||
|
||||
5 人团队(星型:A01 对接所有,其他只对 A01 负责):
|
||||
|
||||
| 代号 | 角色 | 关键路径 |
|
||||
|------|------|---------|
|
||||
| A01 小雪 | 中枢调度 | — |
|
||||
| A02 铁锋 | 技术执行 | — |
|
||||
| A03 墨文 | 内容/队列监控 | `workspace-a03/TEAM/task-queue.md` |
|
||||
| A04 卫安 | 安全审核 | — |
|
||||
| A05 蓝图 | 流程架构 | — |
|
||||
|
||||
**关键 cron**:
|
||||
- `team-task-check`(每 30m)→ 读 `task-queue.md`,超时任务更新 blackboard
|
||||
- `heartbeat-30min`(每 30m)→ 发心跳给 `ou_7a3663f92e09671e3d9b7fa63042114f`
|
||||
- `evening-think`(每天 21:00)→ 发给牧尘 `ou_da2e9d4029c7165c211a2553dc375f80`
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
# OpenClaw MCP 集成 — 2026-07-12 实测记录
|
||||
|
||||
> 本次探索发现的技术细节,供后续调试参考。
|
||||
|
||||
## stdio 模式的本质
|
||||
|
||||
`openclaw mcp serve` 是 **JSON-RPC over stdio**:
|
||||
|
||||
```
|
||||
Parent process (Hermes) --JSON-RPC line--> stdin of openclaw mcp serve
|
||||
<--JSON-RPC line-- stdout of openclaw mcp serve
|
||||
```
|
||||
|
||||
**特性**:
|
||||
- 无新消息时 openclaw 进程退出(不是后台服务)
|
||||
- stderr 输出 doctor 日志/warnings,会混入 stdout 导致 JSON 解析失败
|
||||
- 必须通过 Hermes MCP 工具层间接调用,不能自己写协议解析
|
||||
|
||||
**验证命令**:
|
||||
```bash
|
||||
# 在干净终端测试(stderr 被重定向)
|
||||
openclaw mcp serve </dev/null 2>/tmp/mcp_err.log
|
||||
|
||||
# 查看 stderr 内容
|
||||
cat /tmp/mcp_err.log
|
||||
# 通常包含: [plugins] ... Doctor warnings ... Config warnings ...
|
||||
```
|
||||
|
||||
## 为什么要通过 Hermes MCP 层调用
|
||||
|
||||
直接用 Python 调用 `subprocess.Popen(['openclaw', 'mcp', 'serve'])` 会遇到:
|
||||
|
||||
```
|
||||
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
|
||||
```
|
||||
|
||||
**原因**:openclaw 把 doctor 日志输出到 stderr,但 stderr 被 Python 继承,
|
||||
导致第一条 stdout 不是 JSON 而是日志片段。
|
||||
|
||||
**绕过方法**:
|
||||
```python
|
||||
err_file = open('/tmp/mcp_err.log', 'w')
|
||||
proc = subprocess.Popen(['openclaw', 'mcp', 'serve'],
|
||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=err_file, text=False)
|
||||
```
|
||||
|
||||
但更简洁的方式是**通过 Hermes 的 MCP 工具层**,Hermes 已经处理了 stderr 分离。
|
||||
|
||||
## 子 agent 验证结果(2026-07-12)
|
||||
|
||||
- `hermes mcp add openclaw` → ✓ Found 9 tools
|
||||
- 配置持久化到 `~/.hermes/config.yaml` → ✓ 成功
|
||||
- Gateway 自动重载(无手动 restart)→ ✓ 已生效
|
||||
- 子 agent 调用 `conversations_list` → 工具链路通,49 次 API 调用后超时(等回复)
|
||||
- **结论**:MCP 连接建立成功,但多轮交互(发消息→等回复)需要更长的 timeout 或不同的调用策略
|
||||
|
||||
## 9 个工具的实际用途
|
||||
|
||||
| 工具 | 本次 session 验证 | 备注 |
|
||||
|------|-------------------|------|
|
||||
| `conversations_list` | ⚠️ 超时 | 工具调用成功,等回复时子 agent 超时 |
|
||||
| `conversation_get` | 未测 | 需要 session key 参数 |
|
||||
| `messages_read` | 未测 | Feishu channel-only |
|
||||
| `messages_send` | ⚠️ 受限 | 不能跨 app DM,受 `open_id cross app` 限制 |
|
||||
| `events_poll` | 未测 | — |
|
||||
| `events_wait` | 未测 | — |
|
||||
| `attachments_fetch` | 未测 | — |
|
||||
| `permissions_list_open` | 未测 | — |
|
||||
| `permissions_respond` | 未测 | — |
|
||||
|
||||
## `open_id cross app` 限制的完整说明
|
||||
|
||||
飞书不同应用(App)的 bot 之间**不能**互发消息:
|
||||
|
||||
| 发送方 | 接收方 | 结果 |
|
||||
|--------|--------|------|
|
||||
| Hermes bot (`cli_a95d7ff06b789bb4`) | OpenClaw bot (`cli_a95d7ceba638dbc6`) | ❌ `open_id cross app, code=99992361` |
|
||||
| OpenClaw bot | Hermes bot | ❌ 同上 |
|
||||
| 任意 bot | 用户 (`ou_xxx`) | ✅ 可以 |
|
||||
|
||||
**解决路径**:
|
||||
1. 文件系统协调:`~/.openclaw/workspace-a03/TEAM/task-queue.md`
|
||||
2. 通过用户(牧尘)做中转(不推荐)
|
||||
|
||||
## OpenClaw A02 铁锋的 exec 能力
|
||||
|
||||
A02 是技术执行角色,理论上能执行命令。但需要通过:
|
||||
- `messages_send` 发消息给 OpenClaw session
|
||||
- OpenClaw agent 理解后通过 A02 执行
|
||||
- 结果通过 `messages_read` 返回
|
||||
|
||||
这不是一个同步 RPC,而是一个异步的多轮对话。适合非实时任务,不适合需要毫秒级返回的场景。
|
||||
|
||||
## Gateway 端口
|
||||
|
||||
| 服务 | 端口 | 用途 |
|
||||
|------|------|------|
|
||||
| OpenClaw Gateway | 18789 | dashboard (`/`), HTTP API (`/api`), WebSocket |
|
||||
| Hermes Gateway | 8644 | Hermes 自身 |
|
||||
|
||||
两者都绑定 127.0.0.1,不对外暴露。
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
---
|
||||
tags: [openclaw, mcp, hermes-integration]
|
||||
name: openclaw
|
||||
description: "OpenClaw 日常维护与 Hermes MCP 集成 — skill 管理、配置修复、飞书频道、诊断命令、MCP Server 接入"
|
||||
version: 1.4.0
|
||||
author: 小唯
|
||||
date: 2026-07-12
|
||||
---
|
||||
|
||||
readiness_status: available
|
||||
|
||||
# OpenClaw 飞书频道故障排查
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 群聊 @ 无反应
|
||||
**症状**:飞书群聊 @ 机器人无回应,无日志
|
||||
|
||||
**诊断**:
|
||||
```bash
|
||||
grep "not in group sender allowlist" /tmp/openclaw/openclaw-*.log
|
||||
```
|
||||
|
||||
**原因**:`groupSenderAllowFrom` 配置了 group ID 而非用户 ID,导致群成员被过滤
|
||||
|
||||
**修复**:`groupSenderAllowFrom` 应填写用户 open_id(`ou_xxx`),而非群 ID(`oc_xxx`)
|
||||
```json
|
||||
"groupSenderAllowFrom": [
|
||||
"ou_7a3663f92e09671e3d9b7fa63042114f",
|
||||
"ou_f20eb15b3a76639fed35977c01ddcbb4"
|
||||
]
|
||||
```
|
||||
|
||||
验证:配置热更新后日志出现 `config hot reload applied (channels.feishu.groupSenderAllowFrom)`
|
||||
|
||||
### 私聊能收到消息但无回复
|
||||
**症状**:飞书私聊消息有 dispatch 日志,`queuedFinal=true, replies=N` 但无实际发送
|
||||
|
||||
**诊断**:查看日志中是否所有消息都 `dispatch complete (queuedFinal=true, replies=N)` 后无后续发送
|
||||
|
||||
**原因**:Gateway 重启可解决(可能是 v2026.5.4 的队列 worker 卡住)
|
||||
|
||||
**修复**:
|
||||
```bash
|
||||
# 重启 Gateway
|
||||
ps aux | grep openclaw | grep -v grep | awk '{print $2}' | xargs kill
|
||||
openclaw gateway run &
|
||||
```
|
||||
|
||||
### systemd 服务执行(重要!)
|
||||
`openclaw exec` **不存在**,无法通过 openclaw 执行 systemctl。
|
||||
|
||||
重启 systemd 服务(daemon / gateway 等)的正确方式:
|
||||
- **牧尘手动在终端执行**:`systemctl --user restart <service>`
|
||||
- 或通过 SSH 到本机执行
|
||||
|
||||
**关键约束**:hermes gateway 内部执行 systemctl 会被拦截(PermissionError),必须从 gateway 外部执行。
|
||||
|
||||
### Bot open_id resolved: unknown
|
||||
**症状**:Gateway 启动时 `bot open_id resolved: unknown`
|
||||
|
||||
**原因**:appId/appSecret 配置错误或 app 未在飞书后台正确配置
|
||||
|
||||
## 关键日志关键词
|
||||
| 日志 | 含义 |
|
||||
|------|------|
|
||||
| `received message from ... in oc_xxx (p2p)` | 收到私聊消息 |
|
||||
| `received message from ... in oc_xxx (group)` | 收到群聊消息 |
|
||||
| `dispatching to agent` | 消息正在转发给 agent |
|
||||
| `dispatch complete (queuedFinal=true, replies=N)` | 回复已排队 |
|
||||
| `not in group sender allowlist` | 群成员不在白名单,被过滤 |
|
||||
| `bot open_id resolved` | bot 身份验证结果 |
|
||||
| `WebSocket client started` | 飞书 websocket 连接成功 |
|
||||
| `config hot reload applied` | 配置热更新生效 |
|
||||
|
||||
---
|
||||
|
||||
## 诊断命令汇总
|
||||
|
||||
```bash
|
||||
# 基础诊断(显示所有问题)
|
||||
openclaw doctor
|
||||
|
||||
# 自动修复(禁用缺失依赖的 skill、重置 allowlist 等)
|
||||
openclaw doctor --fix
|
||||
|
||||
# 查看 skill 详细状态
|
||||
openclaw skills check --agent main
|
||||
|
||||
# 安全审计
|
||||
openclaw security audit --deep
|
||||
|
||||
# 查看当前配置(JSON 格式化)
|
||||
cat ~/.openclaw/openclaw.json | python3 -m json.tool | less
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Skill 依赖问题处理流程
|
||||
|
||||
**`openclaw doctor --fix` 会自动**:
|
||||
- 禁用 36 个缺依赖的 skill(如 `apple-*`、`blogwatcher`、`xurl` 等)
|
||||
- 保留本地可用的 skill(如 `gh` 安装后 `gh-issues` 自动恢复)
|
||||
|
||||
**手动处理流程**:
|
||||
1. `openclaw skills check --agent main` 查看缺失项
|
||||
2. 判断工具是否可安装(Linux 发行版包管理器、pip、npm)
|
||||
3. 可安装 → 安装后重新 check
|
||||
4. 不可安装 → `openclaw doctor --fix` 自动禁用
|
||||
|
||||
**常见 CLI 手动安装(绕过 sudo)**:
|
||||
```bash
|
||||
# gh: GitHub CLI(绕过 sudo 限制)
|
||||
cd /tmp
|
||||
curl -LO https://github.com/cli/cli/releases/download/v2.92.0/gh_2.92.0_linux_amd64.tar.gz
|
||||
tar -xzf gh_2.92.0_linux_amd64.tar.gz
|
||||
cp gh_2.92.0_linux_amd64/bin/gh ~/.local/bin/ && chmod +x ~/.local/bin/gh
|
||||
gh --version
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 配置安全加固
|
||||
|
||||
### 保护危险命令(必须)
|
||||
`/diagnostics`、`/export-trajectory`、`/config` 等命令可被任何人调用。添加 owner 限制:
|
||||
|
||||
```json
|
||||
"commands": {
|
||||
"ownerAllowFrom": [
|
||||
"ou_f20eb15b3a76639fed35977c01ddcbb4",
|
||||
"ou_7a3663f92e09671e3d9b7fa63042114f"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 敏感文件权限
|
||||
```bash
|
||||
chmod 600 ~/.openclaw/agents/main/agent/auth-profiles.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MCP Server 模式(Hermes 控制 OpenClaw — 已验证 2026-07-12)
|
||||
|
||||
OpenClaw 可作为 MCP Server,暴露 9 个工具给 Hermes 调用,实现「Hermes 做大脑、OpenClaw 做执行」的架构。
|
||||
|
||||
### 接入流程
|
||||
|
||||
**步骤 1:探测工具**
|
||||
```bash
|
||||
hermes mcp add openclaw --command openclaw --args mcp serve
|
||||
# 成功:✓ Connected! Found 9 tool(s)
|
||||
```
|
||||
⚠️ `openclaw mcp serve` 是 **stdio 模式**(stdin/stdout),不是网络服务器。没有新消息时进程退出,不能作为后台 TCP 服务直接 curl 测试。
|
||||
|
||||
**步骤 2:持久化配置(⚠️ `hermes mcp add` 不写 config.yaml,必须手动加)**
|
||||
```python
|
||||
import yaml
|
||||
with open('/home/muc/.hermes/config.yaml') as f:
|
||||
config = yaml.safe_load(f)
|
||||
config['mcp_servers']['openclaw'] = {
|
||||
'command': 'openclaw',
|
||||
'args': ['mcp', 'serve'],
|
||||
'connect_timeout': 60,
|
||||
'timeout': 300,
|
||||
}
|
||||
with open('/home/muc/.hermes/config.yaml', 'w') as f:
|
||||
yaml.dump(config, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
|
||||
```
|
||||
|
||||
验证:
|
||||
```bash
|
||||
python3 -c "import yaml; c=yaml.safe_load(open('/home/muc/.hermes/config.yaml')); print(c['mcp_servers'].get('openclaw','NOT FOUND'))"
|
||||
```
|
||||
|
||||
**步骤 3:重启 gateway** `hermes gateway restart`(从另一个终端执行,不能从 gateway 进程内部重启)
|
||||
|
||||
**验证** `hermes mcp list` — openclaw 应出现,Status 为 ✓ enabled
|
||||
验证连接:`hermes mcp test openclaw`(输出 ✓ Connected + 9 tools 即成功)
|
||||
|
||||
### 暴露的 9 个工具
|
||||
|
||||
| 工具 | 用途 | 限制 |
|
||||
|------|------|------|
|
||||
| `conversations_list` | 列出所有对话 | — |
|
||||
| `conversation_get` | 获取单个对话 | — |
|
||||
| `messages_read` | 读取历史消息 | Feishu channel-only |
|
||||
| `attachments_fetch` | 获取附件 | — |
|
||||
| `events_poll` | 轮询新事件 | — |
|
||||
| `events_wait` | 阻塞等待事件 | — |
|
||||
| `messages_send` | 发送消息给 OpenClaw 对话 | 只能发给 OpenClaw 自身的 channel,不能跨 app DM |
|
||||
| `permissions_list_open` | 待审批权限 | — |
|
||||
| `permissions_respond` | 审批/拒绝请求 | — |
|
||||
|
||||
**关键限制**:`messages_send` 只能发到 OpenClaw 所在 channel,受 `open_id cross app` 限制,不能直接 DM 牧尘或 Hermes 用户。
|
||||
|
||||
### 任务派发到 OpenClaw 的正确方式
|
||||
|
||||
OpenClaw 有 cron `team-task-check`(每 30 分钟)监控任务队列:
|
||||
|
||||
**正确路径**:`~/.openclaw/workspace-a03/TEAM/task-queue.md`(A03 cron 实际监控的位置,Markdown 表格格式)
|
||||
|
||||
追加格式(在共享队列表格末尾添加):
|
||||
```
|
||||
| ID | 任务 | 负责人 | 状态 | 备注 |
|
||||
| hermes-test-001 | 【小唯测试】xxx任务 | A01 | ⏳ 待处理 | 来源: Hermes A06 |
|
||||
```
|
||||
|
||||
**⚠️ Pitfall:写错队列文件 → 任务永远不会被执行**
|
||||
- `~/.openclaw/workspace/shared/team_task_queue.json` — JSON 格式,OpenClaw cron **不监控**
|
||||
- `~/.openclaw/workspace-a03/TEAM/task-queue.md` — Markdown 表格,才是 cron 实际监控的
|
||||
|
||||
**备选**:`messages_send` 发到 `conversations_list` 找到的 OpenClaw channel key 触发。
|
||||
|
||||
### OpenClaw 内部团队架构
|
||||
|
||||
5 人团队(星型:A01 对接所有,其他只对 A01 负责):
|
||||
|
||||
| 代号 | 角色 | 关键路径 |
|
||||
|------|------|---------|
|
||||
| A01 小雪 | 中枢调度 | — |
|
||||
| A02 铁锋 | 技术执行 | — |
|
||||
| A03 墨文 | 内容/队列监控 | `workspace-a03/TEAM/task-queue.md` |
|
||||
| A04 卫安 | 安全审核 | — |
|
||||
| A05 蓝图 | 流程架构 | — |
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `workspace-a03/TEAM/task-queue.md` | A03 cron 监控的任务队列(Markdown) |
|
||||
| `workspace-a03/blackboard.md` | 公告板,任务状态汇总 |
|
||||
| `workspace/shared/a02_report_queue.json` | A02 报告队列 |
|
||||
| `workspace/shared/chat_inbox.json` | 跨 Agent 通信收件箱 |
|
||||
| `workspace/shared/execution_log.md` | 执行日志 |
|
||||
|
||||
**关键 cron**:
|
||||
- `team-task-check`(每 30m)→ 读 `task-queue.md`,超时任务更新 blackboard
|
||||
- `heartbeat-30min`(每 30m)→ 发心跳给 `ou_7a3663f92e09671e3d9b7fa63042114f`
|
||||
- `evening-think`(每天 21:00)→ 发给牧尘 `ou_da2e9d4029c7165c211a2553dc375f80`
|
||||
|
||||
### OpenClaw ≠ Hermes(身份区分,必须分清)
|
||||
|
||||
| | Hermes (小唯 A06) | OpenClaw (小雪 A01) |
|
||||
|--|------------------|---------------------|
|
||||
| 飞书 App | `cli_a95d7ff06b789bb4` | `cli_a95d7ceba638dbc6` |
|
||||
| Gateway 端口 | 8644 | 18789 |
|
||||
| 配置文件 | `~/.hermes/config.yaml` | `~/.openclaw/openclaw.json` |
|
||||
| 日志 | `~/.hermes/logs/` | `/tmp/openclaw/` |
|
||||
|
||||
**跨 bot 通信受 `open_id cross app` 限制** — 不能靠飞书 DM,必须靠文件系统协调。
|
||||
|
||||
### Pitfall
|
||||
|
||||
详细接入流程+工具限制见 `references/mcp-integration-20260712.md`
|
||||
|
||||
- **`hermes mcp add` 只做临时探测,不写 config.yaml** — 连接测试成功(✓ Found 9 tools)后必须手动 patch config.yaml 持久化
|
||||
- **`hermes mcp reload` 不存在** — 需要 `hermes gateway restart` 才能让新配置生效
|
||||
- **不能从 gateway 进程内重启 gateway** — 从另一个终端执行
|
||||
- **两个 bot 不能跨 app DM** — 靠文件系统协调
|
||||
- **任务队列文件不要写错** — JSON 版本不会被监控,必须写 Markdown 版本
|
||||
|
||||
---
|
||||
|
||||
## Skill 完整清理流程(删 vs 禁用的区别)
|
||||
|
||||
> ⚠️ **危险模式**:用 `json.dump()` 一次性覆盖整个 `openclaw.json` 的 `skills.entries` 会导致绝大多数 skill 配置被清空。必须用 patch 方式只改目标 key,或用 `patch` 后写回时保留所有原 entries。
|
||||
|
||||
openclaw 的 skill 存在于**两个位置**,处理方式不同:
|
||||
|
||||
| 位置 | 路径 | 删除方式 | 配置方式 |
|
||||
|------|------|----------|----------|
|
||||
| 工作空间 | `~/.openclaw/workspace/skills/<name>/` | `rm -rf` 文件系统删除 | 从 `skills.entries` 中 del key |
|
||||
| Bundle 内置 | `~/.local/node-v22.19.0-linux-x64/lib/node_modules/openclaw/skills/<name>/` | **不可删除**(只读) | 在 `skills.entries` 中设 `{"enabled": false}` |
|
||||
|
||||
常见内置 skill(只能禁用不能删):`1password`、`blogwatcher`、`openhue`、`xurl`、`himalaya`、`nano-pdf`、`obsidian`、`mcporter`、`clawhub`、`gifgrep`、`songsee`、`sonoscli`、`wacli`、`sag`、`ordercli`、`gemini`、`gog`、`eightctl`、`blucli`、`camsnap`
|
||||
|
||||
### 正确清理流程
|
||||
|
||||
```bash
|
||||
# 1. 诊断
|
||||
openclaw skills check --agent main
|
||||
|
||||
# 2. 自动禁用缺失依赖 skill(写配置 + 部分删除)
|
||||
openclaw doctor --fix
|
||||
|
||||
# 3. 重启 gateway(清除内存缓存)
|
||||
pkill -f "openclaw gateway"; sleep 2
|
||||
cd /home/muc && openclaw gateway run &
|
||||
|
||||
# 4. 确认禁用生效
|
||||
openclaw skills check --agent main
|
||||
# 期望: Missing requirements: 0
|
||||
|
||||
# 5. 验证 config(不要用全量 json.dump)
|
||||
python3 -c "
|
||||
import json
|
||||
with open('/home/muc/.openclaw/openclaw.json') as f:
|
||||
cfg = json.load(f)
|
||||
entries = cfg.get('skills', {}).get('entries', {})
|
||||
print(f'Skills in config: {len(entries)}')
|
||||
enabled = [k for k,v in entries.items() if v.get('enabled', True)]
|
||||
disabled = [k for k,v in entries.items() if not v.get('enabled', True)]
|
||||
print(f'Enabled: {len(enabled)}, Disabled: {len(disabled)}')
|
||||
"
|
||||
```
|
||||
|
||||
### Skill 分类处理
|
||||
|
||||
**macOS 专有**(无 Linux 等效,删):
|
||||
`apple-notes`、`apple-reminders`、`bear-notes`、`imsg`、`model-usage`、`peekaboo`、`things-mac`
|
||||
|
||||
**无安装包**(确认后删):
|
||||
- 搜不到 apt/pip/npm/brew 包 → 删
|
||||
- 示例:`openhue`(无 pip 包)、`songsee`(无 pip 包)、`xurl`(非 Twitter 工具,npm 上是另一个库)
|
||||
|
||||
**缺 token/环境变量**(删或禁用):
|
||||
`discord`(需 channel token)、`trello`(需 API key)、`spotify-player`(需 spogo)、`sherpa-onnx-tts`、`voice-call`、`bluebubbles`、`openai-whisper-api`
|
||||
|
||||
**可安装 CLI**(优先安装):
|
||||
`gh`(已验证可绕过 sudo 下载二进制)
|
||||
|
||||
---
|
||||
|
||||
## 升级后"不如之前好用"排查框架
|
||||
|
||||
1. `openclaw doctor` — 看全部报错
|
||||
2. `openclaw security audit --deep` — 安全配置
|
||||
3. `openclaw skills check --agent main` — 依赖完整性
|
||||
4. `tail -f /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log` — 实时日志
|
||||
5. 检查飞书 bot 连接状态:`grep -i "feishu\|websocket" /tmp/openclaw/*.log`
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
# OpenClaw MCP Server 接入参考
|
||||
|
||||
## 完整接入流程(2026-07-12 实测)
|
||||
|
||||
### Step 1 — 探测(临时,不写 config)
|
||||
```bash
|
||||
hermes mcp add openclaw --command openclaw --args mcp serve
|
||||
# 成功输出:✓ Connected (2613ms) + ✓ Tools discovered: 9
|
||||
# 注意:此命令只做临时探测,不写入 config.yaml
|
||||
```
|
||||
|
||||
### Step 2 — 持久化配置(手动 patch)
|
||||
`hermes mcp add` 不写 config.yaml,必须手动 Python patch:
|
||||
```python
|
||||
import yaml
|
||||
with open('/home/muc/.hermes/config.yaml') as f:
|
||||
cfg = yaml.safe_load(f)
|
||||
cfg['mcp_servers']['openclaw'] = {
|
||||
'command': 'openclaw',
|
||||
'args': ['mcp', 'serve'],
|
||||
'connect_timeout': 60,
|
||||
'timeout': 300,
|
||||
}
|
||||
with open('/home/muc/.hermes/config.yaml', 'w') as f:
|
||||
yaml.dump(cfg, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
|
||||
```
|
||||
|
||||
### Step 3 — 重启 gateway
|
||||
```bash
|
||||
# 从另一个终端执行(不能从 gateway 内部重启)
|
||||
hermes gateway restart
|
||||
```
|
||||
|
||||
### Step 4 — 验证
|
||||
```bash
|
||||
hermes mcp list # 应显示 openclaw,Status = ✓ enabled
|
||||
hermes mcp test openclaw # 应输出 ✓ Connected + 9 tools
|
||||
```
|
||||
|
||||
## 关键限制
|
||||
|
||||
| 限制 | 说明 |
|
||||
|------|------|
|
||||
| `openclaw mcp serve` 是 stdio 模式 | 不用时进程退出,不能后台 TCP 探测 |
|
||||
| `hermes mcp reload` 不存在 | 改完 config 必须 restart gateway |
|
||||
| `messages_send` 受 cross-app 限制 | 只能发给 OpenClaw 自身的 channel |
|
||||
| Gateway 只绑定 loopback | 外部无法直接 WebSocket 连接 |
|
||||
|
||||
## 暴露的工具(9个)
|
||||
|
||||
`conversations_list` · `conversation_get` · `messages_read` · `attachments_fetch` · `events_poll` · `events_wait` · `messages_send` · `permissions_list_open` · `permissions_respond`
|
||||
|
||||
## 通过 MCP 让 OpenClaw 执行命令
|
||||
|
||||
OpenClaw A02(铁锋)有执行能力,通过 `messages_send` 发指令到其 session,等待 `messages_read` 读结果。多轮对话模式,非单次 RPC。
|
||||
|
||||
**文件任务路径**(A03 cron 每30分钟监控):
|
||||
- 正确:`~/.openclaw/workspace-a03/TEAM/task-queue.md`(Markdown 表格)
|
||||
- 错误:`~/.openclaw/workspace/shared/team_task_queue.json`(JSON 格式,cron 不监控)
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: stock-research
|
||||
version: "1.0"
|
||||
date: "2026-07-12"
|
||||
version: "1.2"
|
||||
date: "2026-07-13"
|
||||
tags: ["stock", "backtest", "selector", "macd", "ma20", "simulation"]
|
||||
description: 小唯股票投研系统 — 四维选股 / 回测对比 / 每日信号
|
||||
---
|
||||
|
|
@ -12,20 +12,40 @@ description: 小唯股票投研系统 — 四维选股 / 回测对比 / 每日
|
|||
|
||||
Use when: building a stock analysis system, researching individual stocks, running backtests, or generating daily trading signals.
|
||||
|
||||
## System Architecture
|
||||
## System Architecture (v1.1 — 2026-07-12 增强版)
|
||||
|
||||
```
|
||||
stock_selector.py ← 四维选股 (macro/fundamental/technical/sentiment)
|
||||
stock_compare.py ← 多策略对比 (MACD/MA20/dual-MA)
|
||||
stock_adaptive.py ← 自适应策略 (ADX环境感知)
|
||||
stock_signal.py ← 每日MA20信号推送(五粮液专用)
|
||||
stock_portfolio.py ← 7只股票MA20每日组合扫描
|
||||
stock_paper.py ← 纸上交易账户(买入/卖出/胜率/最大回撤)
|
||||
stock_news.py ← 每日宏观+原油+大盘摘要
|
||||
stock_backtest/ ← 回测数据 + 模拟交易记录
|
||||
cangjie-skills/ ← 知识蒸馏 (RIA++结构)
|
||||
stock_selector.py ← 四维选股 + 真实新闻接入
|
||||
├─ get_stock_news() # 东方财富个股公告 API
|
||||
├─ get_sector_news() # 行业新闻搜索(东方财富)
|
||||
└─ get_sentiment_score_from_news() # 真实新闻评分+静态回退
|
||||
|
||||
stock_adaptive.py ← 自适应策略 + 风险管理
|
||||
├─ stop_loss_pct=8.0 # 8%止损线(强制平仓)
|
||||
├─ max_position_pct=30.0 # 单笔仓位上限
|
||||
└─ stop_loss_triggered # 止损触发统计
|
||||
|
||||
stock_portfolio.py ← 组合扫描 + 数据质量验证
|
||||
├─ validate_klines() # K线质量验证(过滤0价格/异常值)
|
||||
└─ get_macro() # 宏观: 上证+原油+沪深300
|
||||
|
||||
stock_signal.py ← 五粮液专用MA20信号
|
||||
stock_ma20_backtest.py ← 茅台MA20策略回测 (新)
|
||||
stock_compare.py ← 多策略对比 (MACD/MA20/dual-MA)
|
||||
stock_news.py ← 每日宏观摘要
|
||||
stock_paper.py ← 纸上交易账户
|
||||
stock_backtest/ ← 回测数据 + 模拟交易记录
|
||||
```
|
||||
|
||||
## MoA 系统评估工作流(2026-07-12 新增)
|
||||
|
||||
当需要对系统做全面评估时,使用 MoA 三模型专家共识:
|
||||
1. 读取所有相关脚本源码
|
||||
2. curl 并行调用 NewAPI 参考模型 + 手动聚合
|
||||
3. 生成问题清单 + 修复优先级
|
||||
|
||||
**关键教训**: 消息被截断时(飞书/网络),立即用 `read_file` 定位脚本,不要反复重发同一消息。
|
||||
|
||||
## Core Workflow
|
||||
|
||||
### Phase 1-4: Theory
|
||||
|
|
@ -43,20 +63,30 @@ python3 ~/.hermes/scripts/stock_selector.py --scan # 批量扫描
|
|||
|
||||
四维维度: 宏观面(人民币/沪深300) / 基本面(PE/PB/价格位置) / 技术面(MA排列) / 消息面(行业政策)
|
||||
|
||||
**Step 2 — 回测: 三策略对比**
|
||||
**Step 2 — 回测: MA20策略**(先用MA20,回测框架已有;MACD仅做对比参考)
|
||||
```bash
|
||||
python3 ~/.hermes/scripts/stock_compare.py <code> <start> <end>
|
||||
python3 ~/.hermes/scripts/stock_adaptive.py <code> # 自适应
|
||||
python3 ~/.hermes/scripts/stock_ma20_backtest.py # 茅台MA20回测,结果存档
|
||||
# 输出:ma20_result_{code}.json → 被 stock_portfolio.py 读取做金叉置信度
|
||||
```
|
||||
|
||||
> **MA20 策略回测结果(2026-07-12 实测)**:
|
||||
> - 贵州茅台(600519):α=+6.05%,胜率22.2%,最大回撤26.2%,27次交易 → 策略跑赢买入持有6.05%
|
||||
> - 策略价值:减少亏损,在高位震荡期频繁被套但单次亏损控制得好
|
||||
> - 五粮液(000858):α=+39.2%(历史数据充足时更高)
|
||||
>
|
||||
> **金叉置信度集成(2026-07-12)**:`stock_portfolio.py` 发现金叉时,自动读取 `~/.hermes/stock_backtest/ma20_result_{code}.json`,推送时附一行 `历史胜率X% α+Y% 最大回撤Z%`。当前:茅台已集成,五粮液待跑回测存档。
|
||||
|
||||
**Step 3 — 信号: 每日推送**
|
||||
```bash
|
||||
python3 ~/.hermes/scripts/stock_signal.py # 五粮液专用信号
|
||||
python3 ~/.hermes/scripts/stock_portfolio.py # 7只股票组合扫描(⭐今日发现茅台金叉)
|
||||
python3 ~/.hermes/scripts/stock_portfolio.py # 7只股票组合扫描
|
||||
python3 ~/.hermes/scripts/stock_portfolio.py --push # 推飞书
|
||||
```
|
||||
- 金叉时自动读取 `~/.hermes/stock_backtest/ma20_result_{code}.json`,附加:历史胜率 / α / 最大回撤
|
||||
- cron `f3619a71aebb`(周一~五 08:00)跑 `stock_portfolio.py`
|
||||
|
||||
自动cron:
|
||||
- `c48bbbb4fd18` 五粮液每日16:00信号
|
||||
- `c293eead6688` 7只股票每日09:00组合扫描
|
||||
- `f3619a71aebb` 7只股票每日组合扫描(工作日08:00,调用 stock_portfolio.py)
|
||||
|
||||
**Step 4 — 模拟交易**
|
||||
```bash
|
||||
|
|
@ -122,7 +152,7 @@ Also add `--compressed` flag — without it, ifzq API returns empty from that di
|
|||
| Code | Name | Best Strategy |
|
||||
|------|------|-------------|
|
||||
| 000858 | 五粮液 | MA20突破 (α=+39.2%) |
|
||||
| 600519 | 贵州茅台 | MA20突破 (α=+4.2%) |
|
||||
| 600519 | 贵州茅台 | MA20突破 (α=+6.05%, 胜率22.2%, 最大回撤26.2%) |
|
||||
| 000001 | 平安银行 | MACD (α=+3.6%) |
|
||||
| 300750 | 宁德时代 | 买入持有 (策略有害) |
|
||||
| 510300 | 沪深300ETF | 买入持有 (策略干扰) |
|
||||
|
|
@ -132,16 +162,54 @@ Also add `--compressed` flag — without it, ifzq API returns empty from that di
|
|||
- **akshare import timeout**: Do NOT import akshare at script startup (causes 120s+ hang). Use lazy import after timeout guards, or use Tencent/ifzq API instead.
|
||||
- **Simple scoring fails**: 技术超跌+基本面低估 scores as negative if you just sum — it should be 逆向机会. Use combo scoring logic.
|
||||
- **Adaptive strategy neutral**: ADX-based switching averaged α=-0.5% across 5 stocks. Don't rely on it as primary strategy.
|
||||
- **urllib hangs from ~/.hermes/scripts**: `urllib.request.urlopen()` returns empty when called from the `~/.hermes/scripts/` directory (SSL/compression issue). Always use curl subprocess instead.
|
||||
- **urllib hangs from ~/.hermes/scripts**: `urllib.request.urlopen()` hangs indefinitely when called from `~/.hermes/scripts/` (SSL/compression negotiation issue — not network). Affected: `stock_news.py` (broken → 60s timeout). Fix: use curl subprocess. Pattern to use:
|
||||
```python
|
||||
import subprocess, os
|
||||
def get_url(url, timeout=5, enc="utf-8"):
|
||||
env = dict(os.environ)
|
||||
for k in ["http_proxy", "https_proxy", "HTTP_PROXY", "HTTPS_PROXY"]:
|
||||
env.pop(k, None)
|
||||
r = subprocess.run(["curl", "-s", "--max-time", str(timeout), url],
|
||||
capture_output=True, timeout=timeout+2, env=env)
|
||||
return r.stdout.decode(enc, errors="ignore")
|
||||
```
|
||||
**Note**: `stock_portfolio.py` uses `get_url_gbk()` which already uses curl → works fine. `stock_news.py` used bare `urllib` → broken. Always use curl from this directory.
|
||||
- **Missing --compressed flag**: ifzq API returns `v_pv_none_match` without `--compressed`. Always include `--compressed` in curl command.
|
||||
- **API date format**: Must use `YYYY-MM-DD`, NOT `YYYYMMDD`. Returns `param error` with wrong format.
|
||||
- **Weekend data gap**: API only returns up to last trading day (Fri data on Sun). Always request `days * 1.8` calendar days, then slice the last `min_needed` rows sorted by date.
|
||||
- **K线数据质量不验证**: `stock_portfolio.py` 的 `analyze_ma20()` 原来只检查 `len(klines) >= 25`,不检查数据内容是否有效。修复后 `validate_klines()` 过滤价格为0或异常的记录,确保MA20计算基础可靠。新写的任何获取K线数据的脚本都要先过 validate_klines。
|
||||
- **原油数据解析**: `hf_OIL` 返回格式为 `v_hf_OIL="75.23,-1.40,75.22,75.27,77.52,75.22,05:59:59,76.30,76.15,0,77,2,2026-07-11,文字"`(无 `~` 分隔符,用 `,` 分隔,parts[7]=昨收)。不能用 `parts[3].split("~")` 的通用逻辑。
|
||||
- **汇率/美债数据源不可用**: 腾讯/新浪的 `usdcnh`, `gb_tnx` 等代码均返回 `v_pv_none_match`。宏观面已改用沪深300作为大盘风险代理。
|
||||
- **东方财富新闻API ann_type**: 个股公告接口 `np-anotice-stock.eastmoney.com` 的 `ann_type` 参数要用 `SZA`(不是 `SHS`)。`SHS` 返回 `total_hits=0`,`SZA` 能查到真实公告(分红/回购等),可解析 `notice_date` 和 `title` 字段。完整URL格式: `https://np-anotice-stock.eastmoney.com/api/security/ann?sr=-1&page_size=3&page_index=1&ann_type=SZA&stock_list={code}`。
|
||||
- **行业新闻API全部失效**: `search-api-web.eastmoney.com` 搜索接口(JSONP格式)在此网络环境下返回空。已实现回退:用行业指数(白酒=sh000858、银行=sh000001)涨跌作为行业情绪代理。
|
||||
- **cron no_agent script 不支持参数**: `no_agent=True` 的 cron job 的 `script` 字段只能是纯脚本名(无空格、无参数)。如果原命令是 `python3 x.py report`,必须创建包装 shell 脚本。例如:
|
||||
```bash
|
||||
# ❌ 错误:script: "proactive_learning.py report"
|
||||
# ✅ 正确:创建 wrapper 脚本
|
||||
# optimizer-report.sh:
|
||||
# #!/bin/bash
|
||||
# cd ~/.hermes/scripts && python3 optimizer.py report
|
||||
```
|
||||
验证方式:`bash wrapper.sh` 能直接输出结果即正确。已确认需要包装的脚本:`optimizer.py report`、`proactive_learning.py report`。
|
||||
- **消息被截断**: 飞书/网络传输大文本块可能被截断成乱码。此时不要反复重发,应立即用 `read_file` 定位脚本路径,不要等待对方重发。
|
||||
- **First attempt failure ≠ can't do it**: When a script fails, a URL returns empty, stderr pollutes stdout, or a tool reports an error — try at least 2 more approaches before saying "I can't". Patterns that work:
|
||||
- stderr pollutes stdout → redirect stderr to `/dev/null` or a file
|
||||
- urllib hangs → switch to `curl` subprocess
|
||||
- akshare times out → use Tencent/ifzq API instead
|
||||
- Empty API response → check date format (must be `YYYY-MM-DD`, not `YYYYMMDD`), or request more calendar days
|
||||
- stderr/stdout mixing in subprocess → `exec 2>/dev/null` or pipe through `cat > /dev/null`
|
||||
- **OpenClaw MCP 集成 (2026-07-12 验证)**:OpenClaw 作为独立 agent 系统,有 5 人团队(A01~A05)和 164 个技能。通过 MCP 连接到 Hermes 后,可通过 9 个工具(conversations_list/messages_read/messages_send 等)向 OpenClaw 派发任务。结果存档在 `~/.hermes/stock_backtest/` 供后续读取。
|
||||
- **OpenClaw vs OpenCode 使用场景**:
|
||||
- OpenCode:快的、一次性的、不需要记忆的代码执行
|
||||
- OpenClaw:需要跨 session 记忆、专属技能(浏览器自动化/深度研究)、多 agent 协作、定时任务
|
||||
|
||||
## References
|
||||
|
||||
- `references/backtest-results.md` — 5只股票完整回测数据
|
||||
- `references/ma20-kweichow-20260712.md` — 茅台MA20策略回测结果(2026-07-12 新增)
|
||||
- `references/scoring-logic.md` — 组合评分逻辑详解
|
||||
- `references/data-api.md` — 腾讯/ifzq API接口文档
|
||||
- `references/playwright-environment.md` — Playwright EPIPE崩溃/滑块验证码/内容提取(2026-07-12)
|
||||
- `references/news-and-paper-trading.md` — 新闻监控+模拟交易操作手册
|
||||
|
||||
## 10只股票四维扫描结论(2026-07-12)
|
||||
|
|
@ -171,7 +239,11 @@ Also add `--compressed` flag — without it, ifzq API returns empty from that di
|
|||
|
||||
## Next Steps
|
||||
|
||||
1. **贵州茅台MA20金叉**(2026-07-12): 价格1204.98 > MA20=1201.34,偏离+0.3% → 等牧尘确认是否买入模拟账户
|
||||
2. 等MA20金叉 → `python3 stock_paper.py buy <价格>` 模拟买入
|
||||
3. 五粮液/茅台金叉 → 推飞书通知牧尘确认
|
||||
4. 验证纸上盈利与MA20策略回测α一致(目标>10%)
|
||||
1. ✅ **贵州茅台MA20回测**(2026-07-12): α=+6.05%,胜率22.2%,最大回撤26.2% → 结果已存档 `~/.hermes/stock_backtest/ma20_result_600519.json`
|
||||
2. ✅ **MA20回测置信度集成**(2026-07-12): `stock_portfolio.py` 金叉推送时自动读取回测结果,附历史胜率/α/最大回撤
|
||||
3. ✅ **OpenClaw MCP 集成**(2026-07-12): Hermes gateway 已接入 OpenClaw MCP,9工具可用(conversations_list/messages_send等),配置持久化到 `~/.hermes/config.yaml`
|
||||
4. ⬜ **五粮液MA20回测**:当前空仓,回测数据应提前存档至 `~/.hermes/stock_backtest/ma20_result_000858.json`
|
||||
5. 等MA20死叉 → `python3 stock_paper.py sell <价格>` 模拟卖出
|
||||
6. **真实交易**:牧尘确认风控参数后启动(最大回撤/仓位/禁止品种由牧尘定)
|
||||
7. **扩大股票池**:泸州老窖(000568)、洋河股份(002304) 也已满足逆向机会条件,可加入每日扫描并做MA20回测
|
||||
8. **TencentDB Agent Memory 深入研究**:8603 stars,4层渐进管道+符号化压缩,值得研究其与织忆的融合可能
|
||||
|
|
@ -52,22 +52,23 @@ GET https://qt.gtimg.cn/q={mc}
|
|||
- `[39]`: PE
|
||||
- `[46]`: PB
|
||||
|
||||
## ⚠️ 关键陷阱(今晚发现的)
|
||||
## ⚠️ 关键陷阱
|
||||
|
||||
### 1. urllib从~/.hermes/scripts目录调用返回空
|
||||
从 `~/.hermes/scripts` 目录调用 `urllib.request.urlopen()` 时,SSL握手异常,返回空文本。不从该目录运行或在脚本内用curl子进程可以绕过。
|
||||
### 1. urllib从~/.hermes/scripts目录调用返回空/超时
|
||||
从 `~/.hermes/scripts` 目录调用 `urllib.request.urlopen()` 时,SSL/压缩协商异常,会**无限期阻塞**(不是返回空,是直接hang)。受影响脚本:`stock_news.py`(修复前60s超时)。
|
||||
|
||||
**正确做法**:在脚本内用curl子进程,永远不用urllib:
|
||||
**正确做法**:在脚本内用 curl 子进程,永远不用 urllib:
|
||||
```python
|
||||
import subprocess, shlex, os
|
||||
def get_url(url, timeout=8):
|
||||
import subprocess, os
|
||||
def get_url(url, timeout=5, enc="utf-8"):
|
||||
env = dict(os.environ)
|
||||
for k in ["http_proxy", "https_proxy", "HTTP_PROXY", "HTTPS_PROXY"]:
|
||||
env.pop(k, None)
|
||||
cmd = f"curl -s --max-time {timeout} --compressed {shlex.quote(url)}"
|
||||
r = subprocess.run(cmd, shell=True, capture_output=True, timeout=timeout+2, env=env)
|
||||
return r.stdout.decode("utf-8", errors="ignore")
|
||||
r = subprocess.run(["curl", "-s", "--max-time", str(timeout), url],
|
||||
capture_output=True, timeout=timeout+2, env=env)
|
||||
return r.stdout.decode(enc, errors="ignore")
|
||||
```
|
||||
`stock_portfolio.py` 的 `get_url_gbk()` 已用 curl → 无此问题。新写脚本一律用此模式。
|
||||
|
||||
### 2. 必须加--compressed参数
|
||||
不加`--compressed`,ifzq API返回`v_pv_none_match="1"`(不是空,而是错误标记)。
|
||||
|
|
@ -76,9 +77,22 @@ def get_url(url, timeout=8):
|
|||
用`YYYYMMDD`格式API返回`{"code":0,"msg":"param error","data":[]}`
|
||||
|
||||
### 4. 周末数据只到上一个交易日
|
||||
API不返回非交易日数据。周日调用只能拿到周五数据。**请求时使用`days * 1.8`个日历天**,确保有足够多的交易日:
|
||||
API不返回非交易日数据。周日调用只能拿到周五数据。**请求时使用`days * 1.8`个日历天**,确保有足够多的交易日。
|
||||
|
||||
### 5. hf_OIL原油格式特殊(无~分隔符)
|
||||
`hf_OIL` 返回格式为:
|
||||
```
|
||||
v_hf_OIL="75.23,-1.40,75.22,75.27,77.52,75.22,05:59:59,76.30,76.15,0,77,2,2026-07-11,文字"
|
||||
```
|
||||
**不是** `~` 分隔,是 `,` 分隔。昨收在 `parts[7]`(不是 `parts[4]`)。
|
||||
正确解析:
|
||||
```python
|
||||
start_d = end_d - timedelta(days=int(min_needed * 1.8))
|
||||
if "=" in text:
|
||||
val_part = text.split("=", 1)[1].strip('"; \n')
|
||||
vals = val_part.split(",")
|
||||
if len(vals) >= 8:
|
||||
price = float(vals[0])
|
||||
yclose = float(vals[7])
|
||||
```
|
||||
|
||||
## Python调用封装(已验证可用)
|
||||
|
|
@ -119,7 +133,8 @@ def get_kline(code, min_needed=60):
|
|||
| 问题 | 原因 | 解决方案 |
|
||||
|------|------|---------|
|
||||
| API返回`v_pv_none_match` | 缺少`--compressed` | curl加`--compressed` |
|
||||
| urllib返回空(从scripts目录) | SSL/压缩异常 | 用curl子进程,不使用urllib |
|
||||
| urllib hang/超时(从scripts目录) | SSL/压缩协商异常 | 用curl子进程,不使用urllib |
|
||||
| API返回`param error` | 日期格式错误(YYYYMMDD) | 改为YYYY-MM-DD |
|
||||
| 周末数据只有周五的 | 非交易日无数据 | 请求`days*1.8`日历天,取最后`min_needed`条 |
|
||||
| USD/CNH查询返回none_match | token变了 | 汇率判断改用沪深300替代 |
|
||||
| USD/CNH查询返回none_match | 腾讯/新浪无此代码 | 汇率判断改用沪深300替代 |
|
||||
| `hf_OIL`原油"获取失败" | 格式无`~`分隔,昨收在parts[7] | 用`split("=",1)[1].split(",")`解析,parts[7]=昨收 |
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# 茅台 MA20 策略回测 — 2026-07-12
|
||||
|
||||
## 贵州茅台(600519) MA20突破策略回测结果
|
||||
|
||||
| 指标 | 值 |
|
||||
|------|-----|
|
||||
| 数据区间 | 2024-06-24 ~ 2026-07-10 |
|
||||
| 策略收益 | **-9.60%** |
|
||||
| 买入持有 | -15.65% |
|
||||
| 超额收益 α | **+6.05%** ✅ |
|
||||
| 最大回撤 | 26.17% |
|
||||
| 交易次数 | 27 次 |
|
||||
| 胜率 | 22.2% |
|
||||
| 金叉次数 | 28 |
|
||||
| 死叉次数 | 28 |
|
||||
| 当前持仓 | 是(7/10 金叉买入,价格 1204.98)|
|
||||
|
||||
## 解读
|
||||
|
||||
- 策略跑赢买入持有 6.05%,减少亏损
|
||||
- 茅台高位震荡,MA20 频繁金叉死叉 → 胜率低(22.2%)但单次亏损控制好
|
||||
- 策略有效减少了最大回撤(26.2% vs 买入持有更大跌幅)
|
||||
- 当前持仓:75股@1204.98,等死叉信号
|
||||
|
||||
## 与五粮液对比
|
||||
|
||||
| 指标 | 五粮液(000858) | 贵州茅台(600519) |
|
||||
|------|--------------|----------------|
|
||||
| 数据起点 | 2023-01 | 2024-06(API限制) |
|
||||
| α (vs 买入持有) | +39.2% | +6.05% |
|
||||
| 胜率 | 较高 | 22.2% |
|
||||
| 最大回撤 | 更小 | 26.2% |
|
||||
| 当前状态 | 空仓 | 持仓中 |
|
||||
|
||||
五粮液 MA20 策略效果更好(α=+39.2%),茅台更适合买入持有或更长周期策略。
|
||||
|
||||
## 脚本
|
||||
|
||||
`~/.hermes/scripts/stock_ma20_backtest.py` — 腾讯/ifzq K线数据,MA20 金叉/死叉信号,支持任意 A 股。
|
||||
|
||||
用法:
|
||||
```bash
|
||||
python3 ~/.hermes/scripts/stock_ma20_backtest.py # 默认茅台
|
||||
```
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# Playwright 执行环境 — 已知坑(2026-07-12 实测)
|
||||
|
||||
## EPIPE 崩溃:用系统 python3 调 Playwright
|
||||
|
||||
**症状**:
|
||||
```python
|
||||
# ❌ 用系统 python3 运行 Playwright → EPIPE 崩溃
|
||||
python3 -c "from playwright.sync_api import sync_playwright; ..."
|
||||
# Error: write EPIPE
|
||||
# at afterWriteDispatched (node:internal/stream_base_commons:159:15)
|
||||
```
|
||||
|
||||
**根因**:hermes-agent 的 venv 里装了 `playwright` 包(含 Node.js driver),系统 python3 的 `playwright` CLI 是另一个版本,两者不兼容。
|
||||
|
||||
**解法**:用 hermes-agent venv 的 python3:
|
||||
```bash
|
||||
# ❌ 错误
|
||||
python3 -c "from playwright.sync_api import sync_playwright; ..."
|
||||
/home/muc/.hermes/hermes-agent/.venv/bin/python3 -c "from playwright.sync_api import sync_playwright; ..."
|
||||
```
|
||||
|
||||
在 `execute_code` 工具里调用 Playwright 时,`subprocess.run(["python3", ...])` 会用系统 python3,需要明确指定路径:
|
||||
```python
|
||||
r = subprocess.run(
|
||||
["/home/muc/.hermes/hermes-agent/.venv/bin/python3", "-c", code],
|
||||
...
|
||||
)
|
||||
```
|
||||
|
||||
## 滑块验证码(极验/腾讯防水墙)
|
||||
|
||||
**已知限制**:即使上了 Playwright/camofox,**滑块验证码无法自动完成**。
|
||||
|
||||
知乎/微信等平台使用极验(GeeTest)或腾讯防水墙滑块,需要真人拖动。自动化方案:
|
||||
1. 预先在真实浏览器导出 cookies(.txt/Netscape格式)→ camofox 导入 → 维持登录态
|
||||
2. 新设备首次登录**必须手动完成一次滑块验证**
|
||||
|
||||
**camofox 知乎 cookies 路径**:`~/.camofox/cookies/zhihu.txt`
|
||||
|
||||
当前状态:camofox 未启动,无现成 cookies。如需自动化登录知乎,先在真实浏览器导出 cookies 到该路径,再启动 camofox。
|
||||
|
||||
## 内容提取备选(绕过 JS 渲染墙)
|
||||
|
||||
| 方式 | 用法 | 对知乎 |
|
||||
|------|------|--------|
|
||||
| `r.jina.ai/<url>` | `curl "https://r.jina.ai/https://..."` | ❌ 返回空 |
|
||||
| `textise dot iitty` | 其他公共服务 | 未测试 |
|
||||
| 浏览器截图 | camofox screenshot | ⚠️ 能打开但拿不到内容 |
|
||||
|
||||
**结论**:知乎内容无法服务端提取,必须走浏览器 + cookies 方案。
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# TencentDB Agent Memory — 研究笔记
|
||||
|
||||
**仓库**: https://github.com/TencentCloud/TencentDB-Agent-Memory
|
||||
**语言**: TypeScript | **Stars**: 8603 | **Fork**: 789
|
||||
**集成**: OpenClaw + Hermes Gateway | **License**: MIT
|
||||
|
||||
## 核心设计理念
|
||||
|
||||
> "Memory is not about hoarding everything — it is about sparing humans from having to repeat themselves."
|
||||
|
||||
两个支柱:
|
||||
1. **Memory Layering** — 分层记忆,拒绝平铺向量存储
|
||||
2. **Symbolic Memory** — 把工具调用日志压缩成 Mermaid 符号
|
||||
|
||||
## 数据对比(vs OpenClaw 无记忆基准)
|
||||
|
||||
| 能力 | Benchmark | 基准 | 加插件 | 提升 |
|
||||
|------|----------|------|--------|------|
|
||||
| 短记忆 | WideSearch | 33% | **50%** | **+51.52%** |
|
||||
| 短记忆 | SWE-bench | 58.4% | **64.2%** | +9.93% |
|
||||
| 短记忆 | AA-LCR | 44.0% | **47.5%** | +7.95% |
|
||||
| 长记忆 | PersonaMem | 48% | **76%** | +59% |
|
||||
| Token节省 | WideSearch | 221M | **86M** | **-61.38%** |
|
||||
|
||||
## 4 层渐进管道
|
||||
|
||||
1. **原始层** — 原始对话/工具日志
|
||||
2. **符号层** — 压缩成 Mermaid 图表
|
||||
3. **分层层** — 按人格/场景组织
|
||||
4. **人格层** — 跨 session 形成稳定人格记忆
|
||||
|
||||
## 与织忆的差异
|
||||
|
||||
| 维度 | 织忆 | TencentDB |
|
||||
|------|------|-----------|
|
||||
| 短记忆 | 原始累积 | **符号化 Mermaid** |
|
||||
| 长记忆 | 向量检索+图谱 | **分层人格/场景** |
|
||||
| 外部依赖 | bge/PG | **零依赖** |
|
||||
| Token 节省 | — | 最高 61% |
|
||||
|
||||
## 对织忆的参考价值
|
||||
|
||||
1. **Mermaid 符号压缩** — 工具日志→符号→节省 token
|
||||
2. **4 层渐进 vs 平铺** — 织忆图谱+记忆双层,可思考符号化中间层
|
||||
3. **明确评测基准** — 织忆缺 benchmark,TencentDB 有 WideSearch/SWE-bench 等
|
||||
4. **OpenClaw 集成** — 它的插件是现成的,可直接研究
|
||||
|
||||
## Status
|
||||
|
||||
2026-07-12 牧尘分享,待深入研究。
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
tags: [zhiyi]
|
||||
name: zhiyi
|
||||
description: "织忆 (MemoryWeave) 聚合技能 — API 客户端 + 开发工作流 + 运维规范。含 commit/recall API、数据架构、部署验证、Go 方法论。"
|
||||
version: 11.31
|
||||
version: 11.32
|
||||
author: 小唯 A06
|
||||
updated: 2026-07-10(D-G Phase 修复 + opencode审查局限性 + backup.sh/restore.sh + check_cares飞书卡片修复)
|
||||
updated: 2026-07-12(TencentDB Agent Memory 研究 + 三层记忆架构 + Soulful/织忆/TencentDB 分工明确)
|
||||
---
|
||||
|
||||
> ⚡ 2026-06-25:**全面失忆事故复盘 + 完整修复** — 见末尾「2026-06-25 失忆-恢复章节」。
|
||||
|
|
@ -633,6 +633,109 @@ python3 -c "from plugins.memory.zhiyi import HermesZhiYiMemoryProvider; \
|
|||
|
||||
---
|
||||
|
||||
> 更新:2026-07-12:**TencentDB Agent Memory 安装研究 + 三层记忆架构梳理**
|
||||
> - TencentDB(8603 stars,4层渐进管道)补的是 Soulful 的「自动人格蒸馏」那块,不是织忆的语义检索
|
||||
> - 织忆/Soulful/TencentDB 三者各有分工,不是替代关系
|
||||
> - 详见 `references/tencentdb-agent-memory-20260712.md`
|
||||
> - Soulful 与织忆关系:`references/soulful-zhiyi-integration.md`
|
||||
|
||||
## 三层记忆系统 vs 织忆 + Soulful + TencentDB
|
||||
|
||||
| 系统 | 解决的问题 | 存储介质 | 状态 |
|
||||
|------|---------|---------|------|
|
||||
| **织忆 (ZhiYi)** | 语义记忆(项目/技术/对话) | LanceDB(3292条) | ✅ 独立 Go 服务,:7821 |
|
||||
| **Soulful** | 关系记忆(心迹/牵挂/画像) | JSONL,daemon 自动跑 | ✅ daemon 一部分 |
|
||||
| **TencentDB Agent Memory** | **缺失的那块**:人格分层自动蒸馏 | SQLite + sqlite-vec | ⚠️ Gateway 已在跑:L0成功,L1 pipeline 待调 |
|
||||
| **Soulful 手动关系记忆**(已有) | 手动记录心迹 | JSONL | ✅ |
|
||||
| **TencentDB 自动人格蒸馏**(补) | 自动从对话提炼牧尘偏好模式 | SQLite | 建设中 |
|
||||
|
||||
**Soulful vs TencentDB 的区别**:
|
||||
- Soulful = 手动关系记忆(我主动记录心迹、牵挂、观察到的偏好)
|
||||
- TencentDB = 自动人格蒸馏(从连续对话自动生成 persona 文件,不靠我手动记)
|
||||
- 两者是互补的:Soulful 让我主动观察,TencentDB 让系统自动学习
|
||||
|
||||
**TencentDB 补的不是织忆,补的是 Soulful 的自动化能力**:
|
||||
```
|
||||
Soulful(现在) 手动记录心迹 → 关系记忆
|
||||
↓
|
||||
TencentDB(补) 自动从对话蒸馏 → Persona(人格文件)
|
||||
↓
|
||||
效果:我说"牧尘不喜欢废话"不需要每次解释
|
||||
```
|
||||
|
||||
**TencentDB Agent Memory 集成状态(2026-07-12)**:
|
||||
- npm 安装:✅(npmmirror 镜像,16s)
|
||||
- Gateway 进程:✅(:8420,独立 Node.js)
|
||||
- embedding:✅(走 bge-m3 8000 端口,`sendDimensions: false`)
|
||||
- LLM:✅(走 mistral-large-3-675b via NewAPI 3000)
|
||||
- L0 capture:✅(能写对话记录)
|
||||
- L1 提取:⚠️(pipeline worker 消费了任务但 l1_records=0,需排查)
|
||||
- BM25 搜索:✅(能搜到对话)
|
||||
- Embedding 搜索:✅(strategy=embedding)
|
||||
- recall/search/memories:✅(返回空是因为没数据)
|
||||
- `/search/conversations`:✅(BM25 模式正常)
|
||||
- **关键配置格式**:`memory.embedding.*`(嵌套结构,不是顶层 embedding)
|
||||
|
||||
**TencentDB 配置格式(实测有效)**:
|
||||
```yaml
|
||||
# ~/.memory-tencentdb/memory-tdai/tdai-gateway.yaml
|
||||
llm:
|
||||
baseUrl: http://127.0.0.1:3000/v1
|
||||
apiKey: not-needed
|
||||
model: mistral-large-3-675b
|
||||
|
||||
memory:
|
||||
embedding:
|
||||
provider: openai # 不是 "none"
|
||||
baseUrl: http://127.0.0.1:8000/v1
|
||||
apiKey: not-needed
|
||||
model: bge-m3
|
||||
dimensions: 1024
|
||||
sendDimensions: false # bge-m3 不支持 matryoshka
|
||||
|
||||
vectorDb:
|
||||
type: sqlite-vec
|
||||
|
||||
server:
|
||||
port: 8420
|
||||
|
||||
deployMode: standalone
|
||||
```
|
||||
|
||||
启动:`TDAI_GATEWAY_CONFIG=/home/muc/.memory-tencentdb/memory-tdai/tdai-gateway.yaml npx tsx src/gateway/server.ts`
|
||||
|
||||
**结论**:TencentDB 可以作为独立的人格记忆补充,Gateway 跑着,通过 HTTP `/search/conversations` 获取牧尘偏好模式。当前 L1 提取有问题,BM25 够用但 embedding 检索待修复。
|
||||
|
||||
## 系统三层记忆架构(完整视图)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 牧尘的对话输入 │
|
||||
└─────────────────┬───────────────────────────┘
|
||||
│
|
||||
┌─────────┴──────────┐
|
||||
▼ ▼
|
||||
┌──────────────┐ ┌──────────────────────────┐
|
||||
│ 织忆 (ZhiYi) │ │ TencentDB Agent Memory │
|
||||
│ 语义检索 │ │ L0对话 → L1提取 → L2场景 │
|
||||
│ 5766节点 │ │ L3人格自动蒸馏 │
|
||||
│ LanceDB │ │ SQLite+sqlite-vec │
|
||||
└──────────────┘ └──────────────────────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Soulful(daemon) │
|
||||
│ 心迹/牵挂/画像(手动观察层) │
|
||||
│ → 注入 prefetch:summarize() 接口 │
|
||||
│ → 关系记忆显影,不是优化机制 │
|
||||
└─────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 小唯的上下文(prefetch 注入) │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 2026-06-25 失忆-恢复章节
|
||||
|
||||
**触发**:用户升级 hermes 到 v0.17.0 后,问「织忆系统与升级后冲突不?有没有受限或者失效的功能?」。本次回答完全失忆——基于过期的 AGENTS.md(v3.1,2026-05-24)回答「织忆是设计阶段 / opencode 执行中」,完全忽略织忆 6-15 已上线、6-20 已通过代码审计的事实。
|
||||
|
|
|
|||
|
|
@ -0,0 +1,155 @@
|
|||
# TencentDB Agent Memory — 安装调试笔记(2026-07-12)
|
||||
|
||||
## 概览
|
||||
|
||||
- **仓库**: TencentCloud/TencentDB-Agent-Memory,8603 stars,TypeScript
|
||||
- **用途**: 4层渐进记忆管道(L0对话→L1提取→L2场景→L3人格合成)+ Mermaid 符号压缩工具日志
|
||||
- **与织忆的关系**: 补 Soulful 的「自动人格蒸馏」,不是替代织忆语义检索
|
||||
- **当前状态**: Gateway 跑在 :8420,L0/BM25/embedding 基本通,L1 提取待调
|
||||
|
||||
## 安装步骤(国内环境)
|
||||
|
||||
```bash
|
||||
# 1. 创建目录
|
||||
mkdir -p ~/.memory-tencentdb && cd ~/.memory-tencentdb
|
||||
npm init -y --silent
|
||||
|
||||
# 2. 安装(npm 国内慢,用 npmmirror)
|
||||
npm install @tencentdb-agent-memory/memory-tencentdb@latest \
|
||||
--omit=dev --registry https://registry.npmmirror.com
|
||||
|
||||
# 3. 复制插件
|
||||
cp -r node_modules/@tencentdb-agent-memory/memory-tencentdb \
|
||||
~/.memory-tencentdb/tdai-memory-openclaw-plugin
|
||||
|
||||
# 4. 安装依赖
|
||||
cd ~/.memory-tencentdb/tdai-memory-openclaw-plugin
|
||||
npm install --omit=dev --registry https://registry.npmmirror.com
|
||||
npm install tsx --omit=dev --registry https://registry.npmmirror.com
|
||||
|
||||
# 5. 创建 Gateway 配置文件(见 SKILL.md 主文档)
|
||||
```
|
||||
|
||||
## 调试过程记录
|
||||
|
||||
### 问题1:配置格式错误(YAML vs JSON vs 嵌套结构)
|
||||
|
||||
**现象**: `embedding=disabled`,Gateway 日志显示 `dimensions=0`
|
||||
|
||||
**根因**: 尝试了多种格式都不对:
|
||||
- 顶层 `embedding.*` → 不认
|
||||
- 顶层 `llm.*` + 顶层 `embedding.*` → LLM 生效但 embedding 不生效
|
||||
- 正确格式:**`memory.embedding.*`**(embedding 必须嵌套在 `memory:` 下)
|
||||
|
||||
**正确配置**:
|
||||
```yaml
|
||||
llm:
|
||||
baseUrl: http://127.0.0.1:3000/v1
|
||||
apiKey: not-needed
|
||||
model: mistral-large-3-675b
|
||||
|
||||
memory:
|
||||
embedding:
|
||||
provider: openai
|
||||
baseUrl: http://127.0.0.1:8000/v1
|
||||
apiKey: not-needed
|
||||
model: bge-m3
|
||||
dimensions: 1024
|
||||
sendDimensions: false # bge-m3 不支持 matryoshka
|
||||
```
|
||||
|
||||
### 问题2:bge-m3 sendDimensions
|
||||
|
||||
**现象**: embedding 请求返回 400 "does not support matryoshka representation"
|
||||
|
||||
**根因**: bge-m3 不支持 OpenAI 的 `dimensions` 字段(Matryoshka 表示)
|
||||
|
||||
**修复**: `sendDimensions: false`
|
||||
|
||||
### 问题3:进程端口冲突
|
||||
|
||||
**现象**: `EADDRINUSE: address already in use 127.0.0.1:8420`
|
||||
|
||||
**修复**:
|
||||
```bash
|
||||
fuser -k 8420/tcp # 杀占用进程
|
||||
# 然后重启
|
||||
```
|
||||
|
||||
### 问题4:配置路径(~ 未展开)
|
||||
|
||||
**现象**: `TDAI_GATEWAY_CONFIG=~/.memory-tencentdb/...yaml` 无效
|
||||
|
||||
**修复**: 用绝对路径
|
||||
```bash
|
||||
TDAI_GATEWAY_CONFIG=/home/muc/.memory-tencentdb/memory-tdai/tdai-gateway.yaml
|
||||
```
|
||||
|
||||
## API 端点
|
||||
|
||||
| 端点 | 方法 | 用途 | 状态 |
|
||||
|------|------|------|------|
|
||||
| `/health` | GET | 健康检查 | ✅ |
|
||||
| `/capture` | POST | 记录对话(L0) | ✅ |
|
||||
| `/recall` | POST | 4层检索(需 L1+) | ⚠️ 返回空(无数据) |
|
||||
| `/search/memories` | POST | embedding 搜索 | ⚠️ 返回空(无 L1 数据) |
|
||||
| `/search/conversations` | POST | BM25 搜索 | ✅ 能搜到对话 |
|
||||
| `/session/end` | POST | 结束 session | — |
|
||||
|
||||
## 数据流验证
|
||||
|
||||
```bash
|
||||
# 1. 灌测试对话
|
||||
curl -X POST http://127.0.0.1:8420/capture \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"session_key":"test","user_content":"我不喜欢废话","assistant_content":"好的"}'
|
||||
|
||||
# 2. 等 pipeline 处理(Worker 应有 tasksCompleted 递增)
|
||||
|
||||
# 3. BM25 搜索(有效)
|
||||
curl -s -X POST http://127.0.0.1:8420/search/conversations \
|
||||
-d '{"query":"牧尘 风格"}'
|
||||
|
||||
# 4. 看 worker 状态
|
||||
curl -s http://127.0.0.1:8420/health | python3 -c "
|
||||
import json,sys; d=json.load(sys.stdin)
|
||||
print('Worker:', d['services']['pipelineWorker'])
|
||||
"
|
||||
```
|
||||
|
||||
## 数据库位置
|
||||
|
||||
- SQLite: `~/.memory-tencentdb/memory-tdai/memory.db`(空,metadata)
|
||||
- 向量库: `~/.memory-tencentdb/memory-tdai/vectors.db`
|
||||
- 对话记录: `~/.memory-tencentdb/memory-tdai/conversations/`
|
||||
- 场景块: `~/.memory-tencentdb/memory-tdai/scene_blocks/`
|
||||
- records: `~/.memory-tencentdb/memory-tdai/records/`
|
||||
|
||||
## L1 提取问题
|
||||
|
||||
**现象**: Worker `tasksConsumed=2, tasksCompleted=2` 但 `l1_records=0`
|
||||
|
||||
**可能原因**: LLM 调用失败或 pipeline 逻辑问题
|
||||
|
||||
**诊断**:
|
||||
```bash
|
||||
sqlite3 ~/.memory-tencentdb/memory-tdai/vectors.db \
|
||||
"SELECT COUNT(*) FROM l0_conversations;" # 应>0
|
||||
sqlite3 ~/.memory-tencentdb/memory-tdai/vectors.db \
|
||||
"SELECT COUNT(*) FROM l1_records;" # 应>0
|
||||
```
|
||||
|
||||
**当前 workaround**: BM25 搜索已够用(`/search/conversations`)
|
||||
|
||||
## 与织忆的关系
|
||||
|
||||
TencentDB 的价值不在于替代织忆,而在于:
|
||||
|
||||
1. **4层渐进管道**:L0原始对话 → L1语义提取 → L2场景块 → L3人格合成
|
||||
2. **Mermaid 符号压缩**:工具日志压缩成图,减少 61% token
|
||||
3. **人格自动蒸馏**:连续对话 → 自动生成牧尘 persona 文件
|
||||
|
||||
三个系统的分工:
|
||||
- 织忆 = 语义检索(已回答"我们做过什么")
|
||||
- Soulful = 关系记忆(已回答"我在意什么")
|
||||
- TencentDB = 人格自动学习(将回答"牧尘的工作流习惯是什么")
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"version": 1,
|
||||
"updated_at": "2026-07-11T14:00:57.385434+00:00",
|
||||
"updated_at": "2026-07-12T14:00:22.422065+00:00",
|
||||
"communication_style": "简洁直接",
|
||||
"work_patterns": {
|
||||
"peak_hours": [],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,241 @@
|
|||
{
|
||||
"code": "600519",
|
||||
"start": "2025-01-01",
|
||||
"end": "2026-07-12",
|
||||
"adaptive": {
|
||||
"final": 93713.19,
|
||||
"return": -6.286809999999998,
|
||||
"buyhold": -14.444494145563223,
|
||||
"alpha": 8.157684145563223,
|
||||
"max_dd": 7.664876752765766,
|
||||
"total_trades": 15,
|
||||
"ma20_trades": 11,
|
||||
"macd_trades": 4,
|
||||
"winrate": 100.0,
|
||||
"stop_loss_triggered": 0,
|
||||
"trades": [
|
||||
[
|
||||
"BUY",
|
||||
"2025-04-17",
|
||||
20,
|
||||
1490.419,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2025-04-21",
|
||||
20,
|
||||
1471.419,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2025-05-08",
|
||||
19,
|
||||
1498.609,
|
||||
"MACD_RANGE"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2025-05-23",
|
||||
19,
|
||||
1493.019,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2025-07-04",
|
||||
21,
|
||||
1370.239,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2025-07-07",
|
||||
21,
|
||||
1358.719,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2025-07-08",
|
||||
21,
|
||||
1364.129,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2025-07-15",
|
||||
21,
|
||||
1359.019,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2025-07-17",
|
||||
21,
|
||||
1364.369,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2025-07-31",
|
||||
21,
|
||||
1369.689,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2025-08-11",
|
||||
21,
|
||||
1393.019,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2025-09-18",
|
||||
21,
|
||||
1415.979,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2025-10-16",
|
||||
20,
|
||||
1432.929,
|
||||
"MACD_RANGE"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2025-10-24",
|
||||
20,
|
||||
1398.019,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2025-11-10",
|
||||
21,
|
||||
1410.319,
|
||||
"MACD_RANGE"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2025-11-25",
|
||||
21,
|
||||
1392.669,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2025-12-19",
|
||||
21,
|
||||
1381.976,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2025-12-24",
|
||||
21,
|
||||
1372.876,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2025-12-25",
|
||||
21,
|
||||
1386.146,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2025-12-31",
|
||||
21,
|
||||
1349.156,
|
||||
"MACD_RANGE"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2026-01-05",
|
||||
20,
|
||||
1397.976,
|
||||
"MACD_RANGE"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2026-01-15",
|
||||
20,
|
||||
1360.866,
|
||||
"MACD_RANGE"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2026-01-29",
|
||||
20,
|
||||
1409.696,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2026-03-02",
|
||||
20,
|
||||
1412.086,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2026-03-16",
|
||||
20,
|
||||
1432.156,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2026-03-23",
|
||||
20,
|
||||
1380.046,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2026-03-31",
|
||||
20,
|
||||
1421.976,
|
||||
"MACD_RANGE"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2026-04-17",
|
||||
20,
|
||||
1379.216,
|
||||
"MACD_RANGE"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2026-06-12",
|
||||
22,
|
||||
1263.886,
|
||||
"MA20_TREND"
|
||||
],
|
||||
[
|
||||
"SELL",
|
||||
"2026-06-18",
|
||||
22,
|
||||
1186.976,
|
||||
"MACD_RANGE"
|
||||
],
|
||||
[
|
||||
"BUY",
|
||||
"2026-07-01",
|
||||
23,
|
||||
1193.01,
|
||||
"MACD_RANGE"
|
||||
]
|
||||
]
|
||||
},
|
||||
"benchmark": {
|
||||
"macd": -14.837692000000011,
|
||||
"ma20": -11.423939999999988,
|
||||
"buyhold": -14.444494145563223
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"code": "600519",
|
||||
"name": "贵州茅台",
|
||||
"strategy": "MA20",
|
||||
"period": "2024-06-24 ~ 2026-07-10",
|
||||
"initial_cash": 100000,
|
||||
"final_value": 90402.06400000003,
|
||||
"strategy_return": -9.597935999999972,
|
||||
"buyhold_return": -15.651399999999994,
|
||||
"alpha": 6.053464000000021,
|
||||
"max_drawdown": 26.17300455046467,
|
||||
"total_trades": 27,
|
||||
"win_rate": 22.22222222222222,
|
||||
"trades": "[{'type': 'SELL', 'date': '2026-03-23', 'price': 1380.046, 'shares': 71, 'profit_pct': -3.6385700999053103, 'reason': '死叉'}, {'type': 'BUY', 'date': '2026-03-31', 'price': 1421.976, 'shares': 69, 'reason': '金叉'}, {'type': 'SELL', 'date': '2026-04-13', 'price': 1415.286, 'shares': 69, 'profit_pct': -0.4704720754780709, 'reason': '死叉'}, {'type': 'BUY', 'date': '2026-04-14', 'price': 1418.876, 'shares': 69, 'reason': '金叉'}, {'type': 'SELL', 'date': '2026-04-17', 'price': 1379.216, 'shares': 69, 'profit_pct': -2.795170261530964, 'reason': '死叉'}, {'type': 'BUY', 'date': '2026-04-24', 'price': 1430.466, 'shares': 66, 'reason': '金叉'}, {'type': 'SELL', 'date': '2026-04-27', 'price': 1375.176, 'shares': 66, 'profit_pct': -3.865174006232932, 'reason': '死叉'}, {'type': 'BUY', 'date': '2026-06-12', 'price': 1263.886, 'shares': 72, 'reason': '金叉'}, {'type': 'SELL', 'date': '2026-06-15', 'price': 1243.076, 'shares': 72, 'profit_pct': -1.6465092579552225, 'reason': '死叉'}, {'type': 'BUY', 'date': '2026-07-10', 'price': 1204.98, 'shares': 75, 'reason': '金叉'}]",
|
||||
"in_position": true,
|
||||
"buy_price": 1204.98,
|
||||
"current_price": 1204.98
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
📰 每日宏观+持仓摘要
|
||||
|
||||
【大盘】2026-07-12 09:56
|
||||
📉 上证: 3996.16 (-1.00%)
|
||||
📉 沪深300: 4.83 (-1.77%)
|
||||
📈 五粮液: 73.69 (+3.94%)
|
||||
|
||||
【五粮液持仓信号】⭐ 关注
|
||||
|
||||
📉 布伦特原油: 75.23 (-1.07)
|
||||
【宏观风险提示】
|
||||
• 大盘若跌破关键均线 → 空仓信号加强
|
||||
• 白酒消费数据持续低迷 → 基本面承压
|
||||
• 人民币贬值预期 → 外资流出白酒板块压力
|
||||
|
||||
【五粮液状态】
|
||||
价格: 73.69 (+3.94%)
|
||||
MA20下方 → 空仓信号,等待金叉
|
||||
|
||||
小唯股票投研 · 每日新闻
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"initial_cash": 100000,
|
||||
"final_value": 85162.30799999999,
|
||||
"strategy_return": -14.837692000000011,
|
||||
"buyhold_return": -14.444494145563223,
|
||||
"alpha": -0.3931978544367887,
|
||||
"max_drawdown": 24.8571042432124,
|
||||
"total_trades": 13,
|
||||
"final_value": 81035.66900000004,
|
||||
"strategy_return": -18.964330999999962,
|
||||
"buyhold_return": -13.778311415010839,
|
||||
"alpha": -5.186019584989124,
|
||||
"max_drawdown": 32.61292831854593,
|
||||
"total_trades": 19,
|
||||
"win_rate": 100.0,
|
||||
"trades": "[('BUY', Timestamp('2025-03-06 00:00:00'), 70, 1426.399, 152.07000000000698), ('SELL', Timestamp('2025-03-26 00:00:00'), 70, 1496.419, 104901.40000000001), ('BUY', Timestamp('2025-05-08 00:00:00'), 69, 1498.609, 1497.3790000000154), ('SELL', Timestamp('2025-05-22 00:00:00'), 69, 1500.419, 105026.29000000002), ('BUY', Timestamp('2025-06-26 00:00:00'), 76, 1368.019, 1056.8460000000196), ('SELL', Timestamp('2025-08-01 00:00:00'), 76, 1365.019, 104798.29000000002), ('BUY', Timestamp('2025-08-19 00:00:00'), 75, 1386.019, 846.8650000000198), ('SELL', Timestamp('2025-09-18 00:00:00'), 75, 1415.979, 107045.29000000002), ('BUY', Timestamp('2025-10-16 00:00:00'), 74, 1432.929, 1008.544000000009), ('SELL', Timestamp('2025-10-28 00:00:00'), 74, 1393.019, 104091.95000000001), ('BUY', Timestamp('2025-11-10 00:00:00'), 73, 1410.319, 1138.663000000015), ('SELL', Timestamp('2025-11-26 00:00:00'), 73, 1397.169, 103132.00000000003), ('BUY', Timestamp('2025-12-17 00:00:00'), 74, 1381.119, 929.1940000000322), ('SELL', Timestamp('2025-12-31 00:00:00'), 74, 1349.156, 100766.73800000003), ('BUY', Timestamp('2026-01-05 00:00:00'), 72, 1397.976, 112.4660000000149), ('SELL', Timestamp('2026-01-15 00:00:00'), 72, 1360.866, 98094.81800000001), ('BUY', Timestamp('2026-01-29 00:00:00'), 69, 1409.696, 825.7940000000235), ('SELL', Timestamp('2026-02-26 00:00:00'), 69, 1438.186, 100060.62800000001), ('BUY', Timestamp('2026-03-17 00:00:00'), 68, 1456.976, 986.2600000000093), ('SELL', Timestamp('2026-03-24 00:00:00'), 68, 1379.306, 94779.06800000001), ('BUY', Timestamp('2026-03-31 00:00:00'), 66, 1421.976, 928.6520000000019), ('SELL', Timestamp('2026-04-17 00:00:00'), 66, 1379.216, 91956.908), ('BUY', Timestamp('2026-06-01 00:00:00'), 71, 1281.576, 965.0119999999879), ('SELL', Timestamp('2026-06-08 00:00:00'), 71, 1234.956, 88646.88799999998), ('BUY', Timestamp('2026-06-10 00:00:00'), 71, 1247.856, 49.11199999997916), ('SELL', Timestamp('2026-06-18 00:00:00'), 71, 1186.976, 84324.40799999998), ('BUY', Timestamp('2026-07-01 00:00:00'), 70, 1193.01, 813.7079999999842)]"
|
||||
"trades": "[('BUY', Timestamp('2024-08-09 00:00:00'), 74, 1333.337, 1333.0620000000054), ('SELL', Timestamp('2024-08-28 00:00:00'), 74, 1285.537, 96462.8), ('BUY', Timestamp('2024-08-30 00:00:00'), 72, 1339.727, 2.455999999991036), ('SELL', Timestamp('2024-09-06 00:00:00'), 72, 1294.537, 93209.12), ('BUY', Timestamp('2024-09-25 00:00:00'), 71, 1295.537, 1225.9929999999877), ('SELL', Timestamp('2024-10-17 00:00:00'), 71, 1391.137, 99996.71999999999), ('BUY', Timestamp('2024-11-07 00:00:00'), 64, 1545.677, 1073.3919999999925), ('SELL', Timestamp('2024-11-13 00:00:00'), 64, 1475.037, 95475.76), ('BUY', Timestamp('2024-12-10 00:00:00'), 66, 1443.127, 229.37799999999697), ('SELL', Timestamp('2025-01-02 00:00:00'), 66, 1408.419, 93185.032), ('BUY', Timestamp('2025-01-20 00:00:00'), 66, 1395.219, 1100.5780000000086), ('SELL', Timestamp('2025-01-23 00:00:00'), 66, 1363.419, 91086.23200000002), ('BUY', Timestamp('2025-02-12 00:00:00'), 66, 1363.419, 1100.5780000000086), ('SELL', Timestamp('2025-03-26 00:00:00'), 66, 1496.419, 99864.23200000002), ('BUY', Timestamp('2025-05-08 00:00:00'), 66, 1498.609, 956.0380000000296), ('SELL', Timestamp('2025-05-22 00:00:00'), 66, 1500.419, 99983.69200000004), ('BUY', Timestamp('2025-06-26 00:00:00'), 73, 1368.019, 118.30500000003667), ('SELL', Timestamp('2025-08-01 00:00:00'), 73, 1365.019, 99764.69200000004), ('BUY', Timestamp('2025-08-19 00:00:00'), 71, 1386.019, 1357.3430000000371), ('SELL', Timestamp('2025-09-18 00:00:00'), 71, 1415.979, 101891.85200000004), ('BUY', Timestamp('2025-10-16 00:00:00'), 71, 1432.929, 153.89300000004005), ('SELL', Timestamp('2025-10-28 00:00:00'), 71, 1393.019, 99058.24200000004), ('BUY', Timestamp('2025-11-10 00:00:00'), 70, 1410.319, 335.9120000000403), ('SELL', Timestamp('2025-11-26 00:00:00'), 70, 1397.169, 98137.74200000004), ('BUY', Timestamp('2025-12-17 00:00:00'), 71, 1381.119, 78.29300000004878), ('SELL', Timestamp('2025-12-31 00:00:00'), 71, 1349.156, 95868.36900000005), ('BUY', Timestamp('2026-01-05 00:00:00'), 68, 1397.976, 806.0010000000475), ('SELL', Timestamp('2026-01-15 00:00:00'), 68, 1360.866, 93344.88900000005), ('BUY', Timestamp('2026-01-29 00:00:00'), 66, 1409.696, 304.9530000000668), ('SELL', Timestamp('2026-02-26 00:00:00'), 66, 1438.186, 95225.22900000006), ('BUY', Timestamp('2026-03-17 00:00:00'), 65, 1456.976, 521.7890000000625), ('SELL', Timestamp('2026-03-24 00:00:00'), 65, 1379.306, 90176.67900000006), ('BUY', Timestamp('2026-03-31 00:00:00'), 63, 1421.976, 592.1910000000498), ('SELL', Timestamp('2026-04-17 00:00:00'), 63, 1379.216, 87482.79900000004), ('BUY', Timestamp('2026-06-01 00:00:00'), 68, 1281.576, 335.6310000000376), ('SELL', Timestamp('2026-06-08 00:00:00'), 68, 1234.956, 84312.63900000002), ('BUY', Timestamp('2026-06-10 00:00:00'), 67, 1247.856, 706.2870000000257), ('SELL', Timestamp('2026-06-18 00:00:00'), 67, 1186.976, 80233.67900000003), ('BUY', Timestamp('2026-07-01 00:00:00'), 67, 1193.01, 302.0090000000346)]"
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"code": "000858",
|
||||
"name": "五粮液",
|
||||
"date": "2026-07-12 01:57",
|
||||
"date": "2026-07-12 09:56",
|
||||
"scores": {
|
||||
"macro": -1,
|
||||
"fundamental": 1,
|
||||
"technical": -1,
|
||||
"sentiment": 0
|
||||
"sentiment": 1
|
||||
},
|
||||
"total": 2,
|
||||
"verdict": "⭐ 关注 — 逆向机会或温和看多",
|
||||
|
|
@ -38,7 +38,6 @@
|
|||
"trend_20d": -7.7952952952953
|
||||
},
|
||||
"sentiment_reasons": [
|
||||
"白酒消费降级压制 ⬇️",
|
||||
"白酒估值历史低位有支撑 ⬆️"
|
||||
"利好公告: · 2026-07-03 五粮液:关于回购公司股份进展的公告"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"code": "600519",
|
||||
"name": "贵州茅台",
|
||||
"date": "2026-07-12 01:57",
|
||||
"date": "2026-07-12 09:37",
|
||||
"scores": {
|
||||
"macro": -1,
|
||||
"fundamental": 1,
|
||||
|
|
@ -39,6 +39,6 @@
|
|||
},
|
||||
"sentiment_reasons": [
|
||||
"白酒消费降级压制 ⬇️",
|
||||
"白酒估值历史低位有支撑 ⬆️"
|
||||
"估值低位有支撑 ⬆️"
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue