Skip to content

๐Ÿฆž OpenClaw ๆ ธๅฟƒๆžถๆž„็š„ๆž็ฎ€ๅค็Žฐ๏ผŒๆถต็›– sessionKey ไผš่ฏๅŸŸใ€้˜Ÿๅˆ—ไธฒ่กŒใ€ๅทฅๅ…ทๅŒ–่ฎฐๅฟ†ๆฃ€็ดขใ€ๆŒ‰้œ€ไธŠไธ‹ๆ–‡ๅŠ ่ฝฝใ€ๅฏๆ‰ฉๅฑ•ๆŠ€่ƒฝไธŽไธปๅŠจๅฟƒ่ทณๅ”ค้†’ๆœบๅˆถ

License

Notifications You must be signed in to change notification settings

voocel/openclaw-mini

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

8 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

OpenClaw Mini

OpenClaw ๆ ธๅฟƒๆžถๆž„็š„ๆž็ฎ€ๅค็Žฐ๏ผŒ็”จไบŽๅญฆไน  AI Agent ็š„็ณป็ปŸ็บง่ฎพ่ฎกใ€‚

"ๆฒกๆœ‰่ฎฐๅฟ†็š„ AI ๅชๆ˜ฏๅ‡ฝๆ•ฐๆ˜ ๅฐ„๏ผŒๆœ‰่ฎฐๅฟ† + ไธปๅŠจๅ”ค้†’็š„ AI๏ผŒๆ‰ๆ˜ฏไผšๆผ”ๅŒ–็š„'็”Ÿๅ‘ฝ็ณป็ปŸ'"

ไธบไป€ไนˆๅš่ฟ™ไธช้กน็›ฎ

็ฝ‘ไธŠๅคงๅคšๆ•ฐ Agent ๆ•™็จ‹ๅช่ฎฒ Agent Loop๏ผš

while tool_calls:
    response = llm.generate(messages)
    for tool in tools:
        result = tool.execute()
        messages.append(result)

่ฟ™ไธๆ˜ฏ็œŸๆญฃ็š„ Agent ๆžถๆž„ใ€‚ ไธ€ไธช็”Ÿไบง็บง Agent ้œ€่ฆ็š„ๆ˜ฏ"็ณป็ปŸ็บงๆœ€ไฝณๅฎž่ทต"ใ€‚

OpenClaw ๆ˜ฏไธ€ไธช80w่กŒ็š„ๅคๆ‚Agent ็ณป็ปŸ๏ผŒๆœฌ้กน็›ฎไปŽไธญๆ็‚ผๅ‡บๆ ธๅฟƒ่ฎพ่ฎกไธŽๆœ€ๅฐๅฎž็Žฐ๏ผŒๅธฎๅŠฉไฝ ็†่งฃ๏ผš

  • ไธบไป€ไนˆ้œ€่ฆ้•ฟๆœŸ่ฎฐๅฟ†๏ผŸ
  • ๅฆ‚ไฝ•ๅฎž็ŽฐๆŒ‰้œ€ไธŠไธ‹ๆ–‡ๅŠ ่ฝฝ๏ผŸ
  • ๅฆ‚ไฝ•ๅšไธŠไธ‹ๆ–‡็ฎก็†ไธŽๅŽ‹็ผฉ๏ผˆ่ฃๅ‰ช + ๆ‘˜่ฆ๏ผ‰๏ผŸ
  • ๆŠ€่ƒฝ็ณป็ปŸๆ€Žไนˆ่ฎพ่ฎกๆ‰่ƒฝๆ‰ฉๅฑ•๏ผŸ
  • ไธปๅŠจๅ”ค้†’ๆœบๅˆถ็š„็œŸๅฎžๅฎž็Žฐๆ˜ฏไป€ไนˆ๏ผŸ

ๆžถๆž„ๅฏน็…ง

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                       OpenClaw Mini                               โ”‚
โ”‚                      (ๆœฌ้กน็›ฎ ยท ็ฒพ็ฎ€ๆ ธๅฟƒ็‰ˆ)                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚   Context   โ”‚  โ”‚   Skills    โ”‚  โ”‚       Heartbeat         โ”‚   โ”‚
โ”‚  โ”‚   Loader    โ”‚  โ”‚   Manager   โ”‚  โ”‚       Manager           โ”‚   โ”‚
โ”‚  โ”‚             โ”‚  โ”‚             โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚   โ”‚
โ”‚  โ”‚ AGENTS.md   โ”‚  โ”‚ SKILL.md    โ”‚  โ”‚  โ”‚ HeartbeatWake   โ”‚    โ”‚   โ”‚
โ”‚  โ”‚ SOUL.md     โ”‚  โ”‚ ่งฆๅ‘่ฏๅŒน้…  โ”‚  โ”‚  โ”‚ (่ฏทๆฑ‚ๅˆๅนถๅฑ‚)    โ”‚    โ”‚   โ”‚
โ”‚  โ”‚ TOOLS.md... โ”‚  โ”‚ ๅ†…็ฝฎ+่‡ชๅฎšไน‰ โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚           โ”‚             โ”‚   โ”‚
โ”‚         โ”‚                โ”‚         โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚   โ”‚
โ”‚         โ”‚                โ”‚         โ”‚  โ”‚ HeartbeatRunner โ”‚    โ”‚   โ”‚
โ”‚         โ”‚                โ”‚         โ”‚  โ”‚ (่ฐƒๅบฆๅฑ‚)        โ”‚    โ”‚   โ”‚
โ”‚         โ”‚                โ”‚         โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚   โ”‚
โ”‚         โ”‚                โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚         โ”‚                โ”‚                     โ”‚                  โ”‚
โ”‚         โ–ผ                โ–ผ                     โ–ผ                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚                      Agent Loop                             โ”‚  โ”‚
โ”‚  โ”‚                                                             โ”‚  โ”‚
โ”‚  โ”‚   while (tool_calls) {                                      โ”‚  โ”‚
โ”‚  โ”‚     response = llm.generate(system_prompt + messages)       โ”‚  โ”‚
โ”‚  โ”‚     for (tool of tools) { result = tool.execute() }         โ”‚  โ”‚
โ”‚  โ”‚     messages.push(result)                                   โ”‚  โ”‚
โ”‚  โ”‚   }                                                         โ”‚  โ”‚
โ”‚  โ”‚                                                             โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚         โ”‚                                          โ”‚              โ”‚
โ”‚         โ–ผ                                          โ–ผ              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”‚
โ”‚  โ”‚   Session   โ”‚                          โ”‚   Memory    โ”‚        โ”‚
โ”‚  โ”‚   Manager   โ”‚                          โ”‚   Manager   โ”‚        โ”‚
โ”‚  โ”‚  (JSONL)    โ”‚                          โ”‚ (ๅ…ณ้”ฎ่ฏๆฃ€็ดข) โ”‚        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ”‚
โ”‚                                                                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

5 ๅคงๆ ธๅฟƒๅญ็ณป็ปŸ

ๅญ็ณป็ปŸ ๆœฌ้กน็›ฎ OpenClaw ๆบ็  ๆ ธๅฟƒ่Œ่ดฃ
Session session.ts src/agents/session-manager.ts ไผš่ฏๆŒไน…ๅŒ– (JSONL)ใ€ๅކๅฒ็ฎก็†
Memory memory.ts src/memory/manager.ts (76KB) ้•ฟๆœŸ่ฎฐๅฟ†ใ€่ฏญไน‰ๆฃ€็ดข
Context context/loader.ts src/agents/bootstrap-files.ts ๆŒ‰้œ€ๅŠ ่ฝฝ AGENTS/SOUL/TOOLS/IDENTITY/USER/HEARTBEAT/BOOTSTRAP/MEMORY
Skills skills.ts src/agents/skills/ ๅฏๆ‰ฉๅฑ•ๆŠ€่ƒฝใ€่งฆๅ‘่ฏๅŒน้…
Heartbeat heartbeat.ts src/infra/heartbeat-runner.ts
src/infra/heartbeat-wake.ts
ไธปๅŠจๅ”ค้†’ใ€ไบ‹ไปถ้ฉฑๅŠจ่ฐƒๅบฆ

ๆทฑๅ…ฅ่งฃๆž

1. Session Manager - ไผš่ฏๆŒไน…ๅŒ–

้—ฎ้ข˜๏ผšAgent ้‡ๅฏๅŽๅฆ‚ไฝ•ๆขๅคๅฏน่ฏไธŠไธ‹ๆ–‡๏ผŸ

OpenClaw ๆ–นๆกˆ๏ผš

  • JSONL ๆ ผๅผๅญ˜ๅ‚จ๏ผˆๆฏ่กŒไธ€ๆกๆถˆๆฏ๏ผŒ่ฟฝๅŠ ๅ†™ๅ…ฅ๏ผ‰
  • ๅˆ†ๅธƒๅผ้”้˜ฒๆญขๅนถๅ‘ๅ†™ๅ…ฅ
  • ่‡ชๅŠจ compaction ๅŽ‹็ผฉๅކๅฒ

ๆœฌ้กน็›ฎๅฎž็Žฐ (session.ts:45-62)๏ผš

async append(sessionId: string, message: Message): Promise<void> {
  const filePath = this.getFilePath(sessionId);
  await fs.mkdir(path.dirname(filePath), { recursive: true });
  await fs.appendFile(filePath, JSON.stringify(message) + "\n");
}

2. Memory Manager - ้•ฟๆœŸ่ฎฐๅฟ†

้—ฎ้ข˜๏ผšๅฆ‚ไฝ•่ฎฉ Agent "่ฎฐไฝ"่ทจไผš่ฏ็š„ไฟกๆฏ๏ผŸ

OpenClaw ๆ–นๆกˆ (src/memory/manager.ts)๏ผš

  • SQLite-vec ๅ‘้‡ๆ•ฐๆฎๅบ“ๅš่ฏญไน‰ๆœ็ดข
  • BM25 ๅšๅ…ณ้”ฎ่ฏๆœ็ดข
  • ๆททๅˆๆŽ’ๅบ (Hybrid Search)

ๆœฌ้กน็›ฎ็ฎ€ๅŒ– (memory.ts:85-118)๏ผš

async search(query: string, limit = 5): Promise<MemorySearchResult[]> {
  const queryTerms = query.toLowerCase().split(/\s+/);

  for (const entry of this.entries) {
    let score = 0;
    // ๅ…ณ้”ฎ่ฏๅŒน้…ๅพ—ๅˆ†
    for (const term of queryTerms) {
      if (text.includes(term)) score += 1;
      if (entry.tags.some(t => t.includes(term))) score += 0.5;
    }
    // ๆ—ถ้—ด่กฐๅ‡๏ผš่ถŠๆ–ฐ็š„่ฎฐๅฟ†ๅˆ†ๆ•ฐ่ถŠ้ซ˜
    const recencyBoost = Math.max(0, 1 - ageHours / (24 * 30));
    score += recencyBoost * 0.3;
  }
}

3. Context Loader - ๆŒ‰้œ€ไธŠไธ‹ๆ–‡

้—ฎ้ข˜๏ผšๅฆ‚ไฝ•ๆณจๅ…ฅ้กน็›ฎ็บง่ง„่Œƒ่€ŒไธๆฑกๆŸ“ๆฏๆฌกๅฏน่ฏ๏ผŸ

OpenClaw ๆ–นๆกˆ (src/agents/bootstrap-files.ts)๏ผš

  • AGENTS.md / SOUL.md / TOOLS.md / IDENTITY.md / USER.md / HEARTBEAT.md / BOOTSTRAP.md
  • MEMORY.md๏ผˆๆˆ– memory.md๏ผ‰ไฝœไธบ่ฎฐๅฟ†่กฅๅ……
  • ๅญไปฃ็†ไป…ๅ…่ฎธ AGENTS.md + TOOLS.md ่ฟ›ๅ…ฅไธŠไธ‹ๆ–‡
  • ่ถ…้•ฟๆ–‡ไปถๆŒ‰ head+tail ๆˆชๆ–ญๅนถๅŠ ๆ ‡่ฎฐ

