Agently documentation for building AI applications with stable outputs, observable actions, and durable workflows.
Languages: English · 中文
Agently splits a prompt into named slots. The slots compose, so you can set persistent agent context once and only fill request-specific slots per call.
| Slot | Where it ends up | Typical use |
|---|---|---|
role / system |
system message | persona, capability boundaries |
info |
system or user (impl detail) | background facts, inventories, tool catalogs |
instruct |
user message | step-by-step instructions for this kind of request |
input |
user message | the actual question or payload |
output |
user message + parser | the schema you want back |
Setting a slot persistently:
agent = (
Agently.create_agent()
.role("You are an Agently support assistant.", always=True)
.info({"product": "Agently 4.x"}, always=True)
)
always=True keeps the slot at the agent level so it carries to every request the agent runs.
Setting a slot for one request:
result = (
agent
.instruct(["Reply in fewer than 80 words.", "Never invent product names."])
.input("How do I configure a model?")
.output({"answer": (str, "answer", True)})
.start()
)
instruct(...) here is per-request because always=True was not passed.
| Scope | API |
|---|---|
| Agent (persists for every future request) | .role(...), .info(...), .instruct(...), .set_agent_prompt(key, value) |
| Request (one call only) | .input(...), .output(...), .set_request_prompt(key, value) |
The slot you set last wins for that scope, so you can override agent defaults in one request without mutating the agent.
Same slot model, written declaratively:
# prompts/triage.yaml
$ensure_all_keys: true
.agent:
system: You are a ticket triage assistant.
info:
severities: ["P0", "P1", "P2", "P3"]
.request:
instruct: Classify the ticket text.
output:
$format: json
severity:
$type: str
$desc: One of P0/P1/P2/P3
$ensure: true
rationale:
$type: str
$desc: One-line reason
$ensure: true
Loading:
agent = Agently.create_agent().load_yaml_prompt("prompts/triage.yaml")
result = (
agent
.set_request_prompt("input", "Login fails for all users in EU region.")
.start()
)
load_json_prompt(...) is the same API for JSON. Both accept either a path or a raw string body. Pick one config file per prompt or stack multiple prompts with prompt_key_path="demo.output_control" to select inside a multi-prompt file.
$ensure_all_keys: true at the top makes all leaves required regardless of per-leaf $ensure. Use it when the entire schema must come back complete.
$format on the output block maps to the same output format setting as
.output(..., format=...). Supported values are auto, json,
flat_markdown, and hybrid. You can also use .format, $output_format, or
.output_format when a config file needs a more explicit key.
You can convert a Python-built prompt back to YAML/JSON for review or storage:
agent.role("You are an Agently agent.", always=True).input("Say hello.").output({
"reply": (str, "reply", True),
})
print(agent.get_yaml_prompt())
print(agent.get_json_prompt())
print(agent.get_prompt_text()) # the rendered text the model will see
This round-trip is the canonical way to compare “what I think I’m sending” against “what the framework actually sends”.
Inside any prompt slot, {name} references another slot by key, and ${name} is replaced by mappings={"name": "value"} at load time. Common patterns:
instruct: "Reply {input} politely." — pulls the request input into the instruct text.${ENV.OPENAI_API_KEY} in settings (not prompts) is replaced by the env var; prompts use ${name} with explicit mappings.${INPUT.customer}, ${INFO.policy}, and ${INSTRUCT.step} are render-time
slot references. They become prompt section pointers such as
[INPUT > customer] instead of copying slot values into another slot. Slot
names are case-insensitive; docs use uppercase. The path after the slot name
is not validated because it is only a model-facing reference label.${OUTPUT} is an alias for [OUTPUT REQUIREMENT].To trigger placeholder substitution while loading, pass mappings=... explicitly:
agent.load_yaml_prompt(yaml_text, mappings={"product_name": "Agently"})
When a request runs, Agently composes the final prompt by stacking:
always=True or set_agent_prompt)always=True)info(...))Use agent.get_prompt_text() to see the merged result before sending.
$ensure