diff --git a/explore-analyze/workflows/authoring-techniques/troubleshooting.md b/explore-analyze/workflows/authoring-techniques/troubleshooting.md index 8efb2df63b..adbbd61c24 100644 --- a/explore-analyze/workflows/authoring-techniques/troubleshooting.md +++ b/explore-analyze/workflows/authoring-techniques/troubleshooting.md @@ -281,6 +281,31 @@ The same pattern applies to `agent-id` and `inference-id` on AI steps. Refer to Refer to [`ai.summarize`](/explore-analyze/workflows/steps/ai-steps.md#ai-summarize). +### Templated `agent-id` or `connector-id` isn't substituted [workflows-ts-ai-top-level-templating] + +**Symptom.** An AI step fails because a referenced resource (for example, an agent or connector) isn't found, even though the value is correctly defined in `consts:`. + +**Cause.** Liquid expressions are evaluated only inside the step's `with:` block. On fields outside `with:`, including `agent-id`, `connector-id`, `inference-id`, and `conversation-id`, the engine sends the text to the runtime as-is. So `agent-id: "{{ consts.agent_id }}"` arrives at the API as the literal text `{{ consts.agent_id }}`, instead of being substituted with the value of `consts.agent_id`. + +**Resolution.** Use literal values in top-level fields. For `ai.agent`, drop `connector-id` entirely (the agent encodes its connector). For fields that need templating, place them inside `with:` in snake-case (for example, `conversation_id`). + +```yaml +# Wrong — Liquid in top-level fields isn't resolved +- type: ai.agent + agent-id: "{{ consts.agent_id }}" + connector-id: "{{ consts.connector_id }}" + with: + message: "..." + +# Right — literal top-level values +- type: ai.agent + agent-id: elastic-ai-agent + with: + message: "..." +``` + +Tracked engine-side at [elastic/security-team#17236](https://github.com/elastic/security-team/issues/17236). + ## Composition [workflows-ts-composition] ### `workflow.execute` rejects `workflow_id` [workflows-ts-workflow-id] diff --git a/explore-analyze/workflows/steps/ai-steps.md b/explore-analyze/workflows/steps/ai-steps.md index dad0649ed0..197cedc746 100644 --- a/explore-analyze/workflows/steps/ai-steps.md +++ b/explore-analyze/workflows/steps/ai-steps.md @@ -26,6 +26,8 @@ AI steps let workflows call a large language model (LLM) for reasoning, classifi :::{important} `connector-id`, `agent-id`, and `inference-id` are **top-level step fields** (alongside `name`, `type`, `if`, `foreach`), written in **kebab-case**. They are not nested under `with`, and not `connectorId`. Inside `with`, most AI parameters use `camelCase` (`systemPrompt`, `maxLength`, `includeRationale`). Authentication-style references stay at the top level in kebab-case; content parameters stay inside `with` in camelCase. + +Liquid expressions in these top-level fields aren't evaluated. For example, writing `agent-id: "{{ consts.agent_id }}"` sends the text `{{ consts.agent_id }}` to the API as-is, instead of substituting the value of `consts.agent_id`. Always use a literal value here (for example, `agent-id: elastic-ai-agent`). Tracked at [elastic/security-team#17236](https://github.com/elastic/security-team/issues/17236). ::: ## `ai.prompt` [ai-prompt] diff --git a/explore-analyze/workflows/use-cases/security/automate-security-operations/ai-driven-alert-triage.md b/explore-analyze/workflows/use-cases/security/automate-security-operations/ai-driven-alert-triage.md index 3eda090645..aeed6acf56 100644 --- a/explore-analyze/workflows/use-cases/security/automate-security-operations/ai-driven-alert-triage.md +++ b/explore-analyze/workflows/use-cases/security/automate-security-operations/ai-driven-alert-triage.md @@ -25,7 +25,7 @@ If you're new to workflows, complete [Build your first workflow](/explore-analyz - **Permissions.** `All` on **Analytics > Workflows**, **Security > Cases**, and whatever Agent Builder privilege is required to invoke agents in your space. Refer to [{{kib}} privileges](/deploy-manage/users-roles/cluster-or-deployment-auth/kibana-privileges.md). - **Attack Discovery enabled.** Attack Discovery must be running in your {{elastic-sec}} deployment and producing findings. Refer to [Attack Discovery](/solutions/security/ai/attack-discovery.md). -- **Agent Builder agent.** A configured agent in {{agent-builder}} that can reason over security context. Use one of the built-in agents (for example, the Elastic AI Agent) or a [custom agent](/explore-analyze/ai-features/agent-builder/custom-agents.md). Note the agent ID. +- **Agent Builder agent.** A configured agent in {{agent-builder}} that can reason over security context. Use one of the built-in agents (for example, the Elastic AI Agent) or a [custom agent](/explore-analyze/ai-features/agent-builder/custom-agents.md). The examples use `elastic-ai-agent` as a default. Substitute your agent ID. - **Slack connector.** A Slack [connector](/deploy-manage/manage-connectors.md) or webhook URL for notifications. - **Attach the workflow to a rule.** After saving the workflow, attach it to the Attack Discovery detection rule or the rule group you want to triage. Refer to [Alert triggers](/explore-analyze/workflows/triggers/alert-triggers.md). @@ -129,11 +129,10 @@ Call the agent with the discovery context and a specific prompt. The agent retur ```yaml - name: triage type: ai.agent - agent-id: "{{ consts.agent_id }}" - connector-id: "{{ consts.connector_id }}" + agent-id: elastic-ai-agent create-conversation: false with: - prompt: | + message: | How should we remediate this attack? - Use your knowledge of Elastic Defend to generate remediation commands. @@ -164,11 +163,10 @@ Reuse the agent with a different prompt to get a one-to-two-sentence summary sui ```yaml - name: ai_summary type: ai.agent - agent-id: "{{ consts.agent_id }}" - connector-id: "{{ consts.connector_id }}" + agent-id: elastic-ai-agent create-conversation: false with: - prompt: | + message: | Produce a one-to-two-sentence summary of the attack below for a Slack notification. Wrap entity names like hostnames in backticks. Output only the summary, no preamble. @@ -251,8 +249,6 @@ triggers: enabled: true consts: - agent_id: "your-agent-id" - connector_id: "your-connector-id" slack_webhook: "https://hooks.slack.com/services/YOUR/WEBHOOK/URL" steps: @@ -299,11 +295,10 @@ steps: - name: triage type: ai.agent - agent-id: "{{ consts.agent_id }}" - connector-id: "{{ consts.connector_id }}" + agent-id: elastic-ai-agent create-conversation: false with: - prompt: | + message: | How should we remediate this attack? Reference Elastic Defend remediation commands, include a confidence score, and do not include citations or media. @@ -320,11 +315,10 @@ steps: - name: ai_summary type: ai.agent - agent-id: "{{ consts.agent_id }}" - connector-id: "{{ consts.connector_id }}" + agent-id: elastic-ai-agent create-conversation: false with: - prompt: | + message: | Produce a one-to-two-sentence summary of the attack below for a Slack notification. Wrap hostnames in backticks. Output only the summary.