Learn Hermes AI Agent - Prompt Engineering & System Design
Episode 5 of 23

Learn Hermes AI Agent - Prompt Engineering & System Design

Assembling the agent's brain: system prompts, task instructions, and consistent response formatting; using prompt templates and dynamic prompt generation; plus handling edge cases and failure modes so the prompt stays reliable in every situation.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 4 you gave your agent an identity: persona, goals, capability, and toolset inside a profile. But identity alone is not enough — the quality of an agent's answers is largely determined by how well the prompt is structured. This episode teaches how to write prompts that make the agent consistent, easy to control, and not prone to "wandering off" on unusual input.

Here is the roadmap for this episode: structuring the system prompt, task instructions, and response formatting; using prompt templates and dynamic prompt generation; and then handling edge cases and failure modes in prompt design.

Structuring a Strong System Prompt

The system prompt is the fixed instruction loaded at the start of every conversation. It defines the role, context, and ground rules that apply to all turns. A good system prompt has four layers: role, context, task, and constraints.

system-prompt.txt - four layers
[Peran] Kamu adalah research assistant di tim produk.
[Konteks] Perusahaan menjual software checkout SaaS.
[Tugas] Bantu user meriset kompetitor dan menyusun ringkasan.
[Batasan] Gunakan bahasa Indonesia. Jangan menyebutkan
nama user. Kutip sumber setiap klaim faktual.

These four layers make it easy for the agent to separate "who I am" from "what I must do". Constraints are placed explicitly at the end so they are easy to spot and do not sink into the middle of a long narrative.

Avoid writing system prompts that are too long or too emotional. Sentences like "you MUST always obey" actually make the model drop its focus. Write positive, specific commands: replace "do not ramble" with "answer in at most 3 sentences".

Task Instructions and Response Formatting

If the system prompt answers "who are you and what are your rules", the task instruction answers "what specific job must be done right now". Distinguish them clearly — the system prompt stays fixed, while task instructions can change per invocation.

Response formatting forces the output into a specific structure so it is easy to parse programmatically. The most common is JSON.

response-format.json
{
  "summary": "ringkasan dalam 2 kalimat",
  "competitors": [
    { "name": "Pesaing A", "strengths": ["..."], "risks": ["..."] }
  ],
  "confidence": 0.9
}

To produce valid JSON, ask the model to use a JSON schema in the task instruction and set response_format to JSON mode if the provider supports it. Hermes can then parse the result safely without relying on fragile text parsing — for example through the parseJson helper.

When JSON is not needed, use XML tags to mark answer segments — for example, source citations in a <sumber> tag. XML is more tolerant of models that slip text around the core answer than JSON is.

Info

Always decide the response formatting before writing the prompt. A rigid format prevents the agent from adding filler that would force you to write a parser for every possible shape of answer.

Prompt Templates

Prompts are rarely written raw each time. Templates separate structure from data: the structure stays fixed, the data is injected per invocation.

templates/summarize.prompt
Rangkum dokumen berikut dalam {max_sentences} kalimat.
Fokus pada keputusan dan tindakan yang perlu diambil.
 
Dokumen:
---
{document_content}
---

Here there are two slots: max_sentences and document_content. The slots are replaced at render time. This template lives in the templates/ folder and is version-controlled together with the agent profile — anyone can read the template contents and know exactly what is sent to the model, without running the agent first.

Avoid putting logic inside templates. A template contains only text and slots; the choice logic (which slots to fill, when to use which template) belongs in code, not in the template string.

Dynamic Prompt Generation

Dynamic prompt generation is the process of assembling the final prompt at runtime: read the template, pull data from a tool or memory, and render it into a complete prompt before calling the model.

prompt-service.ts
import { render } from "@hermes/prompt";
 
export async function buildSummaryPrompt(session) {
  const doc = await session.tool("kb.read").call({ id: session.documentId });
  return render("templates/summarize.prompt", {
    max_sentences: 3,
    document_content: doc.content,
  });
}

This function combines three sources you already know from episode 4 and episode 8: the template as structure, tool data as content, and the session as context. The render function fills the template slots with values from a map. Slot values always come from trusted data — not raw user input — so prompt injection from document content does not automatically become an instruction.

Danger

A document read by a tool is data, not a command. When injecting external content into a prompt, wrap it in a clearly marked data block and maintain the constraint that the agent may only follow the instruction section.

Edge Cases and Failure Modes

A good prompt must work not only on ideal input, but also on broken input. Some of the most common failure modes:

  • Empty or too-short input — the agent guesses the user's intent. Mitigation: detect the input length and ask for clarification with a single short question.
  • Too-long input — the document exceeds the prompt window. Mitigation: truncate or summarize the document first (see prompt window management in episode 9), then render the template.
  • The tool returns no data — an empty result or an error. Mitigation: instruct the agent to answer that the data is unavailable, not to make it up.
  • The model follows fake instructions from content — prompt injection from an external document. Mitigation: strict separation between data blocks and instructions, as in the example above.
  • Output does not match the format — the model replies with prose when JSON was requested. Mitigation: validate the result, ask for a single re-render with an error message, or fall back to a safe default answer template.
fallback.ts
const parsed = parseJson(raw);
if (!parsed) {
  const retry = await model.call(
    "Output kamu tidak valid JSON. Ulangi dengan format yang diminta."
  );
  return parseJson(retry) ?? fallbackSummary;
}

The validate-then-retry pattern above is the basic pattern that will later grow into retry with backoff in episode 10. The principle: do not let a single format failure stop the whole workflow — always have a safe fallback answer ready.

Conclusion

Prompt engineering is the bridge between the agent's identity (episode 4) and how it works day to day. With a layered system prompt, specific task instructions, rigid response formatting, templates separated from data, and dynamic prompt generation that assembles everything at runtime, your agent becomes far more consistent and predictable.

Key takeaways:

  • The system prompt uses four layers: role, context, task, and constraints.
  • Task instructions differ from the system prompt; response formatting is decided before writing the prompt.
  • Templates separate structure from data and are version-controlled together with the profile.
  • Dynamic prompt generation assembles a prompt from templates, tool data, and session at runtime.
  • Failure modes are handled with validation, retry, and fallback answers — not by hoping the model is always right.

In episode 6 we activate the agent's hands: Tooling & External Integrations — connecting LLM providers, integrating web search, database, API fetch, and file system tools, plus safety on every tool call. See you there!

Learn Hermes AI Agent - Prompt Engineering & System Design | Learn Hermes AI Agent