Prompt
Seshat does not treat the system prompt as one flat string glued together at random. The runtime builds a layered prompt with a stable core, a dynamic boundary, turn-specific runtime context, project instructions, memory, stage overlays, appended caller context, and provider-facing tool hints. This page documents that architecture and every important prompt-shaping parameter exposed to Go SDK developers.
Prompt Assembly Architecture
The prompt builder is intentionally layered so that stable identity and behavior rules remain cacheable while live session context stays dynamic. That is why Seshat can preserve a durable runtime contract without pretending the whole prompt is static across turns.
Identity, runtime contract, working rules, factual discipline, tool use, workflow, modes, orchestration, examples, and output discipline form the cacheable stable prefix.
The builder inserts a structural marker between stable and dynamic prompt layers. It changes prompt assembly behavior but is never rendered into the final text sent to the provider.
The builder injects live session metadata, tool surface, project instructions from the working directory, memory context, and any execution-stage overlay for the current turn.
Client-level and session-level overrides can replace the base persona or append durable and run-specific business context after the runtime-owned layers.
Tool hints do not rewrite the main system prompt. They are appended to provider-facing tool descriptions so tool choice behavior can change without mutating tool code.
The Pre-Existing Prompt Core
Before your application appends or overrides anything, Seshat already ships a substantial default prompt core. It covers identity, runtime contract, working rules, factual discipline, tool usage, workflow, orchestration, examples, and output discipline.
| Section | Priority | Layer | Purpose | Notes |
|---|---|---|---|---|
| identity | 1000 | stable | Defines the default Seshat role and baseline identity. | Part of the cacheable stable prefix. |
| runtime_contract | 975 | stable | Defines transcript correctness and recoverable runtime behavior. | Stable core behavior contract. |
| working_rules | 950 | stable | Covers read-before-write discipline and destructive-action caution. | One of the main guardrail sections. |
| factual_discipline | 940 | stable | Pushes verification over unsupported claims. | Important for high-risk or current facts. |
| tool_use | 900 | stable | Explains how the model should use the runtime tool surface. | Includes progress-tracking and ask-user guidance. |
| tool_priority | 899 | stable | Defines preferred tool ordering and information-gathering chain. | Includes MCP-vs-builtin preference rules. |
| workflow | 898 | stable | Defines the default mono-run workflow order. | Connects repo inspection, todo tracking, delegation, and completion rules. |
| modes | 897 | stable | Explains plan mode and sub-agent usage. | Part of the built-in orchestration behavior. |
| orchestration | 895 | stable | Gives deeper rules for delegation and sub-agent prompt writing. | Extends the multi-agent discipline. |
| workflow_examples | 890 | stable | Provides example execution patterns for direct work, planning, and delegation. | Stable example section in the shipped prompt. |
| verification_examples | 888 | stable | Shows when local evidence is enough versus when verification is required. | Strengthens the factual-discipline contract. |
| output_discipline | 875 | stable | Constrain final output style toward concise implementation-oriented responses. | Last stable section before the dynamic boundary. |
| dynamic_boundary | 850 | dynamic marker | Separates cacheable stable prompt text from turn-specific dynamic content. | Structural marker only; it is not rendered into the provider-facing prompt text. |
| runtime_context | 800 | dynamic | Injects session id, turn number, working directory, model, provider, and visible tools. | Changes every turn and is never part of the stable cacheable prefix. |
| runtime_guidance | 780 | dynamic | Explains how to interpret the live runtime context and tool surface. | Built dynamically by the prompt builder. |
| project_instructions | 775 | dynamic | Injects project-level instructions discovered from the working directory. | Checks SESHAT.md, AGENTS.md, then .seshat/instructions.md, capped at 32 KB. |
| stage_overlay | 770 | dynamic | Adds stage-specific instructions such as plan mode or continuation. | Can be replaced with StageOverrides. |
| runtime_memory | 760 | dynamic | Injects memory context when the runtime memory system is active. | Absent when memory is disabled or no context exists. |
| append_system_prompt | after assembly | dynamic append | Adds caller-supplied appended instructions after all runtime-built sections. | Comes from PromptConfig.AppendSystemPrompt or Session.SetAppendSystemPrompt. |
Prompt Parameters And Overrides
These are the practical Go SDK surfaces that shape the prompt. The table deliberately mixes client-level config with session methods because both matter when you design embedded agent behavior.
| API surface | Scope | Purpose | Runtime effect | Notes |
|---|---|---|---|---|
| ClientConfig.SystemPromptTemplate | client | Provides a base system prompt template for the client. | Replaces the default Seshat stable identity while keeping runtime-owned dynamic context. | Best when you want one durable persona per client. |
| PromptConfig.SystemPrompt | client | Performs the strongest prompt override. | Replaces the core stable prompt contract and skips the normal stable core sections. | Use deliberately; you now own more of the behavior contract yourself. |
| PromptConfig.AppendSystemPrompt | client | Appends stable business or product context after runtime-built sections. | Adds domain context every turn without replacing the base persona. | Often the safest customization path. |
| PromptConfig.Stage | client | Pins the prompt into a specific execution-stage overlay. | Injects the selected stage behavior into the dynamic prompt section. | Useful for forcing plan mode from the host side. |
| PromptConfig.StageOverrides | client | Replaces built-in overlay text for one or more stages. | Lets the host keep runtime stages but rewrite their instructions. | Good for custom planning or continuation discipline. |
| PromptConfig.ToolHints | client | Adds extra guidance to chosen provider-facing tool descriptions. | Changes tool selection behavior without editing tool definitions. | Hints are applied per canonical tool name. |
| Session.SetSystemPromptTemplate | session | Overrides the client-level base prompt for one run. | Creates a session-specific persona while keeping the same runtime stack. | Empty string clears the override. |
| Session.SetAppendSystemPrompt | session | Adds run-specific appended context. | Useful for one release window, tenant context, or assignment-specific rules. | Empty string clears the override. |
| Session.SetWorkingDirectory | session | Changes the working directory used in runtime prompt context. | Also changes where project instructions are discovered from. | Project instructions lookup checks SESHAT.md, AGENTS.md, and .seshat/instructions.md in that root. |
| PromptFn | client | Bridges runtime-to-user prompts such as approvals or questions. | Does not customize the system prompt itself. | Important to document because developers often confuse it with prompt shaping. |
Structured Prompt Customization
In most products, PromptConfig is the right first tool. It is strong enough to add durable business context, tool-use bias, and custom stage overlays without forcing a full replacement of the shipped runtime contract.
func ptr(value string) *string { return &value }
client, err := sdk.NewClient(&sdk.ClientConfig{
Model: sdk.ModelIdentifier{
Provider: sdk.APIProviderAnthropic,
Model: "claude-sonnet-4-20250514",
},
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
PromptConfig: &sdk.PromptConfig{
AppendSystemPrompt: ptr(`Business context:
- Reliability beats speed.
- Migrations must be backward compatible.`),
ToolHints: map[string]string{
"bash": "Prefer inspection commands before mutating commands.",
"apply_patch": "Keep edits minimal and reviewable.",
},
StageOverrides: map[sdk.ExecutionStage]string{
sdk.StagePlan: `# Stage: plan mode
Tool execution is suspended.
- Produce a concise numbered plan.
- Mention risks and validation steps.
- Do not execute tools.`,
},
},
})Full Override Versus Safe Extension
A full override exists because some host applications genuinely need it, but it should not be your default instinct. Extending the prompt is usually safer than replacing the whole stable contract.
func ptr(value string) *string { return &value }
client, err := sdk.NewClient(&sdk.ClientConfig{
Model: sdk.ModelIdentifier{
Provider: sdk.APIProviderAnthropic,
Model: "claude-sonnet-4-20250514",
},
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
PromptConfig: &sdk.PromptConfig{
SystemPrompt: ptr(`You are the internal release-audit runtime.
Rules:
- Be conservative.
- Audit for regressions and rollback risk.
- Return blockers before suggestions.`),
},
})Use AppendSystemPrompt when you only need extra business or domain context.
Use ToolHints when the issue is tool-choice behavior rather than the full persona.
Use SystemPrompt only when you intentionally want to own more of the core behavior contract.
Session-Level Prompt Context
Session overrides are the right layer for context that should not affect every future run. Release windows, tenant details, one-off compliance instructions, or temporary operational context belong here.
session, err := client.CreateSession(ctx)
if err != nil {
log.Fatal(err)
}
defer session.Close()
session.SetAppendSystemPrompt(`Release context:
- branch: release/2026.06
- freeze: active
- production incidents: 0 open`)
_, err = session.SubmitMessage(ctx, "Inspect the auth service for release blockers.")Execution Stages
Stages are not generic labels. They are real overlays injected into the dynamic prompt layer. You can let the loop infer them when appropriate, or you can pin the stage explicitly from the host side.
client, err := sdk.NewClient(&sdk.ClientConfig{
Model: sdk.ModelIdentifier{
Provider: sdk.APIProviderAnthropic,
Model: "claude-sonnet-4-20250514",
},
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
PromptConfig: &sdk.PromptConfig{
Stage: sdk.StagePlan,
},
})| Stage constant | Value | Typical use | Effect |
|---|---|---|---|
| StageDefault | "" | Normal operation with no forced overlay. | No extra stage section is injected unless the loop auto-detects a stage such as tool-result handling. |
| StageToolCall | tool_call | Manual loop wiring when the model is expected to dispatch tools. | Adds guidance telling the model to proceed with necessary tool calls without duplication. |
| StageToolResult | tool_result | Manual or advanced loop control when tool results are being reintegrated. | Tells the model to integrate results into a direct useful response. |
| StageContinuation | continuation | Resume an unfinished response cleanly. | Adds a continuation nudge that tells the model to resume directly instead of recapping. |
| StagePlan | plan | Host-enforced planning mode or custom plan-mode products. | Suspends tool execution expectations and asks for a numbered plan instead. |
Project Instructions And Working Directory
The prompt builder also pulls project-level instructions from the active working directory. It checks SESHAT.md, then AGENTS.md, then .seshat/instructions.md, taking the first non-empty file and truncating at 32 KB if needed. This is why working-directory control is part of prompt architecture, not just file-tool setup.
What To Use When
- Use SystemPromptTemplate for a durable client-level persona.
- Use AppendSystemPrompt for stable domain or business context.
- Use ToolHints to nudge tool behavior without rewriting the persona.
- Use StageOverrides when the built-in plan or continuation wording is not right for your product.
- Use session overrides for one run, one tenant, one release, or one mission.
- Use a full override only when you intentionally want to replace the shipped stable contract.
Related Pages
Continue with Agent for persona and role patterns, Tools & Surface for the action layer, or Mono-Run Architecture for the runtime-side view behind this prompt assembly.