ๆœฌ้กน็›ฎๅฎž็Žฐ (context/loader.ts)๏ผš

async buildContextPrompt(params?: { sessionKey?: string }): Promise<string> {
  const files = await this.loadBootstrapFiles(params);
  const contextFiles = buildBootstrapContextFiles(files, { maxChars: this.maxChars });
  // Project Context ่พ“ๅ‡บ๏ผˆๅซ SOUL.md ็‰นๆฎŠๆ็คบ๏ผ‰
}

3.1 Context Pruning/Compaction - ไธŠไธ‹ๆ–‡ๅŽ‹็ผฉ

OpenClaw ๆ–นๆกˆ๏ผš

  • src/agents/pi-extensions/context-pruning/*๏ผš่ฃๅ‰ชๅทฅๅ…ท็ป“ๆžœใ€ไฟ็•™ๆœ€่ฟ‘ไธŠไธ‹ๆ–‡
  • src/agents/compaction.ts๏ผš่ถ…้•ฟๅކๅฒๆ‘˜่ฆๅŽ‹็ผฉ

ๆœฌ้กน็›ฎๅฎž็Žฐ๏ผš

  • context/pruning.ts๏ผš่ฝฏ่ฃๅ‰ช tool_result + ไฟ็•™ๆœ€่ฟ‘ assistant
  • context/compaction.ts๏ผš่งฆๅ‘้˜ˆๅ€ผๅŽ็”Ÿๆˆโ€œๅކๅฒๆ‘˜่ฆโ€ๅนถๆณจๅ…ฅ

4. Skills Manager - ๅฏๆ‰ฉๅฑ•ๆŠ€่ƒฝ

้—ฎ้ข˜๏ผšๅฆ‚ไฝ•่ฎฉ็”จๆˆท่‡ชๅฎšไน‰ Agent ่ƒฝๅŠ›๏ผŸ

OpenClaw ๆ–นๆกˆ (src/agents/skills/types.ts)๏ผš

  • SKILL.md frontmatter ๅฎšไน‰ๅ…ƒๆ•ฐๆฎ
  • ๆ”ฏๆŒ่งฆๅ‘ๆกไปถใ€ๅฎ‰่ฃ…่„šๆœฌใ€ๅ‚ๆ•ฐๆ ก้ชŒ
  • ่ฟ่กŒๆ—ถๅŠจๆ€ๅŠ ่ฝฝ

ๆœฌ้กน็›ฎๅฎž็Žฐ (skills.ts:125-170)๏ผš

// SKILL.md ๆ ผๅผ
// ---
// id: deploy
// name: ้ƒจ็ฝฒๅŠฉๆ‰‹
// triggers: ["/deploy", "้ƒจ็ฝฒ"]
// ---
// Prompt ๅ†…ๅฎน...

async match(input: string): Promise<SkillMatch | null> {
  for (const skill of this.skills.values()) {
    for (const trigger of skill.triggers) {
      if (input.startsWith(trigger)) {
        return { skill, matchedTrigger: trigger };
      }
    }
  }
}

5. Heartbeat Manager - ไธปๅŠจๅ”ค้†’

้—ฎ้ข˜๏ผšAgent ๅฆ‚ไฝ•"ไธปๅŠจ"ๅทฅไฝœ๏ผŒ่€Œไธๅชๆ˜ฏ่ขซๅŠจๅ“ๅบ”๏ผŸ

OpenClaw ๆ–นๆกˆ (src/infra/heartbeat-runner.ts, src/infra/heartbeat-wake.ts)๏ผš

่ฟ™ๆ˜ฏๆœ€ๅคๆ‚็š„ๅญ็ณป็ปŸ๏ผŒๅŒ…ๅซไธคๅฑ‚ๆžถๆž„๏ผš

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     HeartbeatWake (่ฏทๆฑ‚ๅˆๅนถๅฑ‚)               โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                              โ”‚
โ”‚  ๅคšๆฅๆบ่งฆๅ‘:                                                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚ interval โ”‚  โ”‚   cron   โ”‚  โ”‚   exec   โ”‚  โ”‚ requestedโ”‚    โ”‚
โ”‚  โ”‚ (ๅฎšๆ—ถๅ™จ) โ”‚  โ”‚ (ไปปๅŠกๅฎŒๆˆ)โ”‚  โ”‚ (ๅ‘ฝไปคๅฎŒๆˆ)โ”‚  โ”‚ (ๆ‰‹ๅŠจ)   โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚       โ”‚             โ”‚             โ”‚             โ”‚           โ”‚
โ”‚       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚
โ”‚                            โ–ผ                                 โ”‚
โ”‚                    request({ reason })                       โ”‚
โ”‚                            โ”‚                                 โ”‚
โ”‚                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                        โ”‚
โ”‚                    โ”‚ ๅŽŸๅ› ไผ˜ๅ…ˆ็บงๅˆๅนถ โ”‚                        โ”‚
โ”‚                    โ”‚ exec > cron   โ”‚                        โ”‚
โ”‚                    โ”‚ > interval    โ”‚                        โ”‚
โ”‚                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                        โ”‚
โ”‚                            โ”‚                                 โ”‚
โ”‚                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                        โ”‚
โ”‚                    โ”‚ schedule(250ms)โ”‚ โ—„โ”€โ”€ ๅˆๅนถ็ช—ๅฃ          โ”‚
โ”‚                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                        โ”‚
โ”‚                            โ”‚                                 โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                  โ”‚
โ”‚              โ”‚ if running: โ”‚ else:       โ”‚                  โ”‚
โ”‚              โ”‚ scheduled=  โ”‚ setTimeout  โ”‚                  โ”‚
โ”‚              โ”‚ true (ๆŽ’้˜Ÿ) โ”‚ execute()   โ”‚                  โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                  โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                            โ”‚
                            โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                   HeartbeatRunner (่ฐƒๅบฆๅฑ‚)                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                              โ”‚
โ”‚  runOnce(request):                                          โ”‚
โ”‚                                                              โ”‚
โ”‚  1. isWithinActiveHours()  โ”€โ”€โ”€ ๆดป่ทƒๆ—ถ้—ด็ช—ๅฃๆฃ€ๆŸฅ             โ”‚
โ”‚     โ”‚                          (08:00-22:00, ๆ”ฏๆŒๆ—ถๅŒบ)      โ”‚
โ”‚     โ–ผ                                                        โ”‚
โ”‚  2. parseTasks()           โ”€โ”€โ”€ HEARTBEAT.md ่งฃๆž            โ”‚
โ”‚     โ”‚                                                        โ”‚
โ”‚     โ–ผ                                                        โ”‚
โ”‚  3. ็ฉบๅ†…ๅฎนๆฃ€ๆต‹             โ”€โ”€โ”€ ๆ— ไปปๅŠกๆ—ถ่ทณ่ฟ‡ API ่ฐƒ็”จ        โ”‚
โ”‚     โ”‚                          (exec ไบ‹ไปถ้™คๅค–)              โ”‚
โ”‚     โ–ผ                                                        โ”‚
โ”‚  4. ๆ‰ง่กŒๅ›ž่ฐƒ               โ”€โ”€โ”€ Agent ๅค„็†ไปปๅŠก               โ”‚
โ”‚     โ”‚                                                        โ”‚
โ”‚     โ–ผ                                                        โ”‚
โ”‚  5. isDuplicateMessage()   โ”€โ”€โ”€ 24h ๅ†…้‡ๅคๆถˆๆฏๆŠ‘ๅˆถ           โ”‚
โ”‚     โ”‚                                                        โ”‚
โ”‚     โ–ผ                                                        โ”‚
โ”‚  6. scheduleNext()         โ”€โ”€โ”€ setTimeout ็ฒพ็กฎ่ฐƒๅบฆ          โ”‚
โ”‚                                (lastRunAt + intervalMs)     โ”‚
โ”‚                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ๅ…ณ้”ฎ่ฎพ่ฎกๅ†ณ็ญ–๏ผš

่ฎพ่ฎก็‚น ไธบไป€ไนˆ่ฟ™ๆ ทๅš
setTimeout ่€Œ้ž setInterval ็ฒพ็กฎ่ฎก็ฎ—ไธ‹ๆฌก่ฟ่กŒๆ—ถ้—ด๏ผŒ้ฟๅ…ๆผ‚็งป
250ms ๅˆๅนถ็ช—ๅฃ ้˜ฒๆญขๅคšไธชไบ‹ไปถๅŒๆ—ถ่งฆๅ‘ๅฏผ่‡ด็š„"ๅ‘ผๅธๆ€ฅไฟƒ"
ๅŒ้‡็ผ“ๅ†ฒ ่ฟ่กŒไธญๆ”ถๅˆฐๆ–ฐ่ฏทๆฑ‚ไธไธขๅคฑ๏ผŒๅฎŒๆˆๅŽ็ซ‹ๅณๅค„็†
็ฉบๅ†…ๅฎนๆฃ€ๆต‹ ๆ— ไปปๅŠกๆ—ถ่ทณ่ฟ‡ LLM ่ฐƒ็”จ๏ผŒ่Š‚็œๆˆๆœฌ
้‡ๅคๆŠ‘ๅˆถ 24h ๅ†…็›ธๅŒๆถˆๆฏไธ้‡ๅคๅ‘้€๏ผŒ้˜ฒๆญข"็บ ็ผ "
ๆดป่ทƒๆ—ถ้—ด็ช—ๅฃ ้ฟๅ…ๅŠๅคœๆ‰“ๆ‰ฐ็”จๆˆท

ๆœฌ้กน็›ฎๅฎž็Žฐ (heartbeat.ts:147-160)๏ผš

private schedule(delayMs: number): void {
  // ๅฆ‚ๆžœๅทฒๅœจ่ฟ่กŒ๏ผŒๆ ‡่ฎฐไธบๅทฒๆŽ’้˜Ÿ๏ผˆๅŒ้‡็ผ“ๅ†ฒ๏ผ‰
  if (this.state.running) {
    this.state.scheduled = true;
    return;
  }
  // ๅฆ‚ๆžœๅทฒๆœ‰ๅฎšๆ—ถๅ™จ๏ผŒไธ้‡ๅค่ฎพ็ฝฎ๏ผˆๅˆๅนถ๏ผ‰
  if (this.state.timer) {
    return;
  }
  this.state.timer = setTimeout(() => this.execute(), delayMs);
}

ๆบ็ ๆ˜ ๅฐ„่กจ

ๆœฌ้กน็›ฎๆ–‡ไปถ OpenClaw ๅฏนๅบ”ๆ–‡ไปถ ่ฏดๆ˜Ž
agent.ts src/agents/pi-embedded-runner/run.ts Agent Loop + run ็”Ÿๅ‘ฝๅ‘จๆœŸ
session.ts src/agents/session-manager.ts JSONL ไผš่ฏๆŒไน…ๅŒ–
memory.ts src/memory/manager.ts ่ฎฐๅฟ†ๆฃ€็ดขๆ ธๅฟƒๆ€่ทฏ
context/loader.ts src/agents/bootstrap-files.ts Bootstrap ๆ–‡ไปถๅŠ ่ฝฝ
context/pruning.ts src/agents/pi-extensions/context-pruning/pruner.ts ไธŠไธ‹ๆ–‡่ฃๅ‰ช
context/compaction.ts src/agents/compaction.ts ๅކๅฒๆ‘˜่ฆๅŽ‹็ผฉ
skills.ts src/agents/skills/ ๆŠ€่ƒฝ็ณป็ปŸ
heartbeat.ts src/infra/heartbeat-runner.ts
src/infra/heartbeat-wake.ts
ไธปๅŠจๅ”ค้†’
tools/*.ts src/tools/ ๅ†…็ฝฎๅทฅๅ…ทๆ ทไพ‹

ๅฟซ้€Ÿๅผ€ๅง‹

# ่ฟ›ๅ…ฅ็›ฎๅฝ•
cd examples/openclaw-mini

# ๅฎ‰่ฃ…ไพ่ต–
pnpm install

# ่ฎพ็ฝฎ API Key
export ANTHROPIC_API_KEY=sk-xxx

# ๅฏ้€‰๏ผšๆŒ‡ๅฎš agentId
export OPENCLAW_MINI_AGENT_ID=main

# ๅฏๅŠจไบคไบ’ๅผๅฏน่ฏ
pnpm dev chat

ๅทฅไฝœๅŒบๆจกๆฟ๏ผˆๆฅ่‡ช OpenClaw ่ฎพ่ฎก๏ผ‰

ๆจกๆฟๆ”พๅœจ examples/openclaw-mini/workspace-templates/๏ผˆๅ†…ๅฎนๅ‚่€ƒ docs/reference/templates/ ็š„่ฎพ่ฎก๏ผ‰๏ผŒ่ฟ่กŒๆ—ถไผšไปŽๅฝ“ๅ‰ๅทฅไฝœๅŒบๆ น็›ฎๅฝ•่ฏปๅ–่ฟ™ไบ›ๆ–‡ไปถใ€‚
้œ€่ฆ็”Ÿๆ•ˆๆ—ถ๏ผŒๆŠŠๆจกๆฟๅคๅˆถๅˆฐๅทฅไฝœๅŒบๆ น็›ฎๅฝ•ๅณๅฏ๏ผš

cp examples/openclaw-mini/workspace-templates/* examples/openclaw-mini/

ไฝฟ็”จ็คบไพ‹

import { Agent } from "openclaw-mini";

const agent = new Agent({
  apiKey: process.env.ANTHROPIC_API_KEY,
  agentId: "main",
  workspaceDir: process.cwd(),
  enableMemory: true,     // ้•ฟๆœŸ่ฎฐๅฟ†
  enableContext: true,    // ไธŠไธ‹ๆ–‡ๅŠ ่ฝฝ
  enableSkills: true,     // ๆŠ€่ƒฝ็ณป็ปŸ
  enableHeartbeat: false, // ไธปๅŠจๅ”ค้†’๏ผˆ้ป˜่ฎคๅ…ณ้—ญ๏ผ‰
  // ๅทฅๅ…ท็ญ–็•ฅไธŽๆฒ™็ฎฑ๏ผˆ็คบๆ„๏ผ‰
  toolPolicy: { deny: ["exec"] },
  sandbox: { enabled: true, allowExec: false, allowWrite: true },
});

// ๅŸบๆœฌๅฏน่ฏ๏ผˆไผ ๅ…ฅ sessionId๏ผŒไผš่‡ชๅŠจ่กฅๅ…จไธบ sessionKey๏ผ‰
const result = await agent.run("session-1", "่ฏทๅˆ—ๅ‡บๅฝ“ๅ‰็›ฎๅฝ•็š„ๆ–‡ไปถ");

// ไฝฟ็”จๆŠ€่ƒฝ
const review = await agent.run("session-1", "/review src/agent.ts");

// ไนŸๅฏไปฅ็›ดๆŽฅไฝฟ็”จ sessionKey
const result2 = await agent.run("agent:main:session-1", "็ปง็ปญๅˆšๆ‰็š„ไปปๅŠก");

// ๅฏๅŠจไธปๅŠจๅ”ค้†’
agent.startHeartbeat((tasks, request) => {
  console.log(`[${request.reason}] ๆฃ€ๆต‹ๅˆฐ ${tasks.length} ไธชๅพ…ๅŠžไปปๅŠก`);
});

่ฎฐๅฟ†ไฝฟ็”จๆ็คบ๏ผšmini ็‰ˆๆ”นไธบโ€œๅทฅๅ…ทๅŒ–่ฎฐๅฟ†โ€๏ผŒๅœจ็ณป็ปŸๆ็คบไธญๅผ•ๅฏผๆจกๅž‹ๅ…ˆ่ฐƒ็”จ memory_search ๅ† memory_get ๆ‹‰ๅ–็ป†่Š‚ใ€‚

ๅญไปฃ็†๏ผšๅฏ้€š่ฟ‡ sessions_spawn ๅทฅๅ…ทๅฏๅŠจๅŽๅฐๅญไปฃ็†๏ผŒๅฎŒๆˆๅŽไผšๅœจ CLI ่พ“ๅ‡บๆ‘˜่ฆ๏ผŒๅนถๅ†™ๅ…ฅ็ˆถไผš่ฏ่ฎฐๅฝ•ใ€‚

ๅญฆไน ่ทฏๅพ„ๅปบ่ฎฎ

  1. ๅ…ˆ่ฏป agent.ts๏ผš็†่งฃ Agent Loop ๅ’Œๅญ็ณป็ปŸๆ•ดๅˆ
  2. ๅ†่ฏป heartbeat.ts๏ผš่ฟ™ๆ˜ฏๆœ€ๅคๆ‚็š„้ƒจๅˆ†๏ผŒ็†่งฃไบ‹ไปถ้ฉฑๅŠจๆžถๆž„
  3. ๅฏน็…ง OpenClaw ๆบ็ ๏ผš้ชŒ่ฏ็ฎ€ๅŒ–็‰ˆๆ˜ฏๅฆๆŠ“ไฝไบ†ๆ ธๅฟƒ
  4. ๅฐ่ฏ•ๆ‰ฉๅฑ•๏ผšๆทปๅŠ ๆ–ฐ็š„ๆŠ€่ƒฝใ€ๅทฅๅ…ทใ€ๆˆ–ๆ”น่ฟ›่ฎฐๅฟ†ๆฃ€็ดข

็ฒพๅŽ่ฎพ่ฎก็ดขๅผ•๏ผˆๅฟ…ๅญฆ 4 ็‚น๏ผ‰

  1. ไธŠไธ‹ๆ–‡็š„ๆ–‡ไปถๅŒ–็ป“ๆž„

    • OpenClaw๏ผšsrc/agents/workspace.ts๏ผˆbootstrap ๆ–‡ไปถๆธ…ๅ•๏ผ‰
    • Mini๏ผšopenclaw-mini/src/context/bootstrap.ts
  2. ็ปŸไธ€ๆณจๅ…ฅ้“พ่ทฏ๏ผˆProject Context๏ผ‰

    • OpenClaw๏ผšsrc/agents/system-prompt.ts
    • Mini๏ผšopenclaw-mini/src/context/loader.ts
  3. ่ง„ๆจกๆŽงๅˆถ๏ผˆๆˆชๆ–ญ + ่ฃๅ‰ช๏ผ‰

    • OpenClaw๏ผšsrc/agents/pi-embedded-helpers/bootstrap.ts + src/agents/pi-extensions/context-pruning/pruner.ts
    • Mini๏ผšopenclaw-mini/src/context/bootstrap.ts + openclaw-mini/src/context/pruning.ts
  4. ๅŽ‹็ผฉ็ปงๆ‰ฟ๏ผˆๆ‘˜่ฆ๏ผ‰

    • OpenClaw๏ผšsrc/agents/compaction.ts
    • Mini๏ผšopenclaw-mini/src/context/compaction.ts

License

MIT

About

๐Ÿฆž OpenClaw ๆ ธๅฟƒๆžถๆž„็š„ๆž็ฎ€ๅค็Žฐ๏ผŒๆถต็›– sessionKey ไผš่ฏๅŸŸใ€้˜Ÿๅˆ—ไธฒ่กŒใ€ๅทฅๅ…ทๅŒ–่ฎฐๅฟ†ๆฃ€็ดขใ€ๆŒ‰้œ€ไธŠไธ‹ๆ–‡ๅŠ ่ฝฝใ€ๅฏๆ‰ฉๅฑ•ๆŠ€่ƒฝไธŽไธปๅŠจๅฟƒ่ทณๅ”ค้†’ๆœบๅˆถ

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published