feat(agent): implement agent identity guidline and improve system prompt

This commit is contained in:
Ahmed Allam
2025-11-15 16:21:05 +04:00
parent 478bf5d4d3
commit 383d53c7a9
5 changed files with 67 additions and 14 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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>

View File

@@ -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>