Skip to main content

How do I define a custom AI agent in YAML?

Summary

  • In Omnigent, an open-source meta-harness (Apache 2.0, "Status: alpha"), a custom agent is a short YAML file: a name, a prompt or instructions, an executor block for harness, model and auth, and optional tools, os_env and policies.
  • executor.harness selects the runtime, such as claude-sdk, codex, cursor, hermes, opencode, pi or openai-agents, so switching harnesses is a one-line change.
  • Tools can be MCP servers, Python functions, sub-agents or inherited tools, and os_env.sandbox sets read_paths, write_paths and allow_network for the agent's OS tools.
  • Run the file with omnigent run path/to/agent.yaml. On Databricks, where Omnigent is in Beta, you can use the built-in policies and custom CEL policies, but not custom Python policies.

How do I define a custom AI agent in YAML?

Write one YAML file and run it with omnigent run path/to/agent.yaml. In Omnigent, that file chooses the harness and model, holds the agent-owned system instructions, and declares which tools, sub-agents, OS access and policies the agent gets. You don't have to write it by hand: describe the agent you want in any Omnigent chat and it authors the file for you.

Which fields does the agent YAML support?

Field What it does Example or default
name Stable identifier shown in sessions and logs my_agent
prompt Inline agent-owned system instructions You are a helpful data analyst.
instructions Inline text or a file path; wins over prompt AGENTS.md
executor Harness, model, auth and optional reasoning_effort harness: claude-sdk
tools MCP servers, Python functions, sub-agents, handoffs or inherited tools type: mcp
policies Guardrails on requests, responses, tool calls and tool results type: function
os_env Local file and shell tools, plus the OS sandbox type: caller_process
terminals Named interactive shells the agent can launch command: bash
async / cancellable / timers Async work tools, cancellation, timer tools true / true / false

What does a complete agent file look like?

name: data_processor
prompt: |
  You process files in this repository and write results to ./artifacts.
  Inspect files before editing and summarize what you changed.

executor:
  harness: claude-sdk
  model: databricks-claude-sonnet-4-6
  auth:
    type: databricks
    profile: <your-profile>

os_env:
  type: caller_process
  cwd: .
  sandbox:
    write_paths: [./artifacts]
    allow_network: false

tools:
  docs:
    type: mcp
    url: https://example.com/mcp
  reviewer:
    type: agent
    description: Review proposed code changes.
    executor:
      harness: codex

policies:
  approve_file_ops:
    type: function
    handler: omnigent.policies.builtins.safety.ask_on_os_tools

On hardened sandbox backends cwd is read-only by default, so write_paths opts ./artifacts back in. allow_network: false turns network access off for the OS tools, and ask_on_os_tools asks you before any file or shell operation. Test the file with omnigent run path/to/agent.yaml -p "Say hello" before you share it.

How do I choose the harness and model?

executor.harness picks the runtime. The README lists claude-sdk, claude-native, codex, codex-native, cursor, cursor-native, hermes, hermes-native, opencode, pi, pi-native and openai-agents. Tools, policies, prompts and models stay the same when you swap it, and --harness and --model override the executor for one run, as in omni run agent.yaml --harness codex. The cursor harness needs a Cursor model id and CURSOR_API_KEY or a prior cursor-agent login; the Databricks route doesn't apply to it.

How do tools, sub-agents and the sandbox work?

  • MCP servers use command and args for local stdio servers, or url for remote HTTP/SSE servers. An optional tools list filters what's exposed, and ${VAR} references in env and headers are expanded at runtime.
  • Python functions point callable at an import path. The parameters JSON Schema is optional, because Omnigent can generate it from the signature.
  • Sub-agents use type: agent, inline or through config: agents/reviewer.yaml. Each can set its own harness, model, tools and policies; pass_history forwards the parent's history and max_sessions limits concurrent invocations.
  • Inheritance: tools.<name>: inherit reuses a parent tool, and spec: self clones the parent spec.

The OS sandbox covers the sys_os_* tools and declared terminals. It doesn't cover MCP servers or the supervisor process that runs the model loop. Omit sandbox.type and Omnigent picks the platform default, linux_bwrap, darwin_seatbelt or windows_jobobject; none opts out. If a requested sandbox can't be provided, Omnigent errors instead of running unsandboxed.

How do policies work?

Each policy has type: function, a handler import path and optional factory_params, and can target phases with a list such as on: [request, response]. A policy returns ALLOW, ASK or DENY. Session policies run first, then agent-spec policies, then server-wide ones, and a DENY short-circuits the rest. Builtins include max_tool_calls_per_session (default limit 100), cost_budget and ask_on_os_tools.

How does Databricks approach custom agent YAML?

On Databricks, Omnigent is in Beta and runs as a managed service. You define an agent in a short YAML file, then swap one line to change its harness or model while tools, prompts, skills and policies stay the same. The managed service supports the built-in contextual policies and custom policies written in Common Expression Language (CEL). Custom Python policies aren't supported there.

FAQs

Can one YAML file define several agents?

Yes, as sub-agents. A supervisor's tools block can declare type: agent entries inline or point each at its own config file, and a directory bundle keeps config.yaml at its root for omni run ./my-agent/.

What happens if the agent reaches for a path it wasn't granted?

On Linux and macOS, the agent sees only the paths you grant; everything else doesn't exist inside the sandbox. On Windows, the Job Object backend contains the process tree but doesn't isolate the filesystem or network.

How do I keep secrets out of the file?

Use ${VAR} references, for example in MCP headers or executor.auth.api_key, and pass only the variables a tool needs through sandbox.env_passthrough.

The information provided herein is for general informational purposes only and may not reflect the most current product capabilities or configurations.