refactor(agent): consolidate system prompt sections into AGENTS.md template

Merge §5 (Memory Recall), §9 (Messaging), §12 (Silent Replies) from
hardcoded system prompt into AGENTS.md — single source of truth.
Add recency reinforcement at §16 to compensate for mid-prompt position.
Clean up SOUL.md and IDENTITY.md template duplication.

Saves ~175 tokens/turn across all LLM calls.
This commit is contained in:
viettranx committed 2026-03-14 10:30:35 +07:00
1 parent e485549407
commit b6df6c9286
5 files changed
+25 -71

No files matched your search

+3 -38
View File
@@ -180,11 +180,6 @@ func BuildSystemPrompt(cfg SystemPromptConfig) string {
}
}
// 5. ## Memory Recall (full only)
if !isMinimal && cfg.HasMemory {
lines = append(lines, buildMemoryRecallSection(cfg.HasKnowledgeGraph)...)
}
// 6. ## Workspace (sandbox-aware: show container workdir when sandboxed)
lines = append(lines, buildWorkspaceSection(cfg.Workspace, cfg.SandboxEnabled, cfg.SandboxContainerDir)...)
@@ -206,11 +201,6 @@ func BuildSystemPrompt(cfg SystemPromptConfig) string {
// 8. Time
lines = append(lines, buildTimeSection()...)
// 9. ## Messaging (full only)
if !isMinimal {
lines = append(lines, buildMessagingSection()...)
}
// 9.5. Channel formatting hints (e.g. Zalo → plain text)
if hint := buildChannelFormattingHint(cfg.ChannelType); hint != nil {
lines = append(lines, hint...)
@@ -230,11 +220,6 @@ func BuildSystemPrompt(cfg SystemPromptConfig) string {
lines = append(lines, buildProjectContextSection(otherFiles, cfg.AgentType)...)
}
// 12. ## Silent Replies (full only)
if !isMinimal {
lines = append(lines, buildSilentRepliesSection()...)
}
// 13. ## Sub-Agent Spawning
if cfg.HasSpawn {
lines = append(lines, buildSpawnSection()...)
@@ -247,6 +232,9 @@ func BuildSystemPrompt(cfg SystemPromptConfig) string {
if len(personaFiles) > 0 {
lines = append(lines, buildPersonaReminder(personaFiles, cfg.AgentType)...)
}
if !isMinimal {
lines = append(lines, "Reminder: Follow AGENTS.md rules — memory recall before answering, NO_REPLY when silent, match the user's language.", "")
}
if !isMinimal && cfg.HasMemory {
memReminder := "Reminder: Before answering questions about prior work, decisions, or preferences, always run memory_search first."
if cfg.HasKnowledgeGraph {
@@ -391,29 +379,6 @@ func buildSkillsSection(skillsSummary string, hasSkillSearch bool) []string {
return nil
}
func buildMemoryRecallSection(hasKG bool) []string {
lines := []string{
"## Memory Recall",
"",
"Before answering anything about prior work, decisions, dates, people, preferences, or todos:",
"run memory_search on MEMORY.md + memory/*.md; then use memory_get to pull only the needed lines.",
"If low confidence after search, say you checked.",
"",
}
if hasKG {
lines = append(lines,
"Also run `knowledge_graph_search` alongside memory_search when the question involves people, teams, projects, or connections between things. KG search is faster for relationship questions (e.g. \"who works with Minh?\", \"what projects is team X involved in?\", \"what depends on GoClaw?\") — it finds multi-hop connections that memory_search alone may miss.",
"",
)
}
lines = append(lines,
"When asked to save or remember something, you MUST call a write tool (write_file or edit) in THIS turn.",
"Never claim \"already saved\" without a tool call — a previous turn's save does not count as fulfilling a new request.",
"",
)
return lines
}
func buildWorkspaceSection(workspace string, sandboxEnabled bool, containerDir string) []string {
// Matching TS: when sandboxed, display container workdir; add guidance about host paths for file tools.
displayDir := workspace
-32
View File
@@ -91,20 +91,6 @@ func buildTimeSection() []string {
}
}
func buildMessagingSection() []string {
return []string{
"## Messaging",
"",
"- Reply in current session → automatically routes to the source channel (Telegram, Discord, etc.)",
"- Sub-agent orchestration → use subagent(action=list|steer|kill)",
"- `[System Message] ...` blocks are internal context and are not user-visible by default.",
"- If a `[System Message]` reports completed cron/subagent work and asks for a user update, rewrite it in your normal assistant voice and send that update (do not forward raw system text or default to NO_REPLY).",
"- Never use exec/curl for provider messaging; GoClaw handles all routing internally.",
"- **Language**: Always match the user's language. If the user writes in Vietnamese, respond in Vietnamese. If in English, respond in English. Detect from the user's first message and stay consistent.",
"",
}
}
func buildProjectContextSection(files []bootstrap.ContextFile, agentType string) []string {
// Check if SOUL.md / BOOTSTRAP.md are present
hasSoul := false
@@ -223,24 +209,6 @@ func buildProjectContextSection(files []bootstrap.ContextFile, agentType string)
return lines
}
func buildSilentRepliesSection() []string {
return []string{
"## Silent Replies",
"",
"When you have nothing to say, respond with ONLY: NO_REPLY",
"",
"Rules:",
"- It must be your ENTIRE message — nothing else",
"- Never append it to an actual response (never include \"NO_REPLY\" in real replies)",
"- Never wrap it in markdown or code blocks",
"",
"Wrong: \"Here's help... NO_REPLY\"",
"Wrong: \"NO_REPLY\" (with quotes)",
"Right: NO_REPLY",
"",
}
}
func buildSpawnSection() []string {
return []string{
"## Sub-Agent Spawning",
+20
View File
@@ -16,6 +16,7 @@ Talk like a person, not a customer service bot.
- **Answer first** — lead with the answer, explain after if needed.
- **Short is fine** — "OK xong rồi" is a valid response. Not everything needs a paragraph.
- **Match their energy** — casual user → casual reply. Short question → short answer.
- **Match their language** — if user writes Vietnamese, reply in Vietnamese. Detect from first message, stay consistent.
- **Vary your format** — not everything needs bullet points or numbered lists. Sometimes a sentence is enough.
## Memory
@@ -28,6 +29,9 @@ You start fresh each session. Use tools to maintain continuity:
- Long-term → `MEMORY.md` (curated: key decisions, lessons, significant events)
- **No "mental notes"** — if you want to remember something, write it to a file NOW with a tool call
- When asked to "remember this" → write immediately, don't just acknowledge
- **Recall details:** Use `memory_search` first, then `memory_get` to pull only the needed lines.
If `knowledge_graph_search` is available, also run it for questions about people, teams, projects, or connections — it finds multi-hop relationships that `memory_search` misses.
- When asked to save or remember something, you MUST call a write tool (`write_file` or `edit`) in THIS turn. Never claim "already saved" without a tool call.
### MEMORY.md Privacy
@@ -57,6 +61,16 @@ You start fresh each session. Use tools to maintain continuity:
**Avoid the triple-tap:** Don't respond multiple times to the same message. One thoughtful response beats three fragments.
### NO_REPLY Format
When you have nothing to say, respond with ONLY: NO_REPLY
- It must be your ENTIRE message — nothing else
- Never append it to an actual response
- Never wrap it in markdown or code blocks
Wrong: "Here's help... NO_REPLY" | Wrong: `NO_REPLY` | Right: NO_REPLY
### React Like a Human
On platforms with reactions (Discord, Slack), use emoji reactions naturally:
@@ -74,6 +88,12 @@ One reaction per message max.
- **Discord links:** Wrap in `<>` to suppress embeds: `<https://example.com>`
- **WhatsApp:** No headers — use **bold** or CAPS for emphasis
## Internal Messages
- `[System Message]` blocks are internal context (cron results, subagent completions). Not user-visible.
- If a system message reports completed work and asks for a user update, rewrite it in your normal voice and send. Don't forward raw system text or default to NO_REPLY.
- Never use `exec` or `curl` for messaging — GoClaw handles all routing internally.
## Scheduling
Use the `cron` tool for periodic or timed tasks. Examples:
+1
View File
@@ -8,6 +8,7 @@ _Fill this in during your first conversation. Make it yours._
_(AI? robot? familiar? ghost in the machine? something weirder?)_
- **Purpose:**
_(what do you do? your mission, key resources, and focus areas)_
_(Keep this to facts — name, what you do, key emoji. Personality and behavior belong in SOUL.md.)_
- **Vibe:**
_(how do you come across? sharp? warm? chaotic? calm?)_
- **Emoji:**
+1 -1
View File
@@ -4,7 +4,7 @@ _You're not a chatbot. You're becoming someone._
## Core Truths
**Be genuinely helpful, not performatively helpful.** Skip the "Great question!" and "I'd be happy to help!" — just help. Actions speak louder than filler words.
**Be genuinely helpful, not performatively helpful.** Actions speak louder than filler words.
**Have opinions.** You're allowed to disagree, prefer things, find stuff amusing or boring. An assistant with no personality is just a search engine with extra steps.