Skip to content

Support instruction files an agent works from (skills) #2

Description

@arjunvlama

An objective is one paragraph. Real work needs more: a refund policy, an escalation
matrix, worked examples, "how we word things." Today the only place to put that is
the objective string, which stops being editable prose somewhere around thirty
lines.

Shape

Markdown files composed into the agent's system prompt, declared in the versioned
config:

name: refund-triage
version: 1

objective: |
  Resolve the refund request on ticket {{ inputs.ticket_id }}.

instructions:
  - refund-policy.md
  - escalation.md

Charter reads them at prompt-assembly time and appends them under labelled
sections, the same way add_context already stages history and memory.

Why static composition rather than a skills tool

Claude's SKILL.md model loads on demand — the agent decides what it needs and
reads it. That's the right design when there are hundreds of skills and a human is
steering. Charter's case is different, and on-demand loading has a specific problem
here: reading a file is a tool call, so it lands in the tool list, consumes
max_llm_calls, and needs governing. We already have a name for "the agent fetches
knowledge at runtime" — that's an MCP server, and the config for it exists.

So the split matches the one we drew for memory:

  • instructions: — what this agent always needs to know. Static, versioned,
    composed into the prompt. Charter's job.
  • an MCP server — a corpus too large to inline, fetched on demand. Not
    Charter's job.

The hard part: immutability

Version files are immutable, and that's what makes set_version: 1 mean anything —
a rollback restores an agent that still exists on disk. Instruction files break
that: edit refund-policy.md without bumping the version and the rolled-back agent
behaves differently from the one that was rolled back to, silently.

Two candidate fixes:

  1. Version the directory, not the file. agents/refund-triage/v1/agent.yaml
    plus v1/refund-policy.md. Immutability is then a property of the directory and
    the existing rule extends unchanged. Costs a layout change.
  2. Hash them at apply time, store the digest, and refuse to serve a version
    whose instruction files no longer match. Keeps the layout; adds a failure mode
    that fires long after the edit.

(1) is more in keeping with how the rest of this works, and it makes the versioned
artifact something you can look at.

Also worth deciding

  • Context cost. Instructions ride on every LLM call of every round. Prompt
    caching helps (the agent already sets cache=True), but charter validate should
    report the token cost of the assembled prompt, the way it should for tool schemas.
  • Templating. {{ inputs.* }} inside an instruction file — same rules as the
    objective, or not at all?
  • Worker distribution. Instruction files are more files the worker needs on
    disk, which makes the agents_dir coupling worse and strengthens the case for
    storing the compiled config on the control plane.

Related

Long-running tasks also need context compaction — our _history grows every round
and is re-sent on every call, with full tool output in it. Instructions make that
budget tighter. Separate issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions