auto-snapshot 2026-08-12 03:00:49
This commit is contained in:
parent
5aca3f9174
commit
a6d924bfc0
160
config.yaml
160
config.yaml
|
|
@ -9,10 +9,10 @@ providers:
|
|||
cost_factor: 0.0
|
||||
default_model: openai/gpt-oss-120b
|
||||
models:
|
||||
- nvidia/nemotron-mini-4b-instruct
|
||||
- openai/gpt-oss-120b
|
||||
- nvidia/nvidia-nemotron-nano-9b-v2
|
||||
- meta/llama-3.1-8b-instruct
|
||||
- nvidia/nemotron-mini-4b-instruct
|
||||
- openai/gpt-oss-120b
|
||||
- nvidia/nvidia-nemotron-nano-9b-v2
|
||||
- meta/llama-3.1-8b-instruct
|
||||
rate_limit: 1000
|
||||
timeout: 30
|
||||
omniroute-local:
|
||||
|
|
@ -21,9 +21,9 @@ providers:
|
|||
cost_factor: 0.0
|
||||
default_model: auto/chat
|
||||
models:
|
||||
- auto/chat
|
||||
- auto/best-free
|
||||
- auto/coding
|
||||
- auto/chat
|
||||
- auto/best-free
|
||||
- auto/coding
|
||||
rate_limit: 1000
|
||||
timeout: 30
|
||||
deepseek:
|
||||
|
|
@ -32,14 +32,14 @@ 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"]'
|
||||
toolsets:
|
||||
- hermes-cli
|
||||
- web
|
||||
- hermes-cli
|
||||
- web
|
||||
agent:
|
||||
max_turns: 90
|
||||
gateway_timeout: 1800
|
||||
|
|
@ -275,9 +275,9 @@ display:
|
|||
ephemeral_system_ttl: 0
|
||||
runtime_footer:
|
||||
fields:
|
||||
- model
|
||||
- context_pct
|
||||
- cwd
|
||||
- model
|
||||
- context_pct
|
||||
- cwd
|
||||
copy_shortcut: auto
|
||||
tool_progress: all
|
||||
tool_progress_style: accumulate
|
||||
|
|
@ -293,7 +293,7 @@ privacy:
|
|||
tts:
|
||||
provider: edge
|
||||
edge:
|
||||
voice: zh-CN-XiaoxiaoNeural
|
||||
voice: zh-CN-XiaoyiNeural
|
||||
elevenlabs:
|
||||
voice_id: pNInz6obpgDQGcFmaJgB
|
||||
model_id: eleven_multilingual_v2
|
||||
|
|
@ -368,12 +368,12 @@ moa:
|
|||
presets:
|
||||
expert-panel:
|
||||
reference_models:
|
||||
- provider: newapi-local
|
||||
model: openai/gpt-oss-120b
|
||||
- provider: newapi-local
|
||||
model: nvidia/llama-3.3-nemotron-super-49b-v1
|
||||
- provider: newapi-local
|
||||
model: mistralai/mistral-large-3-675b-instruct-2512
|
||||
- provider: newapi-local
|
||||
model: openai/gpt-oss-120b
|
||||
- provider: newapi-local
|
||||
model: nvidia/llama-3.3-nemotron-super-49b-v1
|
||||
- provider: newapi-local
|
||||
model: mistralai/mistral-large-3-675b-instruct-2512
|
||||
aggregator:
|
||||
provider: newapi-local
|
||||
model: openai/gpt-oss-120b
|
||||
|
|
@ -431,36 +431,36 @@ approvals:
|
|||
mcp_reload_confirm: true
|
||||
destructive_slash_confirm: false
|
||||
command_allowlist:
|
||||
- pipe remote content to shell
|
||||
- script execution via heredoc
|
||||
- copy/move file into /etc/
|
||||
- find -delete
|
||||
- recursive delete
|
||||
- hermes update (restarts gateway, kills running agents)
|
||||
- shell command via -c/-lc flag
|
||||
- force kill processes (killall -KILL)
|
||||
- script execution via -e/-c flag
|
||||
- overwrite system file via tee
|
||||
- kill hermes/gateway process (self-termination)
|
||||
- delete in root path
|
||||
- git force push short flag (rewrites remote history)
|
||||
- sudo with combined-flag privilege escalation
|
||||
- overwrite system file via redirection
|
||||
- start gateway outside systemd (use 'systemctl --user restart hermes-gateway')
|
||||
- disk copy
|
||||
- overwrite system config
|
||||
- overwrite project env/config via redirection
|
||||
- kill process via pgrep expansion (self-termination)
|
||||
- SQL TRUNCATE
|
||||
- in-place edit of system config
|
||||
- world/other-writable permissions
|
||||
- stop/restart hermes gateway (kills running agents)
|
||||
- sudo with privilege flag (stdin/askpass/shell/list)
|
||||
- copy/move file into system config path
|
||||
- force kill processes
|
||||
- git force push (rewrites remote history)
|
||||
- stop/restart system service
|
||||
- in-place edit of Hermes config/env
|
||||
- pipe remote content to shell
|
||||
- script execution via heredoc
|
||||
- copy/move file into /etc/
|
||||
- find -delete
|
||||
- recursive delete
|
||||
- hermes update (restarts gateway, kills running agents)
|
||||
- shell command via -c/-lc flag
|
||||
- force kill processes (killall -KILL)
|
||||
- script execution via -e/-c flag
|
||||
- overwrite system file via tee
|
||||
- kill hermes/gateway process (self-termination)
|
||||
- delete in root path
|
||||
- git force push short flag (rewrites remote history)
|
||||
- sudo with combined-flag privilege escalation
|
||||
- overwrite system file via redirection
|
||||
- start gateway outside systemd (use 'systemctl --user restart hermes-gateway')
|
||||
- disk copy
|
||||
- overwrite system config
|
||||
- overwrite project env/config via redirection
|
||||
- kill process via pgrep expansion (self-termination)
|
||||
- SQL TRUNCATE
|
||||
- in-place edit of system config
|
||||
- world/other-writable permissions
|
||||
- stop/restart hermes gateway (kills running agents)
|
||||
- sudo with privilege flag (stdin/askpass/shell/list)
|
||||
- copy/move file into system config path
|
||||
- force kill processes
|
||||
- git force push (rewrites remote history)
|
||||
- stop/restart system service
|
||||
- in-place edit of Hermes config/env
|
||||
hooks_auto_accept: false
|
||||
security:
|
||||
allow_private_urls: false
|
||||
|
|
@ -546,16 +546,16 @@ _config_version: 33
|
|||
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:
|
||||
|
|
@ -564,8 +564,8 @@ mcp_servers:
|
|||
openclaw:
|
||||
command: openclaw
|
||||
args:
|
||||
- mcp
|
||||
- serve
|
||||
- mcp
|
||||
- serve
|
||||
connect_timeout: 60
|
||||
timeout: 300
|
||||
codebase-memory-mcp:
|
||||
|
|
@ -574,30 +574,30 @@ mcp_servers:
|
|||
dbx:
|
||||
command: npx
|
||||
args:
|
||||
- -y
|
||||
- '@dbx-app/mcp-server'
|
||||
- -y
|
||||
- '@dbx-app/mcp-server'
|
||||
enabled: true
|
||||
timeout: 120
|
||||
connect_timeout: 60
|
||||
platform_toolsets:
|
||||
cli:
|
||||
- browser
|
||||
- clarify
|
||||
- code_execution
|
||||
- computer_use
|
||||
- cronjob
|
||||
- delegation
|
||||
- file
|
||||
- image_gen
|
||||
- memory
|
||||
- session_search
|
||||
- skills
|
||||
- terminal
|
||||
- todo
|
||||
- tts
|
||||
- vision
|
||||
- web
|
||||
- mcp-codegraph
|
||||
- browser
|
||||
- clarify
|
||||
- code_execution
|
||||
- computer_use
|
||||
- cronjob
|
||||
- delegation
|
||||
- file
|
||||
- image_gen
|
||||
- memory
|
||||
- session_search
|
||||
- skills
|
||||
- terminal
|
||||
- todo
|
||||
- tts
|
||||
- vision
|
||||
- web
|
||||
- mcp-codegraph
|
||||
platforms:
|
||||
webhook:
|
||||
enabled: true
|
||||
|
|
@ -611,9 +611,9 @@ platforms:
|
|||
plugins:
|
||||
disabled: []
|
||||
enabled:
|
||||
- agentic-sms-gateway
|
||||
- cronalytics
|
||||
- rtk-rewrite
|
||||
- agentic-sms-gateway
|
||||
- cronalytics
|
||||
- rtk-rewrite
|
||||
weixin:
|
||||
enabled: true
|
||||
extra:
|
||||
|
|
@ -626,4 +626,4 @@ weixin:
|
|||
session_reset: {}
|
||||
known_plugin_toolsets:
|
||||
cli:
|
||||
- spotify
|
||||
- spotify
|
||||
|
|
|
|||
|
|
@ -109,6 +109,23 @@ def upgrade_zhiyi():
|
|||
except Exception as e:
|
||||
log(f" metrics API 不存在或失败(非致命): {e}")
|
||||
|
||||
# P2 离线整合(LightMem UPDATE_PROMPT):每日自动合并相似记忆
|
||||
# POST /api/v1/consolidate/memory — 找出相似记忆对 → LLM 三选一(update/delete/ignore)
|
||||
try:
|
||||
req = urllib.request.Request(
|
||||
f"{ZHIYI_URL}/api/v1/consolidate/memory",
|
||||
data=json.dumps({"namespace": "hermes-main", "limit": 50}).encode("utf-8"),
|
||||
headers={"X-API-Key": ZHIYI_KEY, "Content-Type": "application/json"},
|
||||
method="POST"
|
||||
)
|
||||
with urllib.request.urlopen(req, timeout=120) as resp:
|
||||
cons = json.loads(resp.read().decode())
|
||||
log(f" consolidate: processed={cons.get('processed',0)} updated={cons.get('updated',0)} deleted={cons.get('deleted',0)} ignored={cons.get('ignored',0)}")
|
||||
if cons.get("processed", 0) > 0:
|
||||
REPORT.append(f"🧹 P2 记忆整合: 处理 {cons.get('processed')} 对相似记忆 (更新 {cons.get('updated')} / 删除 {cons.get('deleted')} / 忽略 {cons.get('ignored')})")
|
||||
except Exception as e:
|
||||
log(f" consolidate 失败(非致命): {e}")
|
||||
|
||||
return actions
|
||||
|
||||
# ── 2. Soulful 自我升级 ─────────────────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
mp3 → opus 转码脚本(飞书语音消息专用)
|
||||
飞书可点播放的语音只支持 .ogg/.opus(Ogg Opus 容器),
|
||||
text_to_speech 生成的 .mp3 只能发成文件附件。
|
||||
用法: python3 to_opus.py input.mp3 [output.ogg]
|
||||
"""
|
||||
import sys, os, subprocess
|
||||
|
||||
def to_opus(src: str, dst: str = None) -> str:
|
||||
if not dst:
|
||||
dst = os.path.splitext(src)[0] + '.opus'
|
||||
cmd = [
|
||||
'ffmpeg', '-y', '-i', src,
|
||||
'-c:a', 'libopus', '-b:a', '24k',
|
||||
'-ar', '24000', '-ac', '1',
|
||||
dst
|
||||
]
|
||||
r = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if r.returncode != 0:
|
||||
raise RuntimeError(f'转码失败: {r.stderr[-300:]}')
|
||||
return dst
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
print('用法: python3 to_opus.py input.mp3 [output.opus]')
|
||||
sys.exit(1)
|
||||
src = sys.argv[1]
|
||||
dst = sys.argv[2] if len(sys.argv) > 2 else None
|
||||
out = to_opus(src, dst)
|
||||
print(f'✅ 转码成功: {out}')
|
||||
print(f' MEDIA:{out}')
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"last_report_path": "/home/muc/.hermes-prof-b/logs/curator/20260804-135338",
|
||||
"last_run_at": "2026-08-04T13:53:38.565125+00:00",
|
||||
"last_run_duration_seconds": 1.078757,
|
||||
"last_run_summary": "auto: 38 marked stale; llm: skipped (consolidation off)",
|
||||
"last_report_path": "/home/muc/.hermes/profiles/prof-b/logs/curator/20260811-140104",
|
||||
"last_run_at": "2026-08-11T14:01:04.419530+00:00",
|
||||
"last_run_duration_seconds": 1.336497,
|
||||
"last_run_summary": "auto: 6 marked stale, 1 reactivated; llm: skipped (consolidation off)",
|
||||
"last_run_summary_shown_at": null,
|
||||
"paused": false,
|
||||
"run_count": 13
|
||||
"run_count": 14
|
||||
}
|
||||
|
|
@ -68,14 +68,16 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-05-13T06:09:07.701394+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": "2026-07-08T18:32:46.513752+00:00",
|
||||
"last_used_at": "2026-07-29T13:39:03.010391+00:00",
|
||||
"last_viewed_at": "2026-07-29T13:39:03.006878+00:00",
|
||||
"patch_count": 41,
|
||||
"last_patched_at": "2026-08-11T17:35:11.052888+00:00",
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": "2026-08-11T17:35:05.111512+00:00",
|
||||
"last_viewed_at": "2026-08-11T17:35:05.107980+00:00",
|
||||
"patch_count": 42,
|
||||
"patch_generation": 1,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 43,
|
||||
"view_count": 43
|
||||
"use_count": 44,
|
||||
"view_count": 44
|
||||
},
|
||||
"apple-liquid-glass": {
|
||||
"archived_at": null,
|
||||
|
|
@ -257,7 +259,7 @@
|
|||
"last_viewed_at": "2026-07-09T01:00:29.700198+00:00",
|
||||
"patch_count": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"state": "stale",
|
||||
"use_count": 1,
|
||||
"view_count": 1
|
||||
},
|
||||
|
|
@ -322,7 +324,7 @@
|
|||
"last_viewed_at": "2026-07-12T02:42:23.152090+00:00",
|
||||
"patch_count": 5,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"state": "stale",
|
||||
"use_count": 9,
|
||||
"view_count": 9
|
||||
},
|
||||
|
|
@ -685,6 +687,36 @@
|
|||
"use_count": 6,
|
||||
"view_count": 6
|
||||
},
|
||||
"document-to-action-items": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-08-11T14:01:05.489919+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": null,
|
||||
"last_viewed_at": null,
|
||||
"patch_count": 0,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"docx": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-08-11T14:01:05.495080+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": null,
|
||||
"last_viewed_at": null,
|
||||
"patch_count": 0,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"dogfood": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-06-30T11:24:39.481778+00:00",
|
||||
|
|
@ -728,27 +760,31 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-05-06T00:47:32.389489+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-07-10T02:10:08.350671+00:00",
|
||||
"last_used_at": "2026-07-29T12:52:03.375233+00:00",
|
||||
"last_viewed_at": "2026-07-29T12:52:03.371929+00:00",
|
||||
"patch_count": 44,
|
||||
"last_patched_at": "2026-08-11T02:20:45.592319+00:00",
|
||||
"last_reused_patch_generation": 1,
|
||||
"last_used_at": "2026-08-11T08:04:08.867971+00:00",
|
||||
"last_viewed_at": "2026-08-11T08:04:08.864102+00:00",
|
||||
"patch_count": 45,
|
||||
"patch_generation": 1,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 74,
|
||||
"view_count": 75
|
||||
"use_count": 78,
|
||||
"view_count": 79
|
||||
},
|
||||
"feishu-bot": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-05-13T12:28:27.306239+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": "2026-06-21T15:40:56.053406+00:00",
|
||||
"last_used_at": "2026-06-21T15:40:48.418853+00:00",
|
||||
"last_viewed_at": "2026-06-21T15:40:48.408618+00:00",
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": "2026-08-11T14:17:03.638945+00:00",
|
||||
"last_viewed_at": "2026-08-11T14:17:03.626540+00:00",
|
||||
"patch_count": 16,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 18,
|
||||
"view_count": 18
|
||||
"use_count": 20,
|
||||
"view_count": 20
|
||||
},
|
||||
"findmy": {
|
||||
"archived_at": null,
|
||||
|
|
@ -832,16 +868,16 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-08-02T18:24:34.438054+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-08-10T04:46:04.191252+00:00",
|
||||
"last_reused_patch_generation": 3,
|
||||
"last_used_at": "2026-08-10T04:45:38.330678+00:00",
|
||||
"last_viewed_at": "2026-08-10T04:45:38.326586+00:00",
|
||||
"patch_count": 11,
|
||||
"patch_generation": 8,
|
||||
"last_patched_at": "2026-08-11T15:56:09.944507+00:00",
|
||||
"last_reused_patch_generation": 10,
|
||||
"last_used_at": "2026-08-11T15:55:58.428178+00:00",
|
||||
"last_viewed_at": "2026-08-11T15:55:58.415651+00:00",
|
||||
"patch_count": 14,
|
||||
"patch_generation": 11,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 9,
|
||||
"view_count": 9
|
||||
"use_count": 14,
|
||||
"view_count": 14
|
||||
},
|
||||
"github-auth": {
|
||||
"archived_at": null,
|
||||
|
|
@ -899,31 +935,31 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-08-10T02:35:03.788507+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-08-10T02:36:11.952237+00:00",
|
||||
"last_reused_patch_generation": 4,
|
||||
"last_used_at": "2026-08-10T04:46:07.027987+00:00",
|
||||
"last_viewed_at": "2026-08-10T04:46:07.016651+00:00",
|
||||
"patch_count": 4,
|
||||
"patch_generation": 4,
|
||||
"last_patched_at": "2026-08-11T15:48:55.169727+00:00",
|
||||
"last_reused_patch_generation": 5,
|
||||
"last_used_at": "2026-08-11T15:48:44.390260+00:00",
|
||||
"last_viewed_at": "2026-08-11T15:48:44.386278+00:00",
|
||||
"patch_count": 6,
|
||||
"patch_generation": 6,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 5,
|
||||
"view_count": 5
|
||||
"use_count": 8,
|
||||
"view_count": 8
|
||||
},
|
||||
"github-project-research": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-08-01T11:50:01.274771+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-08-10T03:37:47.436239+00:00",
|
||||
"last_reused_patch_generation": 3,
|
||||
"last_used_at": "2026-08-10T03:37:37.196684+00:00",
|
||||
"last_viewed_at": "2026-08-10T03:37:37.185336+00:00",
|
||||
"patch_count": 18,
|
||||
"patch_generation": 4,
|
||||
"last_patched_at": "2026-08-11T07:56:41.339533+00:00",
|
||||
"last_reused_patch_generation": 7,
|
||||
"last_used_at": "2026-08-11T07:56:43.941512+00:00",
|
||||
"last_viewed_at": "2026-08-11T07:56:43.938038+00:00",
|
||||
"patch_count": 21,
|
||||
"patch_generation": 7,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 20,
|
||||
"view_count": 20
|
||||
"use_count": 24,
|
||||
"view_count": 24
|
||||
},
|
||||
"github-repo-management": {
|
||||
"archived_at": null,
|
||||
|
|
@ -977,6 +1013,21 @@
|
|||
"use_count": 2,
|
||||
"view_count": 2
|
||||
},
|
||||
"grounded-citations": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-08-11T14:01:05.500727+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": null,
|
||||
"last_viewed_at": null,
|
||||
"patch_count": 0,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"heartmula": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-06-30T11:24:39.521411+00:00",
|
||||
|
|
@ -1029,7 +1080,7 @@
|
|||
"patch_count": 2,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "stale",
|
||||
"state": "active",
|
||||
"use_count": 3,
|
||||
"view_count": 3
|
||||
},
|
||||
|
|
@ -1039,14 +1090,14 @@
|
|||
"created_by": null,
|
||||
"last_patched_at": "2026-08-01T02:18:43.963710+00:00",
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": "2026-08-10T07:52:46.510076+00:00",
|
||||
"last_viewed_at": "2026-08-10T07:52:46.501682+00:00",
|
||||
"last_used_at": "2026-08-11T14:47:08.088523+00:00",
|
||||
"last_viewed_at": "2026-08-11T14:47:08.077261+00:00",
|
||||
"patch_count": 123,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 130,
|
||||
"view_count": 129
|
||||
"use_count": 133,
|
||||
"view_count": 132
|
||||
},
|
||||
"hermes-mcp-setup": {
|
||||
"archived_at": null,
|
||||
|
|
@ -1139,7 +1190,7 @@
|
|||
"last_viewed_at": "2026-07-09T01:00:29.716983+00:00",
|
||||
"patch_count": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"state": "stale",
|
||||
"use_count": 1,
|
||||
"view_count": 1
|
||||
},
|
||||
|
|
@ -1221,6 +1272,21 @@
|
|||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"inspecting-hermes-desktop-dom": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-08-11T14:01:05.516020+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": null,
|
||||
"last_viewed_at": null,
|
||||
"patch_count": 0,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"jupyter-live-kernel": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-06-30T11:24:39.540375+00:00",
|
||||
|
|
@ -1234,6 +1300,21 @@
|
|||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"lazy-senior-dev": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-08-11T17:35:03.221614+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": null,
|
||||
"last_viewed_at": null,
|
||||
"patch_count": 0,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"linux-desktop-apps": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-06-15T07:39:13.833978+00:00",
|
||||
|
|
@ -1277,16 +1358,16 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-08-01T13:47:26.532313+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-08-10T07:53:51.858329+00:00",
|
||||
"last_reused_patch_generation": 2,
|
||||
"last_used_at": "2026-08-10T07:53:36.767251+00:00",
|
||||
"last_viewed_at": "2026-08-10T07:53:36.754920+00:00",
|
||||
"patch_count": 9,
|
||||
"patch_generation": 3,
|
||||
"last_patched_at": "2026-08-11T02:21:13.580898+00:00",
|
||||
"last_reused_patch_generation": 3,
|
||||
"last_used_at": "2026-08-11T02:21:03.966315+00:00",
|
||||
"last_viewed_at": "2026-08-11T02:21:03.955039+00:00",
|
||||
"patch_count": 11,
|
||||
"patch_generation": 5,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 9,
|
||||
"view_count": 9
|
||||
"use_count": 10,
|
||||
"view_count": 10
|
||||
},
|
||||
"llm-wiki": {
|
||||
"archived_at": null,
|
||||
|
|
@ -1385,14 +1466,16 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-07-13T05:22:08.504827+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-07-30T01:24:56.303967+00:00",
|
||||
"last_used_at": "2026-07-30T01:24:29.547939+00:00",
|
||||
"last_viewed_at": "2026-07-30T01:24:29.536797+00:00",
|
||||
"patch_count": 10,
|
||||
"last_patched_at": "2026-08-11T15:56:28.201567+00:00",
|
||||
"last_reused_patch_generation": 4,
|
||||
"last_used_at": "2026-08-11T15:55:41.839536+00:00",
|
||||
"last_viewed_at": "2026-08-11T15:55:41.834604+00:00",
|
||||
"patch_count": 17,
|
||||
"patch_generation": 7,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 4,
|
||||
"view_count": 4
|
||||
"use_count": 8,
|
||||
"view_count": 8
|
||||
},
|
||||
"memoryfabric": {
|
||||
"archived_at": null,
|
||||
|
|
@ -1429,7 +1512,7 @@
|
|||
"last_viewed_at": "2026-07-12T01:13:29.692201+00:00",
|
||||
"patch_count": 5,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"state": "stale",
|
||||
"use_count": 13,
|
||||
"view_count": 10
|
||||
},
|
||||
|
|
@ -1548,7 +1631,7 @@
|
|||
"last_viewed_at": "2026-07-08T17:33:15.036685+00:00",
|
||||
"patch_count": 1,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"state": "stale",
|
||||
"use_count": 3,
|
||||
"view_count": 3
|
||||
},
|
||||
|
|
@ -1634,6 +1717,21 @@
|
|||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"pdf": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-08-11T14:01:05.536268+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": null,
|
||||
"last_viewed_at": null,
|
||||
"patch_count": 0,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"petdex": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-06-30T11:24:39.586358+00:00",
|
||||
|
|
@ -1733,29 +1831,29 @@
|
|||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": null,
|
||||
"last_viewed_at": null,
|
||||
"last_used_at": "2026-08-11T09:56:36.263226+00:00",
|
||||
"last_viewed_at": "2026-08-11T09:56:36.256679+00:00",
|
||||
"patch_count": 0,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 0,
|
||||
"view_count": 0
|
||||
"use_count": 2,
|
||||
"view_count": 2
|
||||
},
|
||||
"provider-tiering": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-07-08T17:13:40.791890+00:00",
|
||||
"created_by": "agent",
|
||||
"last_patched_at": "2026-08-09T11:51:20.442545+00:00",
|
||||
"last_patched_at": "2026-08-11T14:47:32.634533+00:00",
|
||||
"last_reused_patch_generation": 3,
|
||||
"last_used_at": "2026-08-09T12:25:20.836602+00:00",
|
||||
"last_viewed_at": "2026-08-09T12:25:20.824193+00:00",
|
||||
"patch_count": 86,
|
||||
"patch_generation": 3,
|
||||
"last_used_at": "2026-08-11T14:47:23.136481+00:00",
|
||||
"last_viewed_at": "2026-08-11T14:47:23.125236+00:00",
|
||||
"patch_count": 87,
|
||||
"patch_generation": 4,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 80,
|
||||
"view_count": 80
|
||||
"use_count": 81,
|
||||
"view_count": 81
|
||||
},
|
||||
"python-debugpy": {
|
||||
"archived_at": null,
|
||||
|
|
@ -1805,7 +1903,7 @@
|
|||
"last_viewed_at": "2026-07-09T19:30:23.327898+00:00",
|
||||
"patch_count": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"state": "stale",
|
||||
"use_count": 1,
|
||||
"view_count": 1
|
||||
},
|
||||
|
|
@ -1936,14 +2034,14 @@
|
|||
"created_by": "agent",
|
||||
"last_patched_at": "2026-08-10T07:54:48.137988+00:00",
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": null,
|
||||
"last_viewed_at": null,
|
||||
"last_used_at": "2026-08-11T02:21:17.690989+00:00",
|
||||
"last_viewed_at": "2026-08-11T02:21:17.673740+00:00",
|
||||
"patch_count": 1,
|
||||
"patch_generation": 1,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 0,
|
||||
"view_count": 0
|
||||
"use_count": 1,
|
||||
"view_count": 1
|
||||
},
|
||||
"so-team-workflow": {
|
||||
"archived_at": null,
|
||||
|
|
@ -2164,13 +2262,15 @@
|
|||
"created_at": "2026-05-13T16:02:06.347617+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": "2026-08-02T20:34:42.818272+00:00",
|
||||
"last_used_at": "2026-08-02T20:43:50.640254+00:00",
|
||||
"last_viewed_at": "2026-08-02T20:43:50.633517+00:00",
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": "2026-08-11T14:46:39.383816+00:00",
|
||||
"last_viewed_at": "2026-08-11T14:46:39.372771+00:00",
|
||||
"patch_count": 14,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 19,
|
||||
"view_count": 19
|
||||
"use_count": 24,
|
||||
"view_count": 24
|
||||
},
|
||||
"web-content-capture": {
|
||||
"archived_at": null,
|
||||
|
|
@ -2189,14 +2289,16 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-05-13T09:05:27.674550+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": "2026-07-03T10:28:19.836412+00:00",
|
||||
"last_used_at": "2026-07-20T10:26:13.324456+00:00",
|
||||
"last_viewed_at": "2026-07-20T10:26:13.321399+00:00",
|
||||
"patch_count": 23,
|
||||
"last_patched_at": "2026-08-11T17:37:23.001866+00:00",
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": "2026-08-11T17:37:08.976377+00:00",
|
||||
"last_viewed_at": "2026-08-11T17:37:08.972764+00:00",
|
||||
"patch_count": 24,
|
||||
"patch_generation": 1,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 21,
|
||||
"view_count": 21
|
||||
"use_count": 22,
|
||||
"view_count": 22
|
||||
},
|
||||
"website-ux-audit": {
|
||||
"archived_at": null,
|
||||
|
|
@ -2317,6 +2419,21 @@
|
|||
"use_count": 9,
|
||||
"view_count": 9
|
||||
},
|
||||
"xlsx": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-08-11T14:01:05.546571+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": null,
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": null,
|
||||
"last_viewed_at": null,
|
||||
"patch_count": 0,
|
||||
"patch_generation": 0,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 0,
|
||||
"view_count": 0
|
||||
},
|
||||
"xurl": {
|
||||
"archived_at": null,
|
||||
"created_at": "2026-06-30T11:24:39.663772+00:00",
|
||||
|
|
@ -2360,16 +2477,16 @@
|
|||
"archived_at": null,
|
||||
"created_at": "2026-05-29T19:39:03.373231+00:00",
|
||||
"created_by": null,
|
||||
"last_patched_at": "2026-08-09T17:24:35.461838+00:00",
|
||||
"last_reused_patch_generation": 0,
|
||||
"last_used_at": "2026-08-09T16:44:59.475746+00:00",
|
||||
"last_viewed_at": "2026-08-09T16:44:59.472279+00:00",
|
||||
"patch_count": 733,
|
||||
"patch_generation": 2,
|
||||
"last_patched_at": "2026-08-11T13:49:15.769487+00:00",
|
||||
"last_reused_patch_generation": 2,
|
||||
"last_used_at": "2026-08-11T09:56:06.064254+00:00",
|
||||
"last_viewed_at": "2026-08-11T09:56:05.969498+00:00",
|
||||
"patch_count": 736,
|
||||
"patch_generation": 5,
|
||||
"pinned": false,
|
||||
"state": "active",
|
||||
"use_count": 400,
|
||||
"view_count": 374
|
||||
"use_count": 402,
|
||||
"view_count": 376
|
||||
},
|
||||
"zhiyi-dev": {
|
||||
"archived_at": null,
|
||||
|
|
|
|||
|
|
@ -144,6 +144,38 @@ steps:
|
|||
|
||||
---
|
||||
|
||||
## ECC 编码编排参考(2026-08-11 借鉴 affaan-m/ECC 239k⭐)
|
||||
|
||||
ECC 是生产级 AI 编码插件(68 agents / 285 skills / 94 commands),它的**自动编排规则**值得参考:
|
||||
|
||||
### 何时用哪个 agent(ECC 规则 → 我的对应)
|
||||
|
||||
| 场景 | ECC agent | 我的方案 |
|
||||
|------|-----------|---------|
|
||||
| 复杂功能/重构 | planner | ao compose 规划 |
|
||||
| 写完代码 | code-reviewer | 我验收审查 |
|
||||
| 新功能/bug | tdd-guide | opencode + 测试 |
|
||||
| 架构决策 | architect | 我 + opencode 架构师角色 |
|
||||
| 涉密代码 | security-reviewer | 安全审查 |
|
||||
| 自治循环监控 | loop-operator | daemon 深度思考 |
|
||||
| 构建/类型错误 | build-error-resolver | opencode 修复 |
|
||||
|
||||
### 核心原则(ECC → 我的落地)
|
||||
|
||||
1. **Agent-First**:复杂任务主动委派专业 agent,不等用户提示
|
||||
2. **TDD 强制**:先写测试(RED→GREEN→REFACTOR),覆盖率 ≥80%
|
||||
3. **Security-First**:提交前检查无硬编码密钥、输入校验、SQL 注入/XSS/CSRF 防护
|
||||
4. **Immutability**:创建新对象不 mutate
|
||||
5. **代码规范**:函数 <50 行、文件 <800 行、嵌套 <4 层
|
||||
6. **并行执行**:独立操作并行启动多个 agent
|
||||
|
||||
### 我的落地要点
|
||||
- 复杂编码任务:规划 → opencode 执行(TDD)→ 我验收(code-reviewer 视角)
|
||||
- 涉密/敏感改动:先安全审查再动手
|
||||
- 参照 lazy-senior-dev skill 做最小化
|
||||
|
||||
---
|
||||
|
||||
## 与相关技能的关系
|
||||
|
||||
| Skill | 说明 |
|
||||
|
|
|
|||
|
|
@ -123,6 +123,16 @@ clone_via_mirror() { # repo=owner/name, dir=本地路径
|
|||
8. **URL 拼接重复 `http://`(2026-08-10 实测踩坑)** — `GITEA="http://git.zszs.site"` 后拼 `"$GITEA/api..."` 没问题,但若 remote 写 `"http://$GITEA/xiaoxue_admin/REPO.git"` 会变成 `http://http://git.zszs.site/...`,报 `Could not resolve host: http`,全部 push 假成功(Gitea 仓库建了但代码没推上)。**GITEA 变量只放裸域名 `git.zszs.site`**,remote/API 统一拼 `http://$GITEA/...`。
|
||||
9. **tags push 会 `send-pack: unexpected disconnect` 但 main 已成功(2026-08-10 实测)** — 大仓库(orca 600MB/8268 commits)走 frp 公网推 tags 常断开。判断成功以**分支 push 结果 + `git ls-remote ... HEAD` 有输出**为准,tags 可后续补推(`git push ... --tags` 重跑即可)。
|
||||
10. **push 脚本要防"假 OK"** — 把 `git push` 输出写日志、用 `ls-remote HEAD` 或 API HTTP 200 验证远端有 HEAD,别只看 `tail -1`(会吞掉 fatal)。
|
||||
11. **大仓库(>200MB)下载策略(2026-08-10 cosmos 275MB 实测 4 方案全败)**:
|
||||
- 场景:`NVIDIA/cosmos` 275MB,ghfast 镜像超时 → gh-proxy clone `fetch-pack: unexpected disconnect`(大 pack 传输中断)→ GitHub 直连 443 超时 → codeload tar.gz 下到 53MB/275MB 截断。
|
||||
- **镜像对大仓库不稳**:gh-proxy 对 600MB 的 orca 能成功(慢但通),275MB 的 cosmos 却断——大仓库碰运气,别假定镜像一定行。
|
||||
- **`wget -c` 假续传**:codeload 不支持 range 请求,`-c` 会从头重下,每轮超时前下 ~47MB 然后重来,永远下不完。aria2c 分片续传中断后 control 文件丢失,会产生 `cosmos.tar.1.gz` / `cosmos.tar.1.1.gz` 多个碎片文件且无法合并。
|
||||
- **可行路径**:aria2c 多线程(`-x 16 -s 16`)确实能推进(53MB→130MB),但中断后要保证 control 文件还在(同一 `-o` 文件名续传);或分多轮 wget 手工续传。
|
||||
- **决策铁律**:大仓库 + 被墙网络 = 先评估价值。价值低(如研究型大仓库)直接**建议放弃**并问用户,别耗 40 分钟 4 种方案。用户认可放弃后清理残留文件(`cosmos.tar*` 多个碎片)收尾。
|
||||
12. **杀卡死后台 clone 的坑(2026-08-11 firecrawl 实测)** — `pkill -f "firecrawl"` 会匹配到当前 shell 自身(命令字符串里含 firecrawl),导致 exit -15 自杀。且只杀 git clone 子进程没用——batch 脚本父进程(`bash batch_clone.sh` + `wait`)活着会重新拉起 clone(PID 会变)。正确姿势:`ps aux | grep` 拿全部显式 PID → `kill -9 <PID...>` 一次杀光(含父脚本),再 `ps aux | grep` 验证数量归零。
|
||||
13. **研究型大仓库可走 tar.gz 而非放弃(2026-08-11 firecrawl 173MB 实测)** — 若仓库价值是**研究**,aria2c codeload tar.gz 是 pitfall 11 决策铁律的合法替代:gh-proxy 卡死(17min 只下 5.4MB,CPU 3s = 网络死)→ kill 清理 → `aria2c -x 16 -s 16 "https://codeload.github.com/OWNER/REPO/tar.gz/refs/heads/main"` 解压研究。
|
||||
- **tar.gz 快照也能推 Gitea(实测成功)**:`git init -b main . && git add -A && git commit -m "main snapshot (tar.gz, no history)"` 单提交快照,Gitea 接受(虽丢历史,但代码可归档、可 clone 研究)。残留的失败 clone 会留 `.git/`(git init 显示 "Reinitialized existing")+ stale origin remote——先 `git remote remove origin` 清掉再推。
|
||||
- 完整历史只在需要审计/追 commit 时才必须——研究价值仓库快照足够。
|
||||
|
||||
## 参考
|
||||
|
||||
|
|
|
|||
|
|
@ -215,20 +215,10 @@ systemd-run --user --unit=gw-compression-restart --collect bash /tmp/restart_gw_
|
|||
|
||||
**`ConnectionClosed("initialize request")` 是正常行为,不是错误**——stdio MCP server 启动后等待客户端发 initialize 请求,无客户端就退出。用 `--version` 测 MCP server 会看到这个"错误",别被骗。
|
||||
|
||||
真正验证(MCP SDK 握手 + 列工具):
|
||||
```python
|
||||
# /tmp/test_mcp_sdk.py
|
||||
import asyncio, sys
|
||||
async def main():
|
||||
from mcp import ClientSession, StdioServerParameters
|
||||
from mcp.client.stdio import stdio_client
|
||||
server = StdioServerParameters(command="npx", args=["-y", "@dbx-app/mcp-server"])
|
||||
async with stdio_client(server) as (read, write):
|
||||
async with ClientSession(read, write) as session:
|
||||
await asyncio.wait_for(session.initialize(), timeout=60)
|
||||
tools = await session.list_tools()
|
||||
print(f"✅ 发现 {len(tools.tools)} 个工具:", [t.name for t in tools.tools])
|
||||
asyncio.run(main())
|
||||
真正验证(MCP SDK 握手 + 列工具)——用固化脚本 `scripts/verify_mcp_stdio.py`(本 skill 自带,可复用):
|
||||
```bash
|
||||
python3 ~/.hermes/skills/devops/llm-gateway-ops/scripts/verify_mcp_stdio.py "npx" "-y" "@dbx-app/mcp-server"
|
||||
# 输出: ✅ MCP 连接成功,发现 N 个工具: dbx_list_connections, ...
|
||||
```
|
||||
|
||||
### config.yaml 是安全保护文件(patch 工具拒绝写)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
stdio MCP server 验证脚本 — 不配置 Hermes 就能先测 MCP server 是否可用。
|
||||
|
||||
背景(2026-08-10 dbx 实测):
|
||||
- 裸跑 `npx @dbx-app/mcp-server` 报 `ConnectionClosed("initialize request")` 是正常 MCP 行为
|
||||
(server 等客户端发 initialize,没客户端就退出),不代表 server 坏。
|
||||
- 用本脚本做真实协议握手:initialize → list_tools,确认工具发现。
|
||||
|
||||
用法:
|
||||
python3 verify_mcp_stdio.py "npx" "-y" "@dbx-app/mcp-server"
|
||||
python3 verify_mcp_stdio.py "/absolute/path/to/dbx-mcp"
|
||||
|
||||
前置: pip install mcp(Hermes venv 已装 1.26.0)
|
||||
"""
|
||||
import asyncio, sys
|
||||
|
||||
async def main(command: str, *args: str):
|
||||
from mcp import ClientSession, StdioServerParameters
|
||||
from mcp.client.stdio import stdio_client
|
||||
|
||||
server = StdioServerParameters(command=command, args=list(args), env=None)
|
||||
try:
|
||||
async with stdio_client(server) as (read, write):
|
||||
async with ClientSession(read, write) as session:
|
||||
await asyncio.wait_for(session.initialize(), timeout=60)
|
||||
tools = await session.list_tools()
|
||||
print(f"✅ MCP 连接成功,发现 {len(tools.tools)} 个工具:")
|
||||
for t in tools.tools:
|
||||
print(f" - {t.name}: {t.description[:60]}")
|
||||
except Exception as e:
|
||||
print(f"❌ 连接失败: {type(e).__name__}: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("用法: verify_mcp_stdio.py <command> [args...]")
|
||||
sys.exit(1)
|
||||
asyncio.run(main(sys.argv[1], *sys.argv[2:]))
|
||||
|
|
@ -28,7 +28,7 @@ pitfalls:
|
|||
- model-health.json 的稳定模型列表需要定期更新(EOL 后替换为当前可用模型)
|
||||
- 当 model-health.json 显示 stable=0 或发现大量 410,执行全量 sweep:见 references/nvidia-nim-eol-sweep.md
|
||||
- ⚠️ EOL 后不仅要更新 catalog,还要检查脚本中的硬编码模型名(daemon.py 的 FAST/DEEP/COMPACTION_MODEL、wiki_curator.py 的 LLM_MODEL、cangjie_distill.py 的默认参数等),见 sweep 第5步
|
||||
- config.yaml 的 patch 被安全墙阻挡时,用 hermes config set 替代
|
||||
- config.yaml 的 patch 被安全墙阻挡时,用 hermes config set 替代(2026-08-11 实例:改 TTS 音色 `hermes config set tts.edge.voice zh-CN-XiaoyiNeural` 成功,patch 被拒 `Refusing to write to Hermes config file`;改完无需重启 gateway,下次调用即生效)
|
||||
- fallback_providers 必须是 provider+model dict 列表,不是裸 provider 名字。`["deepseek"]` 字符串格式被 Hermes 忽略——用 hermes fallback add 重新添加
|
||||
- 加 fallback 前必须先用 curl 测模型是否可用,否则无声失败。例如 `nvidia/nemotron-3-ultra-550b-a55b` 在 NewAPI 列表里有但实际报 "No available channel"
|
||||
- ⚠️ 测试模型可用性不等于测试认证:即使模型在列表中且能连通,也必须验证 API Key 是否有效且有额度/权限。建议在加入 fallback 前,用目标模型发送一个简单的测试请求(如 `max_tokens: 1`)确认能获得正常响应。
|
||||
|
|
|
|||
|
|
@ -343,6 +343,39 @@ if content_match:
|
|||
|
||||
---
|
||||
|
||||
## Firecrawl 对比参考(2026-08-11 研究 165k⭐)
|
||||
|
||||
> 已镜像:`~/projects/ai-collection/firecrawl/`(main 快照)。**不替代本工具链**,仅作架构参考。
|
||||
|
||||
### firecrawl 的架构(产品级抓取平台)
|
||||
|
||||
```
|
||||
apps/api(Fastify API + worker 队列)
|
||||
├─ /v1/scrape — 单页抓取(返回 markdown/json)
|
||||
├─ /v1/crawl — 整站爬取(异步 job)
|
||||
├─ /v1/search — 搜索+抓取
|
||||
└─ /v1/map — 站点地图发现
|
||||
apps/*-sdk(Python/Node/Rust 官方 SDK)
|
||||
firecrawl-cli + firecrawl-skills(把 CLI 封装成 agent skill,教编码 agent 会话内用)
|
||||
SELF_HOST.md(自托管 docker-compose)
|
||||
```
|
||||
|
||||
### 可借鉴点(对我们)
|
||||
|
||||
| firecrawl | 我们 | 借鉴 |
|
||||
|-----------|------|------|
|
||||
| `/v1/crawl` 异步 job 队列 | crawl4ai 单页 | 批量爬取时可参考 job 队列设计 |
|
||||
| firecrawl-skills(独立仓库教 agent 用 CLI)| web-content-extraction skill | ✅ 已类似:把工具封装成 skill |
|
||||
| 多 SDK 官方支持 | hermes-web-extract CLI 封装 | 需要 Python SDK 时参考 |
|
||||
| 自托管 docker-compose | 本地二进制 | 需要分布式抓取时参考 |
|
||||
|
||||
### 结论
|
||||
- 单页抓取/markdown 提取 → 继续用 crawl4ai(已验证 1.6s)
|
||||
- 批量/整站爬取 → scrapy 或参考 firecrawl crawl job 设计
|
||||
- **暂不引入 firecrawl 依赖**(我们已有完整工具链,firecrawl 是 API 服务需部署,且核心价值与我们重叠)
|
||||
|
||||
---
|
||||
|
||||
## 完整工具链架构
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -45,6 +45,23 @@ description: 主动发现并推荐GitHub开源项目时使用。收集→LLM筛
|
|||
7. **seen 只存"最近推荐的"(最多 20 个)**:存"所有见过的"会导致测试/积累后无新候选 → 永久哑火。只存本次 picks → 下周只滤掉 3-5 个,其余仍新鲜。
|
||||
8. **周期性交付任务不能静默**:no_agent 空输出=什么都不推=用户以为坏了。无新候选时输出"本周无新候选"提示。
|
||||
|
||||
## 手动即时推荐(牧尘随时问"有什么推荐"时用,2026-08-11 实测)
|
||||
|
||||
不用等每周一 cron,牧尘随口问推荐时直接手动抓——**用 GitHub Search API 比跑周报脚本快得多**:
|
||||
|
||||
- **不要跑 `github-weekly-digest.py --dry-run`**:实测 180s 超时(RSSHub 抓取慢 + 多主题串行),等不起。
|
||||
- **直接调 Search API**(25s 超时内返回):
|
||||
```bash
|
||||
# 按 topic 抓热榜(ai-agents / llm+memory 等组合主题)
|
||||
curl -s "https://api.github.com/search/repositories?q=topic:ai-agents&sort=stars&order=desc&per_page=8" | python3 -c "
|
||||
import json,sys; d=json.load(sys.stdin)
|
||||
for it in d.get('items',[]): print(f\"{it['full_name']} ⭐{it['stargazers_count']} | {(it.get('description') or '')[:70]}\")"
|
||||
```
|
||||
- **给用户前先对照 `seen` 文件**(`~/.hermes/data/github_digest_seen.json`)和上期周报输出,跳过已推荐过的(supabase/agno/graphify 等)。
|
||||
- **推荐语按用户画像组织**:记忆系统同赛道(mempalace/EverOS)→ 建议研究借鉴织忆;Agent 框架 → 建议借鉴 skill 管理;明确给出"最值得研究哪个"的建议,不要平铺。
|
||||
- **推荐输出格式(2026-08-11 实测牧尘认可)**:🥇🥈🥉 分级 + 每个给「为什么值得研究」(关联现有系统:织忆/skill 管理/爬虫)+ 链接;备选放 🎁 组。收尾问句:要不要拉下来深研究(像 LightMem 那样)/ 先推 Gitea 存档。
|
||||
- 用户说"都下载研究"→ 走 gitea-repo-mirroring 批量流程(查重→clone→推 Gitea→研究),firecrawl 173MB 大仓库注意镜像不稳。
|
||||
|
||||
## 模型选型经验(免费模型做自动化的通用参考)
|
||||
|
||||
| 场景 | 模型 | 原因 |
|
||||
|
|
|
|||
|
|
@ -163,3 +163,4 @@ content = base64.b64decode(d2['content']).decode('utf-8', 'ignore')
|
|||
- `references/2026-08-01-research-cases-batch2.md` — strix(AI 渗透)、grok-build(编码 Agent,含搜索跑偏案例 + 源码深读模式)、Vibe-Trading(量化交易)
|
||||
- `references/2026-08-02-research-cases-batch3.md` — ai-agent-book(李博杰 Agent 书,ch3/ch8 对标织忆)、ui-skills(UI 质量技能集)、croc(安全文件传输)+ MCP 工具全流程方法论
|
||||
- `references/2026-08-10-research-mapcn.md` — mapcn(React 地图组件库,11.3k stars,CARTO 底图许可注意)+ tarball 整仓下载法实测
|
||||
- `references/2026-08-10-research-lightmem.md` — LightMem(浙大 zjunlp 记忆增强生成框架,ICLR 2026,1.1k stars)+ 与织忆对照结论(不替代、借鉴 llmlingua-2 预压缩)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
# 2026-08-10 调研:zjunlp/LightMem(浙大 NLP 记忆框架)
|
||||
|
||||
> 触发:牧尘丢来 GitHub 链接要求研究。走标准调研流程(API 元数据 → README 深读 → 本地兼容检查 → 与织忆对照)。
|
||||
|
||||
## 元数据(api.github.com 实测)
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 全名 | zjunlp/LightMem: Lightweight and Efficient Memory-Augmented Generation |
|
||||
| ⭐ | 1,078(实测) |
|
||||
| 论文 | ICLR 2026(arXiv:2510.18866) |
|
||||
| 协议 | MIT ✅ |
|
||||
| 语言 | Python 3.11 |
|
||||
| 状态 | 活跃(2026-08-10 还在提交;入选 CCF ODTC 开源激励计划) |
|
||||
| Topics | agent / memory / long-term-memory / rag / memory-management / personalization |
|
||||
|
||||
## 它解决什么
|
||||
|
||||
长运行 LLM/Agent 的 **Context bloat(上下文膨胀)+ Token 浪费 + 缓存利用率低** 三痛点。
|
||||
管线:对话进来 → 预压缩 → 主题分段 → 元数据/摘要提取 → 向量+BM25 混合检索 → 只喂相关记忆给模型。
|
||||
|
||||
## 核心模块与后端(README 实测)
|
||||
|
||||
| 模块 | 功能 | 后端 |
|
||||
|---|---|---|
|
||||
| PreCompressor | 存前压缩(省 token 省存储) | `llmlingua-2` / `entropy_compress` |
|
||||
| TopicSegmenter | 长对话按主题切段独立索引 | `llmlingua-2` |
|
||||
| MemoryManager | 摘要+元数据生成 | OpenAI / **DeepSeek**(含 deepseek-v4-flash/pro,支持 reasoning_effort)/ Ollama / vLLM |
|
||||
| TextEmbedder | 向量嵌入 | huggingface(默认 all-MiniLM-L6-v2, 384 维) |
|
||||
| Retriever | 语义/关键词检索 | Qdrant / FAISS / BM25 |
|
||||
| graph_mem | 图记忆(可选) | 需额外图处理/存储 |
|
||||
| MCP Server | 直接接 MCP 客户端 | `fastmcp run mcp/server.py:mcp --transport http --port 8000` |
|
||||
|
||||
**关键配置项**(BaseMemoryConfigs):
|
||||
- `pre_compress` / `topic_segment` / `metadata_generate` / `text_summary` 开关
|
||||
- `index_strategy`: `embedding` / `context` / `hybrid`
|
||||
- `update`: **`offline`(完整支持)** / `online`(占位 no-op,不持久化)
|
||||
- `extraction_mode`: `flat`(事实独立单元)/ `event`(事件级,保时间绑定与因果)
|
||||
- BoundMem 可选插件:`boundmem_tags` 给记忆打标签、检索按标签过滤(opt-in)
|
||||
|
||||
## 实验数据(LoCoMo 基准,README 原文)
|
||||
|
||||
| 方法 | ACC(%) gpt-4o-mini | 总 Token(k) | 耗时(s) |
|
||||
|---|---|---|---|
|
||||
| FullText | 73.83 | 54,884 | 6,971 |
|
||||
| NaiveRAG | 63.64 | 3,870 | 1,884 |
|
||||
| A-MEM | 64.16 | 21,665 | 67,084 |
|
||||
| MemoryOS(eval) | 58.25 | 10,519 | 26,129 |
|
||||
| Mem0 | 36.49 | 25,793 | 120,175 |
|
||||
| Mem0(api) | 61.69 | 72,518 | 10,445 |
|
||||
|
||||
亮点:比 A-MEM/Mem0 runtime 快 5-10 倍、token 少 50%+,精度不低于 MemoryOS。注意 README 里 LightMem 自己那行主结果不在表格(论文为准),表格列的是对比基线。
|
||||
|
||||
## 安装(2026-08-10 现状)
|
||||
|
||||
- `pip install lightmem` 标 **"Coming soon"**——目前只能源码装:`git clone` + `conda create -n lightmem python=3.11` + `pip install -e .`
|
||||
- Quick Start 需下 2 个 HF 模型:llmlingua-2(~400MB)+ all-MiniLM-L6-v2(~90MB)+ 数据集 longmemeval-cleaned
|
||||
- 本地 Python 3.11.15 ✅;qdrant/faiss 未装(首次跑需 pip 装)
|
||||
|
||||
## 源码深读产出(2026-08-10 二次研究,tarball 拉取)
|
||||
|
||||
> 源码:`~/projects/zjunlp/LightMem/`(8.8MB tarball 完整)。主模块 11929 行,核心 `memory/lightmem.py`(879 行)+ `memory/prompts.py`(415 行)。
|
||||
|
||||
### add_memory 全管线
|
||||
```
|
||||
输入 → 1. MessageNormalizer(统一时间戳/会话)
|
||||
→ 2. PreCompressor(可选,llmlingua-2 压缩每条 content)
|
||||
→ 3. TopicSegmenter(可选,主题分段,双缓冲触发)
|
||||
→ 4. ShortMemBuffer(2000 token 积累,阈值触发提取)
|
||||
→ 5. 提取 LLM(逐条消息判断事实 → 补全独立句 → 输出 JSON facts)
|
||||
→ 6. MemoryEntry(带 time_stamp / weekday / speaker / topic_id)
|
||||
→ 7. offline_update(存时同时记录相似候选 update_queue)
|
||||
```
|
||||
|
||||
### 三个可移植织忆的设计(优先级 1>2>3)
|
||||
| # | 设计 | LightMem 精髓 | 织忆借鉴 |
|
||||
|---|------|--------------|---------|
|
||||
| 1 | **逐条事实提取 prompt** | 逐消息按序判断是否含事实("Unless purely meaningless, extract it")→ 轻量补全独立句 → 保留全部实体细节(全名/地点/数字/公司名)→ 推断隐含 → 时间区分(mention time vs event time)→ 输出 `{"data":[{"source_id":N,"fact":"..."}]}` | 织忆 distill 升级:整段压缩 → 原子事实,正好喂知识图谱节点 |
|
||||
| 2 | **离线整合 UPDATE_PROMPT** | 找 update_queue 相似候选(score≥阈值)→ LLM 三选一:update(合并细节)/ delete(冲突且候选新则删目标)/ ignore;只改目标不动候选,输出 `{"action":...,"new_memory":{...}}` | 织忆加记忆合并/冲突消解,图谱去重 |
|
||||
| 3 | **双缓冲触发** | Sensory 512 token(满则分段,超长单条单独成段不阻塞)→ Short-term 2000 token(满则一次 LLM 提取,批量省 API);force_extract/force_segment 手动触发 | 织忆 distill 时机:token 积累再批量调用 |
|
||||
|
||||
### 检索设计
|
||||
query → embed → 向量检索(Qdrant/FAISS)→ 返回 `"{time_stamp} {weekday} {memory}"` 格式化字符串;可选 BM25 混合 + BoundMem tag 过滤(按重叠 tag 保留)。
|
||||
|
||||
### 模型需求(部署成本)
|
||||
| 组件 | 模型 | 大小 |
|
||||
|---|---|---|
|
||||
| 预压缩 | microsoft/llmlingua-2-bert-base-multilingual-cased-meetingbank | ~400MB 可 CPU |
|
||||
| 嵌入 | sentence-transformers/all-MiniLM-L6-v2 | ~90MB(384 维) |
|
||||
| 记忆管理 | OpenAI/DeepSeek/Ollama API | 免费可用 NewAPI |
|
||||
| 向量库 | Qdrant(本地)/ FAISS | 可选 |
|
||||
|
||||
## 与织忆(MemoryWeave)对照 → 结论:不替代,借鉴预压缩
|
||||
|
||||
| 维度 | 织忆 | LightMem |
|
||||
|---|---|---|
|
||||
| 形态 | Go daemon + Rust sidecar + 图谱(5766 节点) | Python 库 + MCP server |
|
||||
| 记忆组织 | 语义 + 知识图谱 | 主题分段 + 摘要 + 向量 |
|
||||
| 检索 | bge-m3 嵌入 + 图谱导航 | Qdrant/FAISS + BM25 混合 |
|
||||
| 压缩 | ❌ 无预压缩 | ✅ llmlingua-2 预压缩(独有亮点) |
|
||||
| 更新 | distill 管道 | offline 批量更新 |
|
||||
| 部署 | 已生产运行 | 研究框架 |
|
||||
|
||||
**建议**:选 B(只研究架构)——织忆已生产、图谱更强,不值得换;但 **llmlingua-2 预压缩思想值得移植**:织忆若加"存前压缩",长对话 token 成本可降。落地选项 A 试跑(下 2 模型)/ B 只研究(免费)/ C 接 MCP / D 归档。
|
||||
|
||||
## 系列生态
|
||||
|
||||
LightMem 系列:LightMem(本仓)/ LightMem2(模块化长运行 agent 记忆)/ LightMem-Ego(流式多模态日常助手)。
|
||||
对比基线框架:zjunlp/MemBase(LoCoMo/LongMemEval 多记忆层基准)。
|
||||
|
|
@ -130,6 +130,9 @@ git clone http://SERVER/repo5.git repo5 2>&1 &
|
|||
| multica | Go+Next.js | agent 生命周期管理,Squad 路由,skill 复用 |
|
||||
| agent-second-brain | Python | Telegram 语音优先,vault 健康评分,每日报告 |
|
||||
| Foretold | ❌ SSH 认证不可达 | — |
|
||||
| LightMem | Python | **zjunlp 浙大,1078⭐,ICLR 2026**:逐条事实提取 prompt + 离线整合 UPDATE_PROMPT + 双缓冲(Sensory 512→Short-term 2000)+ llmlingua-2 预压缩。织忆 distill 改造的直接参考(2026-08-11 已移植 P1) |
|
||||
| mempalace | Python | **MemPalace,58k⭐,本地优先**:逐字存储(绝不总结/蒸馏)+ 宫殿结构(WING→ROOM→DRAWER)+ AAAK 压缩索引(结构化符号摘要,LLM 原生可读)+ BM25+向量混合检索 + 实体优先消歧 + 可插拔后端(ChromaDB 默认)。LongMemEval 96.6% R@5 零 API 调用。**与织忆哲学相反:织忆蒸馏、它保真**。详见 references/2026-08-11-mempalace-everos-notes.md |
|
||||
| EverOS | Python | **EverMind-AI,11.9k⭐,md-first 记忆**:Markdown 真相 + SQLite 状态 + LanceDB(向量+BM25+标量)三件套 + DDD 5 层单向依赖 + everalgo 独立算法库。存储分层可借鉴。详见 references/2026-08-11-mempalace-everos-notes.md |
|
||||
|
||||
## 关键设计模式(可迁移到织忆)
|
||||
|
||||
|
|
@ -200,6 +203,8 @@ git clone http://SERVER/repo5.git repo5 2>&1 &
|
|||
| `2026-07-13-memory-systems-notes.md` | 9 个参考记忆系统对比分析 | 2026-07-13 |
|
||||
| `2026-07-19-jarvis-agent-landscape-notes.md` | MyJarvis L1-L6 架构调研 | 2026-07-19 |
|
||||
| `2026-07-30-codebase-memory-mcp.md` | **codebase-memory-mcp** — C 实现的代码知识图谱 MCP 服务器(158语言,15 MCP 工具,arXiv 论文),织忆互补系统 | 2026-07-30 |
|
||||
| `2026-08-11-lightmem-notes.md` | **LightMem** — zjunlp 逐条事实提取 prompt / 离线整合 UPDATE_PROMPT / 双缓冲触发,已移植织忆 distill P1 | 2026-08-11 |
|
||||
| `2026-08-11-mempalace-everos-notes.md` | **mempalace**(逐字存储/AAAK 压缩索引/BM25+向量混合/实体优先,LongMemEval 96.6%)+ **EverOS**(md-first 三件套存储/DDD 分层/everalgo 算法库)— 织忆借鉴参考 | 2026-08-11 |
|
||||
|
||||
每次调研后,将原始 notes 保存到:
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
# LightMem 源码研究笔记(2026-08-11)
|
||||
|
||||
> zjunlp/LightMem — 浙大 NLP 实验室,1078⭐,ICLR 2026,MIT,Python
|
||||
> 定位:轻量高效的大模型/Agent 长期记忆管理框架
|
||||
> 源码:`~/projects/zjunlp/LightMem`(tarball 法下载,8.8MB 完整)
|
||||
> 报告:`~/小唯/07-Wiki/concepts/LightMem-源码研究-织忆可移植设计.md`
|
||||
|
||||
## 一句话结论
|
||||
|
||||
不替代织忆,但三个设计直接可移植:①逐条事实提取 prompt ②离线整合 UPDATE_PROMPT ③双缓冲触发。已移植 P1(逐条事实提取)到织忆 distill 引擎。
|
||||
|
||||
## 核心管线(add_memory 全流程)
|
||||
|
||||
```
|
||||
输入消息 → MessageNormalizer(统一时间戳/会话)
|
||||
→ PreCompressor(可选,llmlingua-2 压缩每条 content)
|
||||
→ TopicSegmenter(可选,主题分段,双缓冲触发)
|
||||
→ ShortMemBuffer(2000 token 积累,阈值触发提取)
|
||||
→ 提取 LLM(逐条消息判断事实 → 补全独立句 → 输出 JSON facts)
|
||||
→ MemoryEntry(带 time_stamp / weekday / speaker / topic_id)
|
||||
→ offline_update(存时同时记录相似候选 update_queue)
|
||||
```
|
||||
|
||||
## 四个可移植设计
|
||||
|
||||
### 1. 🥇 提取 Prompt(prompts.py METADATA_GENERATE_PROMPT)
|
||||
- 逐条消息**按序**判断是否含事实(不是整段摘要)
|
||||
- **不跳过小细节**("User drank coffee this morning" 也要保留)
|
||||
- **轻量上下文补全**:`"My friend John is studying medicine"` → `"User's friend John is studying medicine."`
|
||||
- **保留全部实体细节**:全名/地点/事件/数字/公司名
|
||||
- **推断隐含信息**:多个相关条目 → 推断一般模式
|
||||
- **时间区分**:mention time vs event time
|
||||
- 输出严格 JSON:`{"data": [{"source_id": N, "fact": "..."}]}`
|
||||
|
||||
### 2. 🥈 离线整合 Update Prompt(UPDATE_PROMPT)
|
||||
对每条记忆,找 update_queue 里相似度 ≥ 阈值的候选,LLM 三选一:
|
||||
- **update**:同事实但候选更细 → 合并细节
|
||||
- **delete**:直接冲突且候选更新 → 删目标
|
||||
- **ignore**:不相关 → 跳过
|
||||
- 只改目标记忆,不动候选
|
||||
|
||||
### 3. 🥉 双缓冲触发
|
||||
- Sensory buffer:512 token,积累 user 消息,**满则触发分段**
|
||||
- 超长单条消息:单独成段(oversize_segment)不阻塞
|
||||
- Short-term buffer:2000 token,**满则触发一次 LLM 提取**(批量省 API)
|
||||
- force_extract / force_segment 手动触发
|
||||
|
||||
### 4. 主题分段 + 全局 topic_id
|
||||
llmlingua-2 切主题 → 每段独立索引 → **全局递增 topic_id**(GLOBAL_TOPIC_IDX)→ 记忆带 topic 归属,检索跨主题关联。
|
||||
|
||||
## 检索设计
|
||||
|
||||
- query → embed → embedding_retriever.search(Qdrant/FAISS)
|
||||
- 返回 `"{time_stamp} {weekday} {memory}"` 格式化字符串
|
||||
- 可选:BM25 + 向量 hybrid;BoundMem tag 过滤
|
||||
|
||||
## 模型需求
|
||||
|
||||
| 组件 | 模型 | 大小 |
|
||||
|------|------|------|
|
||||
| 预压缩 | microsoft/llmlingua-2-bert-base-multilingual-cased-meetingbank | ~400MB |
|
||||
| 嵌入 | sentence-transformers/all-MiniLM-L6-v2 | ~90MB |
|
||||
| 记忆管理 | OpenAI/DeepSeek/Ollama API | — |
|
||||
| 向量库 | Qdrant/FAISS | — |
|
||||
|
||||
## 织忆 P1 移植(2026-08-11 ✅ 已部署验证)
|
||||
|
||||
- 文件:`/tmp/memoryweave/go/internal/distill/engine.go` `callLLM5D` prompt 重写
|
||||
- 要点:LightMem 式逐条事实提取(不跳过小细节、补全独立句、保留实体细节、时间区分、推断隐含)
|
||||
- 计划:`/tmp/memoryweave/docs/lightmem-p1-fact-extraction-plan.md`
|
||||
- 提交:`0734ffa`(2 files, 113 insertions)
|
||||
- **验证结果(实测)**:提交含 4 条事实的测试内容 → 日志 `LLM facts: 4` + `LLM entities: 6`(旧版整段摘要只有 1 条);recall 命中 `"小唯安装了ffmpeg用于语音转码"` score=0.879
|
||||
- 注意:Gitea push 因审批拦截未完成(remote 需 token,涉及 token 的复合命令被拦)——本地 commit 已就绪,下次可单独 push
|
||||
|
||||
## 系列生态
|
||||
|
||||
- LightMem2(模块化)、LightMem-Ego(多模态流式)、StructMem(层次记忆, ACL 2026)
|
||||
- 评估框架:zjunlp/MemBase(LoCoMo / LongMemEval 基准)
|
||||
- 论文:arXiv:2510.18866
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
# mempalace + EverOS 研究笔记(2026-08-11)
|
||||
|
||||
> 来源:批量 AI 项目研究(GitHub 热榜推荐),与织忆同赛道/互补的两个记忆系统。
|
||||
> 完整研究报告:`~/小唯/07-Wiki/concepts/ai-projects-batch-research-2026-08-11.md`
|
||||
> 本地源码:`~/projects/ai-collection/mempalace/`、`~/projects/ai-collection/EverOS/`(已镜像 Gitea)
|
||||
|
||||
## mempalace(MemPalace,58k⭐,Python)
|
||||
|
||||
### 核心哲学:逐字存储(与织忆的 LLM 蒸馏相反)
|
||||
|
||||
- **Verbatim 铁律**:不总结、不提取、不转述,原样存用户的话。"Memory is identity."
|
||||
- **宫殿结构**:WING(人/项目)→ ROOM(时间/主题)→ DRAWER(逐字文本块),源自记忆宫殿法 + Zettelkasten
|
||||
- **AAAK 压缩索引**(`dialect.py`):结构化符号摘要格式(Header: FILE_NUM|PRIMARY_ENTITY|DATE|TITLE + Zettel: ZID:ENTITIES|topic_keywords|"key_quote"|WEIGHT|EMOTIONS|FLAGS + Tunnel + Arc),**LLM 原生可读、无需解码器**。注意 AAAK 是 lossy(原文本不可重建),但索引层让 LLM 扫数千条即刻定位目标 drawer
|
||||
- **混合检索**(`searcher.py`):Okapi-BM25 关键词 + 向量语义双路 + min-max 归一化 + rerank
|
||||
- **实体优先**(`entity_detector.py`):两遍法(候选扫描→评分分类 person/project),一切按真实姓名 + 消歧键(DOB/ID/上下文)
|
||||
- **可插拔后端**:`backends/base.py` 抽象接口,ChromaDB 默认
|
||||
- **性能预算**:hook <500ms、启动注入 <100ms
|
||||
- **本地优先**:默认零外部 API(Ollama/LM Studio/llama.cpp/vLLM),BYOK 需显式配置
|
||||
- **Benchmark**:LongMemEval 96.6% R@5(raw mode,零 API 调用)
|
||||
|
||||
### 对织忆的启示(优先级高)
|
||||
|
||||
1. **AAAK 压缩索引** → 织忆图谱节点/边可借鉴"压缩摘要+指针"设计,降低蒸馏 LLM 调用成本
|
||||
2. **BM25+向量混合** → 织忆当前仅向量检索,加 BM25 路提升关键词命中(LightMem P2 相似度升级的参考方向)
|
||||
3. **实体优先** → 织忆 P1 已做实体提取,可加强"人/项目"维度消歧
|
||||
4. **逐字 vs 蒸馏哲学对比** → 织忆选蒸馏(省空间/高密度),mempalace 选逐字(100% 保真)。互补:织忆可加"原文抽屉"层保底
|
||||
|
||||
## EverOS(EverMind-AI,11.9k⭐,Python)
|
||||
|
||||
### 核心:md-first 记忆提取框架
|
||||
|
||||
- **存储三件套**:Markdown(真相/唯一真相源)+ SQLite(状态/audit/queue)+ LanceDB(向量+BM25+标量),索引可从 md 重建
|
||||
- **DDD 5 层单向依赖**:entrypoints → service → memory → infra,import-linter 强制,违反即 CI 失败
|
||||
- **记忆根目录**:`~/.everos/{agents,users,knowledge}/`(md 文件 = 单源真值)
|
||||
- **算法独立库**:everalgo(prompts/extractors 独立 PyPI 发布),算法与框架解耦
|
||||
- **工程纪律**:datetime 统一工具(禁直接 now())、CJK 语言策略、CI 门禁(make ci)
|
||||
|
||||
### 对织忆的启示
|
||||
|
||||
1. **Markdown 真相层 + SQLite 状态 + LanceDB 索引** → 织忆已有 LanceDB,可加 md 导出层(可读、可迁移、防锁死)
|
||||
2. **everalgo 独立算法库** → 织忆的蒸馏/整合 prompt 可独立成库,方便迭代版本对比
|
||||
3. **DDD 分层 + import-linter** → 织忆 Go 代码分层纪律参考(当前 internal/ 结构已接近)
|
||||
|
||||
## 同批研究的非记忆系统(ECC / ponytail / firecrawl)简述
|
||||
|
||||
- **ECC**(239k⭐,JS):68 专业 agent + 285 skills + 94 commands 编码编排体系。TDD 强制(RED→GREEN→REFACTOR,80%+ 覆盖)+ 安全铁律 + 自动编排规则(写完代码自动→code-reviewer)
|
||||
- **ponytail**(100k⭐,JS):「懒惰资深开发」7 阶梯决策框架(YAGNI→复用→标准库→平台→依赖→一行→最小代码),实测 ~54% 少代码、~20% 便宜、~27% 快。Bug 修根因不修症状、`ponytail:` 注释标注简化天花板
|
||||
- **firecrawl**(165k⭐,TS):产品级 Web 抓取平台(apps/cli/skills/workflows/自托管),与 web-content-extraction 工具链可对比
|
||||
|
||||
## 批量下载教训(大仓库)
|
||||
|
||||
firecrawl 173MB:gh-proxy clone 卡死(17min 下 5.4MB,CPU 3s = 网络死)→ kill(用 PID 不用 pkill -f,防自杀)→ aria2c -x 16 -s 16 codeload tar.gz(274KiB/s 成功)→ git init 单提交快照推 Gitea(丢历史但可归档)。详见 gitea-repo-mirroring skill pitfall 12-13。
|
||||
|
|
@ -379,6 +379,22 @@ grep "shutdown notification" ~/.hermes/logs/gateway.log
|
|||
|
||||
**验证**:重启 gateway 后,观察另一台机器的飞书是否收到通知。
|
||||
|
||||
## 语音消息(msg_type=audio)— 必须真 .ogg/.opus(2026-08-10 实测)
|
||||
|
||||
**飞书「可点播放的语音气泡」只接受 `.ogg` / `.opus` 扩展名**(Hermes 飞书 adapter `_FEISHU_OPUS_UPLOAD_EXTENSIONS = {".ogg", ".opus"}`,按扩展名路由 `("opus", "audio")`)。`.mp3`/`.wav` 等只能发成文件附件(要下载才能听)。
|
||||
|
||||
**⚠️ 陷阱**:`edge-tts --write-media xxx.ogg` 只是改扩展名,内容仍是 `MPEG ADTS`(mp3)——飞书服务器验内容会失败。必须真正转码成 Ogg Opus。
|
||||
|
||||
**正确做法**(ffmpeg 已装):
|
||||
|
||||
```bash
|
||||
edge-tts -t "文本" -v "zh-CN-XiaoxiaoNeural" --write-media out.mp3
|
||||
python3 ~/.hermes/scripts/to_opus.py out.mp3 out.opus # ffmpeg -c:a libopus -b:a 24k -ar 24000 -ac 1
|
||||
# 回复里用 MEDIA:<out.opus> → 飞书显示为语音气泡
|
||||
```
|
||||
|
||||
验证:`file out.opus` 应显示 `Ogg data, Opus audio`。判断用户收到的是语音气泡还是文件:飞书端能否直接点播放。
|
||||
|
||||
## 群聊(Group)故障排查(2026-05-12)
|
||||
|
||||
**症状**:DM 正常,群聊 0 条消息(Gateway 日志 `oc_81f6df` 从无 inbound)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
name: lazy-senior-dev
|
||||
description: 写代码/实现功能时用 7 阶梯最小化决策。触发词"少写代码""别过度设计""最小实现"。
|
||||
version: 1.0.0
|
||||
author: 小唯 A06
|
||||
tags: [code-minimalism, ponytail, yagni, code-style]
|
||||
trigger: "写代码/实现功能时希望最小化;或用户说:少写点代码、别过度设计、只要最小实现、别加没用的东西"
|
||||
created: 2026-08-11
|
||||
updated: 2026-08-11
|
||||
---
|
||||
|
||||
# 最小化编码(Lazy Senior Dev — 源自 ponytail 100k⭐)
|
||||
|
||||
> 来源:DietrichGebert/ponytail(实测 ~54% 少代码 / ~20% 便宜 / ~27% 快,基准 vs 同一 agent 无 skill)
|
||||
> 核心信条:**最好的代码是从未写过的代码**。Lazy = 高效,不是粗心。
|
||||
|
||||
## 7 阶梯决策框架(写任何代码前,逐级停)
|
||||
|
||||
写代码前**先完整理解问题**(读任务 + 涉及的代码 + 从头到尾追踪真实流程),然后从第 1 级开始爬,停在第一个成立的台阶:
|
||||
|
||||
1. **需要建吗?**(YAGNI)— 这个功能真的需要吗?还是可以不做/推迟?
|
||||
2. **代码库已有?** — 复用现成的 helper/util/pattern,不重写
|
||||
3. **标准库能做?** — 用它,不引第三方
|
||||
4. **原生平台功能覆盖?** — 平台自带的能力,不自己造
|
||||
5. **已装依赖能解决?** — 用它,不新增依赖
|
||||
6. **能一行吗?** — 写一行
|
||||
7. **最后:写最少可用代码**
|
||||
|
||||
## 硬性规则
|
||||
|
||||
- ❌ 无未明确请求的抽象
|
||||
- ❌ 无可以避免的新依赖
|
||||
- ❌ 无没人要的样板代码
|
||||
- ✅ **删 > 加**;**无聊 > 聪明**;**最少文件**
|
||||
- ✅ 最短可用 diff 胜出——**但必须先理解问题**。最小改动放在错误的地方不是懒,是第二个 bug
|
||||
- ✅ 质疑复杂请求:"你确定需要 X,还是 Y 就够了?"
|
||||
- ✅ 两个标准库方案同样大小时,选边界情况正确的那个(懒 = 代码更少,不是算法更弱)
|
||||
- ✅ 有意简化(全局锁/O(n²)扫描/朴素启发式)→ 必须 `ponytail:` 注释标注天花板和升级路径
|
||||
|
||||
## 绝不偷懒的地方
|
||||
|
||||
- ❌ **理解问题**(读完整 + 追踪真实流程后再爬梯子;看不懂就改小 = 懒但假装高效)
|
||||
- ❌ 信任边界的输入校验
|
||||
- ❌ 防止数据丢失的错误处理
|
||||
- ❌ 安全、无障碍
|
||||
- ❌ 真实硬件的校准(平台永远不是规范理想:时钟会漂移、传感器有偏差)
|
||||
- ❌ 任何用户明确要求的事
|
||||
|
||||
## 验证纪律
|
||||
|
||||
- 非平凡逻辑**必须留 1 个可运行检查**——能失败的最小验证(assert 演示/自检或 1 个小测试文件,无框架无 fixture)
|
||||
- 平凡的一行代码无需测试
|
||||
|
||||
## Bug 修复 = 修根因,不修症状
|
||||
|
||||
- 报告命名的是症状。grep 你改的函数的**每个调用者**,修共享函数一次——一个守卫是比每个调用者都改更小的 diff
|
||||
- 只修 ticket 指名路径 = 兄弟调用者仍然坏着
|
||||
|
||||
## 落地示例(我的场景)
|
||||
|
||||
| 场景 | 之前 | 之后(7阶梯) |
|
||||
|------|------|--------------|
|
||||
| 写脚本 | 先装 pandas 再处理 | 标准库 csv/json 能搞定就不装 |
|
||||
| 加功能 | 建抽象类/接口 | 先问:真需要抽象吗?函数够不够? |
|
||||
| 修 bug | 在调用处加 if | grep 所有调用者,修源头函数一次 |
|
||||
| 加依赖 | 直接 pip install | 已装依赖/标准库/平台能力有没有覆盖? |
|
||||
|
||||
## 检查清单(动手前过一遍)
|
||||
|
||||
- [ ] 我理解问题吗?(读代码、追流程)
|
||||
- [ ] 这需要建吗?YAGNI?
|
||||
- [ ] 已有代码/标准库/平台/已装依赖能覆盖?
|
||||
- [ ] 能更短吗?能一行吗?
|
||||
- [ ] 我的简化有 `ponytail:` 注释和升级路径吗?
|
||||
- [ ] 非平凡逻辑有 1 个可运行检查吗?
|
||||
|
|
@ -7,6 +7,47 @@ updated: 2026-07-13(画像可执行化 v2 + 参考项目对比分析)
|
|||
|
||||
---
|
||||
|
||||
## P2+P3 完成:离线整合 + 双缓冲触发(2026-08-11)
|
||||
|
||||
**改动**(commit `82c3d25`,已部署 + 推 Gitea):
|
||||
- **P2 离线整合**:`go/internal/distill/consolidate.go` 新增 `ConsolidateMemory`(LLM 三选一 update/delete/ignore,移植 LightMem UPDATE_PROMPT)+ `TextSimilarity`(词重叠相似度,中文2-gram/英文单词);`server.go` 新增 `POST /api/v1/consolidate/memory {"namespace":"hermes-main","limit":50}` 手动触发端点
|
||||
- **P3 双缓冲**:`engine.go` Enqueue 按 token 积累触发 flush(阈值 2000,`estimateTokens` = rune/2),batchTimeout 5min 兜底
|
||||
- **fix JSON 剥离**:LLM 响应剥离增强(找首个 `{` 和最后 `}` 截取),修复模型返回 markdown/注释导致 parse error
|
||||
|
||||
**验证结果**:
|
||||
- P2:`processed:1 ignored:1`(能找到相似对并调 LLM 决策,无错误)
|
||||
- P3:小内容积累 `queue_len:2` 不立即 flush,达阈值 `batch=4` 批量蒸馏
|
||||
- JSON 修复:`LLM facts: 4` 无 parse error
|
||||
- 全链路健康:memories 6822→6836,recall 正常
|
||||
|
||||
**P2 端点**:`POST /api/v1/consolidate/memory`(namespace 必填,默认 hermes-main;limit 默认 50;相似度阈值 0.5)
|
||||
|
||||
**待做**:~~P2 每日 cron 自动触发~~ ✅ **已并入** `memory-system-self-upgrade.py`(cron `691709a8b4cf` 每日 4:00)——在 `upgrade_zhiyi()` 里加 consolidate API 调用,输出报告到飞书;P2 用词重叠近似相似度,可升级为向量相似度
|
||||
|
||||
## LightMem 逐条事实提取改造(2026-08-11 上线)
|
||||
|
||||
**目标**:织忆 distill 从「整段摘要式提取」升级为「逐条事实提取」(借鉴 zjunlp/LightMem,ICLR 2026)。
|
||||
|
||||
**改动**:`go/internal/distill/engine.go` `callLLM5D` prompt 重写(commit `0734ffa`,已部署 + 推 Gitea)。
|
||||
|
||||
**新 prompt 精华**:
|
||||
- 逐条判断:除非纯问候/填充,否则每条消息都提取为独立事实
|
||||
- 轻量上下文补全:`"user: 昨天买了苹果"` → `"用户昨天买了苹果。"`
|
||||
- 保留全部实体细节:完整名称/地点/事件/数字/公司名
|
||||
- 推断隐含信息:多个相关条目 → 推断一般模式
|
||||
- 时间区分:mention time(何时说)vs event time(何时发生)
|
||||
- 输出 JSON:`{"facts": [...], "entities": [...], "decisions": [...], "conclusions": [...], "is/su/pa/vd/ru": 0-1}`
|
||||
|
||||
**验证结果(端到端实测)**:
|
||||
- `LLM facts for content: 4 facts`(旧版只有 1 条整段摘要)
|
||||
- `LLM entities: 6 entities`
|
||||
- recall 命中独立事实:`"小唯安装了ffmpeg用于语音转码"`(score=0.879)
|
||||
- 真 LLM 调用(model=meta/llama-3.1-8b-instruct),非 fallback
|
||||
|
||||
**⚠️ 部署注意**:`systemctl --user stop zhiyid` → cp 新 binary → start;验证 `journalctl --user -u zhiyid` 出现 `LLM facts: N`(N≥3 为成功)。测试内容提交后 recall 需等异步蒸馏(5-10s)。
|
||||
|
||||
**参考**:`docs/lightmem-p1-fact-extraction-plan.md`(实施计划)
|
||||
|
||||
## RSSHub → 织忆 信息源接入(2026-08-03 上线)
|
||||
|
||||
**用途**:把外部信息源(GitHub AI 内容等)定时抓取写入织忆,形成"信息触角"。管线已跑通并上线。
|
||||
|
|
|
|||
Loading…
Reference in New Issue