Instructions & Templating¶
Hector provides a powerful system for defining agent behavior through instructions (system prompts). This system supports dynamic content injection, scoped state access, and file embedding, allowing agents to adapt their behavior based on runtime context.
Configuration¶
Basic Instruction¶
The most common way to define an agent's behavior is the instruction field in the agent configuration.
agents:
researcher:
name: "Web Researcher"
instruction: "You are a detailed-oriented web researcher. Always cite your sources."
Global Instruction¶
You can define a global_instruction on the root agent (or any agent acting as a root for sub-agents). This instruction is prepended to the agent's specific instruction, making it ideal for shared guidelines, voice, or safety rules.
agents:
root:
global_instruction: "Responses must be in valid JSON format."
agents:
child1:
instruction: "Analyze this data."
Prompt Configuration¶
For more granular control, use the prompt configuration object. This allows you to separate the core role from specific guidance or override the system prompt entirely.
agents:
analyst:
prompt:
role: "Senior Data Analyst"
guidance: "Focus on trends and outliers. Be concise."
# system_prompt: "..." # (Optional) Completely overrides 'instruction'
Effectively, the final system prompt is constructed as: Global Instruction + Role + Instruction + Guidance.
SKILL.md (Skill-based Configuration)¶
For a simpler, file-based approach to defining a single agent's behavior, Hector supports SKILL.md. This follows the Agent Skills specification for portable skill definitions. If this file is present in your working directory, Hector will automatically use it to configure the default agent.
Structure¶
SKILL.md consists of a YAML frontmatter block for configuration and a markdown body for the instruction.
---
name: Data Analyst
description: Analyzes CSV files
allowed-tools: Read Edit Bash(git:*)
---
You are an expert data analyst.
Always visualize your findings.
Frontmatter Reference¶
| Field | Description | Example |
|---|---|---|
name |
Agent name (display name) | Data Analyst |
description |
Brief description of the agent's purpose | Analyzes data |
allowed-tools |
Space-delimited tool hints (see below) | Read Edit Bash(git:*) |
allowed-tools Mapping¶
Hector maps Agent Skills tool names to built-in tools:
| Agent Skills Name | Hector Tool | Notes |
|---|---|---|
Read, Edit, Write, Editor |
text_editor |
All map to unified file tool |
Bash, Bash(*), Bash(git:*) |
bash |
Wildcard patterns are hints only |
Grep |
grep_search |
(planned) |
[!NOTE] The Agent Skills spec's
allowed-toolsfield is marked as experimental. Hector treats these as tool selection hints, not granular permission restrictions. For fine-grained control (e.g., restrictingtext_editorto view-only, orbashto specific commands), use fullhector.yamlconfiguration withallowed_commandsandrequire_approval.
Integration¶
When hector serve initializes:
1. It detects SKILL.md.
2. It parses the frontmatter to set the agent's name, description, and allowed tools.
3. It uses the markdown body as the agent's instruction.
4. It generates/updates .hector/config.yaml to reflect these settings.
Dynamic Templating¶
Static text is often insufficient. Hector's instruction system allows you to inject dynamic values using placeholder syntax {...}. These placeholders are resolved at runtime just before the agent executes.
Syntax Reference¶
| Placeholder | Scope | Description | Example |
|---|---|---|---|
{variable} |
Session | Value from the current session state. | Hello {user_name} |
{app:variable} |
App | Value from global application state. | {app:environment} |
{user:variable} |
User | Value from user-specific state. | {user:preferences} |
{temp:variable} |
Temp | Value from temporary (ephemeral) state. | {temp:current_job} |
{artifact.file} |
Artifact | Text content of a file in the artifact system. | {artifact.code.go} |
{var?} |
Optional | Returns empty string if missing (no error). | Context: {extra_context?} |
Examples¶
1. Personalization:
instruction: "You are helpful assistant for {user_name}. Current project: {app:project_name}."
2. Injecting Code/Docs:
If you have a file named api_spec.json loaded into the artifact system (e.g., via the text_editor tool or initial context), you can inject it directly:
instruction: |
You are an API expert.
Here is the API specification you must follow:
```json
{artifact.api_spec.json}
```
3. Conditional Context:
Use the ? suffix to handle optional values gracefully without causing errors if the key is missing.
instruction: |
Analyze the following data.
{additional_context?}
Programmatic Control¶
For advanced use cases where YAML templating is not enough, you can generate instructions programmatically using Go. This is done by implementing an InstructionProvider.
InstructionProvider¶
The InstructionProvider is a function that receives the full read-only context of the agent and returns a string.
type InstructionProvider func(ctx agent.ReadonlyContext) (string, error)
Usage:
import (
"github.com/verikod/hector/pkg/agent"
"github.com/verikod/hector/pkg/agent/llmagent"
)
func main() {
myAgent, _ := llmagent.New(llmagent.Config{
Name: "dynamic-agent",
Model: myModel,
// Dynamic instruction generation
InstructionProvider: func(ctx agent.ReadonlyContext) (string, error) {
// Access state
state := ctx.ReadonlyState()
mode, _ := state.Get("mode")
if mode == "expert" {
return "You are an expert scientist. Use technical jargon.", nil
}
return "You are a helpful teacher. Explain simply.", nil
},
})
// ...
}
Precedence¶
When an InstructionProvider is set, it takes precedence over the static Instruction field in the configuration. However, GlobalInstruction is still applied if defined.
GlobalInstructionProvider¶
Similar to InstructionProvider, you can dynamically generate global instructions:
myAgent, _ := llmagent.New(llmagent.Config{
Name: "dynamic-agent",
Model: myModel,
GlobalInstructionProvider: func(ctx agent.ReadonlyContext) (string, error) {
// Dynamic global instructions for all sub-agents
return "All responses must be under 500 words.", nil
},
InstructionProvider: func(ctx agent.ReadonlyContext) (string, error) {
return "You are a helpful assistant.", nil
},
})