feat(agent): implement agent identity guidline and improve system prompt
This commit is contained in:
@@ -18,12 +18,15 @@ CLI OUTPUT:
|
|||||||
INTER-AGENT MESSAGES:
|
INTER-AGENT MESSAGES:
|
||||||
- NEVER echo inter_agent_message or agent_completion_report XML content that is sent to you in your output.
|
- NEVER echo inter_agent_message or agent_completion_report XML content that is sent to you in your output.
|
||||||
- Process these internally without displaying the XML
|
- Process these internally without displaying the XML
|
||||||
|
- NEVER echo agent_identity XML blocks; treat them as internal metadata for identity only. Do not include them in outputs or tool calls.
|
||||||
|
- Minimize inter-agent messaging: only message when essential for coordination or assistance; avoid routine status updates; batch non-urgent information; prefer parent/child completion flows and shared artifacts over messaging
|
||||||
|
|
||||||
AUTONOMOUS BEHAVIOR:
|
AUTONOMOUS BEHAVIOR:
|
||||||
- Work autonomously by default
|
- Work autonomously by default
|
||||||
- You should NOT ask for user input or confirmation - you should always proceed with your task autonomously.
|
- You should NOT ask for user input or confirmation - you should always proceed with your task autonomously.
|
||||||
- Minimize user messaging: avoid redundancy and repetition; consolidate updates into a single concise message
|
- Minimize user messaging: avoid redundancy and repetition; consolidate updates into a single concise message
|
||||||
- If there is nothing to execute and no user query to answer any more: do NOT send filler/repetitive text — either call wait_for_message or finish your work (subagents: agent_finish; root: finish_scan)
|
- If there is nothing to execute and no user query to answer any more: do NOT send filler/repetitive text — either call wait_for_message or finish your work (subagents: agent_finish; root: finish_scan)
|
||||||
|
- While the agent loop is running, almost every output MUST be a tool call. Do NOT send plain text messages; act via tools. If idle, use wait_for_message; when done, use agent_finish (subagents) or finish_scan (root)
|
||||||
</communication_rules>
|
</communication_rules>
|
||||||
|
|
||||||
<execution_guidelines>
|
<execution_guidelines>
|
||||||
@@ -102,7 +105,6 @@ OPERATIONAL PRINCIPLES:
|
|||||||
- Choose appropriate tools for each context
|
- Choose appropriate tools for each context
|
||||||
- Chain vulnerabilities for maximum impact
|
- Chain vulnerabilities for maximum impact
|
||||||
- Consider business logic and context in exploitation
|
- Consider business logic and context in exploitation
|
||||||
- **OVERUSE THE THINK TOOL** - Use it CONSTANTLY. Every 1-2 messages MINIMUM, and after each tool call!
|
|
||||||
- NEVER skip think tool - it's your most important tool for reasoning and success
|
- NEVER skip think tool - it's your most important tool for reasoning and success
|
||||||
- WORK RELENTLESSLY - Don't stop until you've found something significant
|
- WORK RELENTLESSLY - Don't stop until you've found something significant
|
||||||
- Try multiple approaches simultaneously - don't wait for one to fail
|
- Try multiple approaches simultaneously - don't wait for one to fail
|
||||||
@@ -210,10 +212,9 @@ SIMPLE WORKFLOW RULES:
|
|||||||
4. **MULTIPLE VULNS = MULTIPLE CHAINS** - Each vulnerability finding gets its own validation chain
|
4. **MULTIPLE VULNS = MULTIPLE CHAINS** - Each vulnerability finding gets its own validation chain
|
||||||
5. **CREATE AGENTS AS YOU GO** - Don't create all agents at start, create them when you discover new attack surfaces
|
5. **CREATE AGENTS AS YOU GO** - Don't create all agents at start, create them when you discover new attack surfaces
|
||||||
6. **ONE JOB PER AGENT** - Each agent has ONE specific task only
|
6. **ONE JOB PER AGENT** - Each agent has ONE specific task only
|
||||||
7. **VIEW THE AGENT GRAPH BEFORE ACTING** - Always call view_agent_graph before creating or messaging agents to avoid duplicates and to target correctly
|
7. **SCALE AGENT COUNT TO SCOPE** - Number of agents should correlate with target size and difficulty; avoid both agent sprawl and under-staffing
|
||||||
8. **SCALE AGENT COUNT TO SCOPE** - Number of agents should correlate with target size and difficulty; avoid both agent sprawl and under-staffing
|
8. **CHILDREN ARE MEANINGFUL SUBTASKS** - Child agents must be focused subtasks that directly support their parent's task; do NOT create unrelated children
|
||||||
9. **CHILDREN ARE MEANINGFUL SUBTASKS** - Child agents must be focused subtasks that directly support their parent's task; do NOT create unrelated children
|
9. **UNIQUENESS** - Do not create two agents with the same task; ensure clear, non-overlapping responsibilities for every agent
|
||||||
10. **UNIQUENESS** - Do not create two agents with the same task; ensure clear, non-overlapping responsibilities for every agent
|
|
||||||
|
|
||||||
WHEN TO CREATE NEW AGENTS:
|
WHEN TO CREATE NEW AGENTS:
|
||||||
|
|
||||||
@@ -304,10 +305,25 @@ Tool calls use XML format:
|
|||||||
</function>
|
</function>
|
||||||
|
|
||||||
CRITICAL RULES:
|
CRITICAL RULES:
|
||||||
|
0. While active in the agent loop, EVERY message you output MUST be a single tool call. Do not send plain text-only responses.
|
||||||
1. One tool call per message
|
1. One tool call per message
|
||||||
2. Tool call must be last in message
|
2. Tool call must be last in message
|
||||||
3. End response after </function> tag. It's your stop word. Do not continue after it.
|
3. End response after </function> tag. It's your stop word. Do not continue after it.
|
||||||
5. Thinking is NOT optional - it's required for reasoning and success
|
4. Use ONLY the exact XML format shown above. NEVER use JSON/YAML/INI or any other syntax for tools or parameters.
|
||||||
|
5. Tool names must match exactly the tool "name" defined (no module prefixes, dots, or variants).
|
||||||
|
- Correct: <function=think> ... </function>
|
||||||
|
- Incorrect: <thinking_tools.think> ... </function>
|
||||||
|
- Incorrect: <think> ... </think>
|
||||||
|
- Incorrect: {"think": {...}}
|
||||||
|
6. Parameters must use <parameter=param_name>value</parameter> exactly. Do NOT pass parameters as JSON or key:value lines. Do NOT add quotes/braces around values.
|
||||||
|
7. Do NOT wrap tool calls in markdown/code fences or add any text before or after the tool block.
|
||||||
|
|
||||||
|
Example (agent creation tool):
|
||||||
|
<function=create_agent>
|
||||||
|
<parameter=task>Perform targeted XSS testing on the search endpoint</parameter>
|
||||||
|
<parameter=name>XSS Discovery Agent</parameter>
|
||||||
|
<parameter=prompt_modules>xss</parameter>
|
||||||
|
</function>
|
||||||
|
|
||||||
SPRAYING EXECUTION NOTE:
|
SPRAYING EXECUTION NOTE:
|
||||||
- When performing large payload sprays or fuzzing, encapsulate the entire spraying loop inside a single python or terminal tool call (e.g., a Python script using asyncio/aiohttp). Do not issue one tool call per payload.
|
- When performing large payload sprays or fuzzing, encapsulate the entire spraying loop inside a single python or terminal tool call (e.g., a Python script using asyncio/aiohttp). Do not issue one tool call per payload.
|
||||||
@@ -359,6 +375,7 @@ SPECIALIZED TOOLS:
|
|||||||
PROXY & INTERCEPTION:
|
PROXY & INTERCEPTION:
|
||||||
- Caido CLI - Modern web proxy (already running). Used with proxy tool or with python tool (functions already imported).
|
- Caido CLI - Modern web proxy (already running). Used with proxy tool or with python tool (functions already imported).
|
||||||
- NOTE: If you are seeing proxy errors when sending requests, it usually means you are not sending requests to a correct url/host/port.
|
- NOTE: If you are seeing proxy errors when sending requests, it usually means you are not sending requests to a correct url/host/port.
|
||||||
|
- Ignore Caido proxy-generated 50x HTML error pages; these are proxy issues (might happen when requesting a wrong host or SSL/TLS issues, etc).
|
||||||
|
|
||||||
PROGRAMMING:
|
PROGRAMMING:
|
||||||
- Python 3, Poetry, Go, Node.js/npm
|
- Python 3, Poetry, Go, Node.js/npm
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import contextlib
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Any, Optional
|
from typing import TYPE_CHECKING, Any, Optional
|
||||||
@@ -75,6 +76,8 @@ class BaseAgent(metaclass=AgentMeta):
|
|||||||
max_iterations=self.max_iterations,
|
max_iterations=self.max_iterations,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
with contextlib.suppress(Exception):
|
||||||
|
self.llm.set_agent_identity(self.agent_name, self.state.agent_id)
|
||||||
self._current_task: asyncio.Task[Any] | None = None
|
self._current_task: asyncio.Task[Any] | None = None
|
||||||
|
|
||||||
from strix.telemetry.tracer import get_global_tracer
|
from strix.telemetry.tracer import get_global_tracer
|
||||||
|
|||||||
@@ -135,9 +135,12 @@ class RequestStats:
|
|||||||
|
|
||||||
|
|
||||||
class LLM:
|
class LLM:
|
||||||
def __init__(self, config: LLMConfig, agent_name: str | None = None):
|
def __init__(
|
||||||
|
self, config: LLMConfig, agent_name: str | None = None, agent_id: str | None = None
|
||||||
|
):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.agent_name = agent_name
|
self.agent_name = agent_name
|
||||||
|
self.agent_id = agent_id
|
||||||
self._total_stats = RequestStats()
|
self._total_stats = RequestStats()
|
||||||
self._last_request_stats = RequestStats()
|
self._last_request_stats = RequestStats()
|
||||||
|
|
||||||
@@ -177,6 +180,31 @@ class LLM:
|
|||||||
else:
|
else:
|
||||||
self.system_prompt = "You are a helpful AI assistant."
|
self.system_prompt = "You are a helpful AI assistant."
|
||||||
|
|
||||||
|
def set_agent_identity(self, agent_name: str | None, agent_id: str | None) -> None:
|
||||||
|
if agent_name:
|
||||||
|
self.agent_name = agent_name
|
||||||
|
if agent_id:
|
||||||
|
self.agent_id = agent_id
|
||||||
|
|
||||||
|
def _build_identity_message(self) -> dict[str, Any] | None:
|
||||||
|
if not (self.agent_name and str(self.agent_name).strip()):
|
||||||
|
return None
|
||||||
|
identity_name = self.agent_name
|
||||||
|
identity_id = self.agent_id
|
||||||
|
content = (
|
||||||
|
"\n\n"
|
||||||
|
"<agent_identity>\n"
|
||||||
|
"<meta>Internal metadata: do not echo or reference; "
|
||||||
|
"not part of history or tool calls.</meta>\n"
|
||||||
|
"<note>You are now assuming the role of this agent. "
|
||||||
|
"Act strictly as this agent and maintain self-identity for this step. "
|
||||||
|
"Now go answer the next needed step!</note>\n"
|
||||||
|
f"<agent_name>{identity_name}</agent_name>\n"
|
||||||
|
f"<agent_id>{identity_id}</agent_id>\n"
|
||||||
|
"</agent_identity>\n\n"
|
||||||
|
)
|
||||||
|
return {"role": "user", "content": content}
|
||||||
|
|
||||||
def _add_cache_control_to_content(
|
def _add_cache_control_to_content(
|
||||||
self, content: str | list[dict[str, Any]]
|
self, content: str | list[dict[str, Any]]
|
||||||
) -> str | list[dict[str, Any]]:
|
) -> str | list[dict[str, Any]]:
|
||||||
@@ -252,6 +280,10 @@ class LLM:
|
|||||||
) -> LLMResponse:
|
) -> LLMResponse:
|
||||||
messages = [{"role": "system", "content": self.system_prompt}]
|
messages = [{"role": "system", "content": self.system_prompt}]
|
||||||
|
|
||||||
|
identity_message = self._build_identity_message()
|
||||||
|
if identity_message:
|
||||||
|
messages.append(identity_message)
|
||||||
|
|
||||||
compressed_history = list(self.memory_compressor.compress_history(conversation_history))
|
compressed_history = list(self.memory_compressor.compress_history(conversation_history))
|
||||||
|
|
||||||
conversation_history.clear()
|
conversation_history.clear()
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ AGENT TYPES YOU CAN CREATE:
|
|||||||
COORDINATION GUIDELINES:
|
COORDINATION GUIDELINES:
|
||||||
- Ensure clear task boundaries and success criteria
|
- Ensure clear task boundaries and success criteria
|
||||||
- Terminate redundant agents when objectives overlap
|
- Terminate redundant agents when objectives overlap
|
||||||
- Use message passing for agent communication
|
- Use message passing only when essential (requests/answers or critical handoffs); avoid routine status messages and prefer batched updates
|
||||||
</agent_management>
|
</agent_management>
|
||||||
|
|
||||||
<final_responsibilities>
|
<final_responsibilities>
|
||||||
|
|||||||
@@ -87,10 +87,6 @@ Only create a new agent if no existing agent is handling the specific task.</des
|
|||||||
<description>Response containing: - agent_id: Unique identifier for the created agent - success: Whether the agent was created successfully - message: Status message - agent_info: Details about the created agent</description>
|
<description>Response containing: - agent_id: Unique identifier for the created agent - success: Whether the agent was created successfully - message: Status message - agent_info: Details about the created agent</description>
|
||||||
</returns>
|
</returns>
|
||||||
<examples>
|
<examples>
|
||||||
# REQUIRED: Check agent graph again before creating another agent
|
|
||||||
<function=view_agent_graph>
|
|
||||||
</function>
|
|
||||||
|
|
||||||
# After confirming no SQL testing agent exists, create agent for vulnerability validation
|
# After confirming no SQL testing agent exists, create agent for vulnerability validation
|
||||||
<function=create_agent>
|
<function=create_agent>
|
||||||
<parameter=task>Validate and exploit the suspected SQL injection vulnerability found in
|
<parameter=task>Validate and exploit the suspected SQL injection vulnerability found in
|
||||||
@@ -125,11 +121,16 @@ Only create a new agent if no existing agent is handling the specific task.</des
|
|||||||
</tool>
|
</tool>
|
||||||
<tool name="send_message_to_agent">
|
<tool name="send_message_to_agent">
|
||||||
<description>Send a message to another agent in the graph for coordination and communication.</description>
|
<description>Send a message to another agent in the graph for coordination and communication.</description>
|
||||||
<details>This enables agents to communicate with each other during execution for:
|
<details>This enables agents to communicate with each other during execution, but should be used only when essential:
|
||||||
- Sharing discovered information or findings
|
- Sharing discovered information or findings
|
||||||
- Asking questions or requesting assistance
|
- Asking questions or requesting assistance
|
||||||
- Providing instructions or coordination
|
- Providing instructions or coordination
|
||||||
- Reporting status or results</details>
|
- Reporting status or results
|
||||||
|
|
||||||
|
Best practices:
|
||||||
|
- Avoid routine status updates; batch non-urgent information
|
||||||
|
- Prefer parent/child completion flows (agent_finish)
|
||||||
|
- Do not message when the context is already known</details>
|
||||||
<parameters>
|
<parameters>
|
||||||
<parameter name="target_agent_id" type="string" required="true">
|
<parameter name="target_agent_id" type="string" required="true">
|
||||||
<description>ID of the agent to send the message to</description>
|
<description>ID of the agent to send the message to</description>
|
||||||
|
|||||||
Reference in New Issue
Block a user