Skip to main content
The model-family harness picks a small system-prompt fragment and the preferred file-edit tool that suit the model you’re using — set no config to keep today’s behaviour, or opt in by naming a supported model.
The agent sets llm="claude-opus-4"; the harness resolves the anthropic profile and shapes both the system prompt and the coding toolset automatically.
Unknown or non-string model ids resolve to the default profile — the system prompt and toolset order stay byte-for-byte identical to earlier versions. Adopting the harness requires no config change.

Quick Start

1

Zero config (default profile — behaviour unchanged)

2

Opt in — Anthropic family

On this agent, apply_patch is advertised before edit_file, and the system prompt gains: “When editing files, prefer patch-style edits: use apply_patch to create or rewrite files and edit_file for targeted changes.”
3

Opt in — OpenAI family

Here edit_file is advertised first, with a matching prompt fragment.
4

Inspect the resolved profile

5

Register a custom family profile

6

Override on a single agent


How It Works

The agent resolves a profile from the model id at prompt-build time, then prepends the fragment and reorders the edit tools.

Which override do I need?

Precedence

Resolution follows a fixed order, from most specific to the behaviour-preserving fallback:
Agent.harness_base_prompt (explicit override) > register_profile(...) (user-registered, most recent wins) > built-in matchers (anthropic, openai) > DEFAULT_PROFILE

Configuration Options

Import the harness API from the top level (all lazy — no import-time cost):
Or from the submodule for the full surface:

HarnessProfile fields

Built-in registry

First match wins; matching is case-insensitive substring on the model id.

Functions

Toolset helpers for advanced users composing custom coding toolsets:

Common Patterns

Pass the model id and the resolver does the rest — no extra configuration required.
  • All-Claude team — do nothing; naming a claude-… model activates the profile automatically.
  • Mixed models via a router — leave llm unset per agent and pass the model id per call. The resolver reads self.llm at prompt build-time, so a mid-run model swap picks up the new profile each turn.
  • Local Ollama model treated like Claude — register a profile at startup:
  • Team on Llama or Mistral — register once at startup so every downstream agent gets the family hint:
  • Strip the auto fragment on one agent — set agent.harness_base_prompt = "".

Add a house-style opener for every model

Register a profile whose matcher hits every model id the agent may see:

YAML usage

Nothing new to configure — the harness reads the llm field on the agent block, so YAML paths get the improvement automatically:

CLI usage

No new flag — praisonai run picks up the profile from the model id:

End-to-end examples


User Interaction Flow

A user creates an Agent(llm="claude-opus-4", toolsets=["coding"]) and types "Refactor src/user.py". The harness resolver sees "claude-opus-4", picks the anthropic profile, prepends the patch-first guidance to the agent’s system prompt, and advertises apply_patch before edit_file in the coding toolset. The agent reaches for apply_patch first — no config touched. The same user later switches to llm="gpt-4o". Same code, same toolset — the resolver now picks the openai profile, and the agent reaches for edit_file first. Still no config touched.

Best Practices

The default profile is byte-for-byte identical to pre-harness behaviour — verified by test_coding_toolset_unknown_model_is_byte_for_byte. Recognised families gain tuned guidance automatically; everything else stays the same.
The registry is process-global. Call register_profile once during application startup — registering inside request handlers repeatedly prepends duplicate mappings.
Matchers are case-insensitive substring hits against the model id, first match wins. Keep them short and stable — "claude", "gpt" — so new model versions in the same family match without edits. Registrations prepend, so a custom mapping overrides the built-in defaults.
Both edit primitives remain available; the model can still call the non-preferred one. Ordering is a hint, not a constraint.
Object-based LLMs resolve to the default profile by design, so custom LLM wrappers don’t silently pick up an unrelated family’s guidance. Pass a string llm= model id to opt in.

Backward compatibility: Default behaviour is unchanged. Agents that don’t set a supported llm string, don’t set toolsets, or use a non-string LLM object continue producing byte-for-byte identical system prompts and tool orderings.

Toolsets

The coding toolset whose edit-primitive order the harness reorders.

File Editing

The edit_file and apply_patch primitives themselves

Rules

The other lever that shapes the assembled system prompt

Prompt Cache Optimization

The fragment is prepended, so it participates in cache-key ordering

Models

The model id you pass is the trigger for profile resolution.