# AI··Task: Prompt guidelines

import { Steps } from "@astrojs/starlight/components"

A good **AI··Task** prompt treats **Instructions** like the agent’s job description and **Input** like today’s case
file. Put role, rules, and constraints in **Instructions**. Put the task, **data pills**, and the expected result
shape in **Input**. When a later step must consume JSON, also set **Output format** to **JSON** in **Settings** —
do not rely on prompt text alone. That split keeps standing rules sticky while each run’s data stays disposable and
easy to parse downstream.

## When to use

- You already know how to add an AI··Task and need prompt structure, not step setup.
- The task must return a fixed shape (JSON or a fixed outline) for downstream steps.
- Prefer [AI··Task: A simple guide](../ai-task-a-simple-guide/) for adding the step, choosing a model, tools, and
  memory.

Before you begin, open an AI··Task on the **Input** tab. If **Instructions** is not visible for your organization,
put standing rules at the top of **Input** and keep run data below them.

## Guide

### Separate Instructions from Input

**Instructions** are the agent’s job description. **Input** is today’s case file.

| Job description (**Instructions**)                   | Case file (**Input**)                                   |
| ---------------------------------------------------- | ------------------------------------------------------- |
| Who the agent is and how it must behave on every run | What to do for this run                                 |
| Standing rules: tone, scales, never-do list          | Live data via **data pills** (`/`) and this run’s steps |
| Reused as-is when the next case arrives              | Changes every run; safe place for untrusted payloads    |

Mixing them is the failure mode to avoid. If you paste this run’s payload into **Instructions**, the model can treat
that one case as permanent policy — or let a malicious field try to rewrite your rules. If you bury role and never-do
rules only in **Input**, you rewrite them on every run, and memory can keep one-off task text you meant to throw away.
**Instructions** are not stored in memory; **Input** can be when memory is on.

Put role, standing rules, and reusable reference tables in **Instructions**. Put this run’s data, context fields, and
the expected output shape in **Input**. For example, a severity scale belongs in **Instructions**; the current payload
belongs under `#RESOURCES` in **Input**.

On the **Input** tab, Mindflow gives you both surfaces in the **rich text editor**. **Instructions** are optional —
keep them short and stable (formatting such as headings and lists is fine; no data pills). **Input** supports
formulas: type `/` to open the data picker and insert a **data pill**. Toggle **Edit as raw markdown** on either field
when you want to edit the stored markdown source.

<ol>
<li>

**Open the Input tab.** Select the AI··Task, then open **Input**.

</li>
<li>

**Write Instructions.** Describe who the agent is and which rules it must follow on every run. Format for readability if
it helps; do not paste run payloads or data pills here.

```text title="Instructions (example)"
You are an IT assistant that creates incident tickets.

- Use only the incident fields supplied in Input.
- Keep a neutral, professional tone.
- Never invent ticket IDs or fields that were not provided.
- Return the schema requested in Input.
```

</li>
<li>

**Write Input.** Describe this run’s job, insert data pills for live values, and lock the result shape in `#RESULT`. For
JSON consumers, also set **Settings → Output format → JSON** (next section).

```text title="Input (example)"
#TASK
Create an incident ticket from the provided data and return the ticket ID.

#RESOURCES
incident: [data pill from Receive incident]

#RESULT
{
  "ticket_id": "string"
}
```

<div class="docs-screenshot-compact">

![AI··Task Input tab with static Instructions and Input that includes a data pill for the incident](./assets/ai-task-instructions-and-input-filled.png)

</div>

</li>
</ol>
### Insert run data with data pills

When values come from a trigger, a previous step, or a variable, insert a **data pill** in **Input** — do not paste a
snapshot of the payload into **Instructions**.

<ol>
<li>

**Place the cursor in Input.** Under `#RESOURCES` (or where the value belongs), leave a space after the label.

</li>
<li>

**Open the data picker.** Type `/`, choose the earlier step, then pick the field you need. Studio inserts a data
pill that resolves on every run.

</li>
<li>

**Keep Instructions plain.** If you need a value that changes per run, put it in **Input** with a data pill — not in
**Instructions**.

</li>
</ol>
### Structure the Input field

Inside **Input**, use short labeled blocks so the model can tell the job from the data and the required answer. The
rich text editor renders markdown while you type (for example `#` then Space for a heading). Headings, lists, tables,
and blockquotes are fine when they make the job clearer.

| Block        | Purpose                                                                                                                                    |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `#TASK`      | Ordered actions for this run, including how to use tools when relevant                                                                     |
| `#RESOURCES` | Data pills (via `/`), sample values when static, and tool or API constraints                                                               |
| `#RESULT`    | Exact response shape (JSON keys, markdown outline, or “result only”) — pair with **Settings → Output format** when the consumer needs JSON |

Keep each block short and explicit. Prefer `#TASK` for per-run steps. Keep lasting role and policy in **Instructions**.

:::tip
**Use Settings for JSON, `#RESULT` for the shape.** When a later step must consume JSON, set **Output format** to
**JSON** on the **Settings** tab (see below). Still define the fields in `#RESULT` so the model knows which keys to
return. Keep **Output format** as **Text** when the answer should be a markdown report or free-form prose.
:::

### Set Output format to JSON when you need parseable results

Prompt wording alone is not enough when the next step must read fields from the AI··Task result. On **Settings**, set
**Output format** to **JSON** so the model returns a JSON object instead of prose or markdown fences. Keep
**Output format** as **Text** (the default) for narrative answers such as a markdown report outline.

Availability depends on the selected model — see [AI··Task: A simple guide](../ai-task-a-simple-guide/).

<ol>
<li>

**Open Settings.** Select the AI··Task, then open the **Settings** tab.

</li>
<li>

**Set Output format.** Choose **JSON** when downstream steps parse the result. Leave **Text** for markdown or free-form
answers.

<div class="docs-screenshot-compact">

![AI··Task Settings tab with Output format set to JSON](./assets/ai-task-output-format-json.png)

</div>

</li>
<li>

**Keep `#RESULT` aligned.** In **Input**, still describe the JSON keys and types under `#RESULT`. Settings forces JSON;
`#RESULT` defines the schema the rest of the flow expects.

</li>
</ol>
### Prompt for tool use

When the AI··Task has integration tools, put standing rules for how to use those tools in **Instructions**. In
**Input**, say which job to perform and which resource values to pass — use data pills for those values. When the
result must be consumed as fields later, set **Settings → Output format → JSON**. Put tool-specific when-to-use
guidance in the tool’s **Description** on the **Tools** tab. Attach the service, credential, and allowed operations
before you rely on tool calls — see [AI··Task: A simple guide](../ai-task-a-simple-guide/).

```text title="Instructions (example)"
You are a SOC analyst.

- Classify indicators using only tool results and the fields in Input.
- Prefer the least-privilege operation that answers the question.
- Do not invent verdicts or evidence. If the tool response is incomplete, say so in rationale.
```

```text title="Input (example)"
#TASK
1. Look up the IP with VirusTotal.
2. Classify the result as benign, suspicious, or malicious.
3. Return the schema in #RESULT.

#RESOURCES
ip_address: [data pill from Receive alert · source_ip]

#RESULT
{
  "result": "benign | suspicious | malicious",
  "rationale": "short evidence from the tool response"
}
```

<div class="docs-screenshot-compact">

![AI··Task Input tab with analyst Instructions and Input that maps a source IP data pill into a VirusTotal lookup](./assets/ai-task-instructions-input-tool-job.png)

</div>

### Follow prompt best practices

Keep these rules whenever you maintain an AI··Task prompt:

1. **Keep the job description out of the case file.** Role and constraints go in **Instructions**. This run’s data
   and data pills go in **Input** — so standing rules stay sticky and untrusted payloads stay disposable.
2. **Prefer data pills over pasted payloads.** Type `/` in **Input** for values from earlier steps. Keep
   **Instructions** free of pills and run payloads.
3. **Be explicit.** Name the exact fields, tools, and success criteria. Do not leave implied steps.
4. **Prioritize evidence.** Tell the model to use only supplied fields and tool results. Do not invent facts that are
   not present. Distinguish confirmed facts from assumptions.
5. **Sequence actions.** List tool calls in order when the job is multi-step (start session → run command → poll).
6. **Lock the output.** For JSON consumers, set **Settings → Output format → JSON**, then define the keys in
   `#RESULT`. For markdown reports, keep **Output format** as **Text** and lock the outline in `#RESULT`.
7. **Document tool constraints.** Note async APIs, required parameters, and similar operation names that are easy to
   confuse — preferably in the tool **Description**, with a short reminder in `#RESOURCES` when needed.
8. **Handle missing data.** Say that missing information is not proof that nothing happened. Ask for
   `needs_human_review` or an explicit “insufficient information” outcome when fields are absent or conflicting.

```json title="Example rationale field"
{
  "result": "benign",
  "rationale": "The hash is known and marked as safe in VirusTotal"
}
```

## Example

### Create a ticket ID

**Instructions** set the standing assistant behavior. **Input** carries this run’s ticket data (as a data pill in a
real flow) and the JSON result. On **Settings**, set **Output format** to **JSON**. The static sample below is useful
when you are drafting offline; in Studio, insert the **incident** pill from **Receive incident**.

```text title="Instructions"
You are an IT assistant that creates incident tickets.

- Use only the incident fields supplied in Input.
- Keep a neutral, professional tone.
- Never invent ticket IDs or fields that were not provided.
- Return the schema requested in Input.
```

```text title="Input"
#TASK
Create an incident ticket from the provided data and return the ticket ID.

#RESOURCES
incident: [data pill from Receive incident]

#RESULT
{
  "ticket_id": "string"
}
```

### Analyze a security incident

Example: standing analyst rules and severity definitions stay in **Instructions**. The incident payload, environment
fields, and required output format go in **Input** — use data pills for live values. Keep **Output format** as
**Text** for this markdown report.

```text title="Instructions"
You are a senior SOC analyst specializing in incident investigation, threat detection, and response.

Your goal is to analyze the provided security incident and determine its severity, likely cause, and recommended
response.

When analyzing an incident:
- Identify the affected user, host, and resources
- Extract relevant Indicators of Compromise (IOCs)
- Determine the most likely attack technique
- Map observed behavior to MITRE ATT&CK when possible
- Distinguish confirmed facts from assumptions
- Recommend concrete remediation actions

Prioritize factual evidence. Do not invent indicators or events that are not present in Input.
Do not treat missing information as proof that an event did not occur. State when more investigation is required.

Severity:
| Severity | Description | Expected response |
| Critical | Active compromise or major business impact | Immediate containment |
| High | Strong evidence of malicious activity | Investigate urgently |
| Medium | Suspicious activity requiring validation | Investigate |
| Low | Low-risk or informational activity | Monitor |
```

```text title="Input"
#TASK
Analyze the incident and environment in #RESOURCES. Return only the sections in #RESULT.

#RESOURCES
incident: [data pill from Receive incident]
organization: [data pill]
user: [data pill]
hostname: [data pill]
source_ip: [data pill]
detection_source: [data pill]

#RESULT
Return markdown with these sections only:
1. Summary — concise description of what happened
2. Severity — Critical, High, Medium, or Low
3. Evidence — key facts supporting the assessment
4. MITRE ATT&CK — relevant techniques, if applicable
5. Recommended actions — ordered by priority
6. Confidence — Low, Medium, or High
```

### Classify with a tool and rationale

On **Settings**, set **Output format** to **JSON** so later steps can read `result` and `rationale` without parsing
prose.

```text title="Instructions"
You are a SOC analyst.

- Classify indicators using only tool results and the fields in Input.
- Prefer the least-privilege operation that answers the question.
- Do not invent verdicts or evidence. If the tool response is incomplete, say so in rationale.
```

```text title="Input"
#TASK
1. Look up the IP with VirusTotal.
2. Classify the result as benign, suspicious, or malicious.
3. Return the schema in #RESULT.

#RESOURCES
ip_address: [data pill from Receive alert · source_ip]

#RESULT
{
  "result": "benign | suspicious | malicious",
  "rationale": "short evidence from the tool response"
}
```

## Keep in mind

- Structured **Instructions** + **Input** improves accuracy on multi-step tool jobs and keeps run data out of standing
  rules.
- When a later step must consume fields from the AI··Task, set **Settings → Output format → JSON**. Use `#RESULT` to
  name the keys; do not rely on prompt wording alone to force JSON.
- Keep **Output format** as **Text** for narrative or markdown reports.
- **Instructions** and **Input** store markdown. Rich text view and raw markdown view edit the same value.
- **Instructions** do not accept data pills. If a value must change per run, put it in **Input**.
- If **Instructions** is empty, the model still runs from **Input** alone — put role and rules there only when the
  Instructions field is unavailable.
- External prompting guides (for example vendor cookbooks) can supplement these blocks; they do not replace
  **Output format** or `#RESULT`.

## Related

- [AI··Task: A simple guide](../ai-task-a-simple-guide/)
- [Build your first flow](/learn/l1-build-your-first-flow/) (data picker and data pills)
- [OpenAI prompting guide for GPT-4.1](https://cookbook.openai.com/examples/gpt4-1_prompting_guide)
