mirror of https://github.com/aliasrobotics/cai.git
150 lines
5.7 KiB
Markdown
150 lines
5.7 KiB
Markdown
# Agents
|
|
|
|
Agents are the core of CAI. An agent uses Large Language Models (LLMs), configured with instructions and tools.
|
|
Each agent is defined in its own `.py` file in `src/cai/agents`.
|
|
|
|
## Basic configuration
|
|
|
|
Key agent properties include:
|
|
|
|
- `name`: of the agent e.g. the name of `one_tool_agent` is 'CTF Agent'.
|
|
- `instructions`: known as the system prompt.
|
|
- `model`: which LLM to use, and optional `model_settings` to configure their parameters like temperature, top_p, etc.
|
|
- `tools`: Tools that the agent can use to achieve its tasks.
|
|
- `handoffs`: wich allows an agent to delegate tasks to another agent.
|
|
|
|
|
|
## Example: `one_tool_agent.py`
|
|
|
|
```python
|
|
from cai.sdk.agents import Agent, OpenAIChatCompletionsModel
|
|
from cai.tools.reconnaissance.generic_linux_command import generic_linux_command
|
|
from openai import AsyncOpenAI
|
|
|
|
one_tool_agent = Agent(
|
|
name="CTF agent",
|
|
description="Agent focused on conquering security challenges using generic linux commands",
|
|
instructions="You are a Cybersecurity expert Leader facing a CTF challenge.",
|
|
tools=[
|
|
generic_linux_command,
|
|
],
|
|
model=OpenAIChatCompletionsModel(
|
|
model="qwen2.5:14b",
|
|
openai_client=AsyncOpenAI(),
|
|
)
|
|
)
|
|
```
|
|
|
|
|
|
## Context
|
|
|
|
There are two main context types. See [context](context.md) for details.
|
|
|
|
Agents are generic on their `context` type. Context is a dependency-injection tool: it's an object you create and pass to `Runner.run()`, that is passed to every agent, tool, handoff etc, and it serves as a grab bag of dependencies and state for the agent run. You can provide any Python object as the context.
|
|
|
|
```python
|
|
@dataclass
|
|
class SecurityContext:
|
|
target_system: str
|
|
is_compromised: bool
|
|
|
|
async def get_exploits() -> list[Exploits]:
|
|
return ...
|
|
|
|
agent = Agent[SecurityContext](
|
|
...,
|
|
)
|
|
```
|
|
|
|
## Output types
|
|
|
|
By default, agents produce plain text (i.e. `str`) outputs. If you want the agent to produce a particular type of output, you can use the `output_type` parameter. A common choice is to use [Pydantic](https://docs.pydantic.dev/) objects, but we support any type that can be wrapped in a Pydantic [TypeAdapter](https://docs.pydantic.dev/latest/api/type_adapter/) - dataclasses, lists, TypedDict, etc.
|
|
|
|
```python
|
|
from pydantic import BaseModel
|
|
from cai.sdk.agents import Agent
|
|
|
|
class SecurityVulnerability(BaseModel):
|
|
name: str
|
|
severity: str
|
|
affected_files: list[str]
|
|
description: str
|
|
|
|
agent = Agent(
|
|
name="Vulnerability scanner",
|
|
instructions="Analyze system output and identify security vulnerabilities",
|
|
output_type=SecurityVulnerability,
|
|
)
|
|
```
|
|
|
|
!!! note
|
|
<span style="color: red;"> When you pass an `output_type`, that tells the model to use [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) instead of regular plain text responses.</span>
|
|
|
|
## Handoffs
|
|
|
|
Handoffs are sub-agents that the agent can delegate to. You provide a list of handoffs, and the agent can choose to delegate to them if relevant. This is a powerful pattern that allows orchestrating modular, specialized agents that excel at a single task. Read more in the [handoffs](handoffs.md) documentation.
|
|
|
|
```python
|
|
from cai.sdk.agents import Agent
|
|
|
|
crypto_agent = Agent(
|
|
name="Cryptography agent",
|
|
description="Agent specialized in solving cryptographic challenges and decoding encrypted messages",
|
|
instructions="Analyze encrypted data and apply cryptographic techniques to decode it.",
|
|
tools=[
|
|
execute_cli_command,
|
|
],
|
|
handoff_description="Specialized agent in Cryptography and code breaking",
|
|
model=OpenAIChatCompletionsModel(
|
|
model=os.getenv('CAI_MODEL', "qwen2.5:14b"),
|
|
openai_client=AsyncOpenAI(),
|
|
)
|
|
)
|
|
network_agent = Agent(
|
|
name="Network Agent",
|
|
description="Agent specialized in network analysis, packet inspection, and network security assessments",
|
|
instructions="Analyze network traffic, identify suspicious patterns, and help with network-related CTF challenges",
|
|
handoff_description="Specialized agent in network security, traffic analysis, and protocol understanding",
|
|
model=OpenAIChatCompletionsModel(
|
|
model=os.getenv('CAI_MODEL', "qwen2.5:72b"),
|
|
openai_client=AsyncOpenAI(),
|
|
)
|
|
)
|
|
lead_agent = Agent(
|
|
name="Cybersecurity Lead Agent",
|
|
instructions=(
|
|
"You are a lead cybersecurity expert coordinating security operations."
|
|
"If the user needs network analysis or traffic inspection, handoff to the network agent."
|
|
"If the user needs cryptographic solutions or code breaking, handoff to the crypto agent."
|
|
),
|
|
handoffs=[network_agent, crypto_agent],
|
|
model="qwen2.5:72b"
|
|
)
|
|
```
|
|
|
|
## Dynamic instructions
|
|
|
|
In most cases, you can provide instructions when you create the agent. However, you can also provide dynamic instructions via a function. The function will receive the agent and context, and must return the prompt. Both regular and `async` functions are accepted.
|
|
|
|
```python
|
|
def dynamic_instructions(
|
|
context: RunContextWrapper[UserContext], agent: Agent[UserContext]
|
|
) -> str:
|
|
security_level = "high" if context.context.is_admin else "standard"
|
|
return f"You are assisting {context.context.name} with cybersecurity operations. Their security clearance level is {security_level}. Tailor your security recommendations appropriately and prioritize addressing their immediate security concerns."
|
|
|
|
|
|
agent = Agent[UserContext](
|
|
name="Cybersecurity Triage Agent",
|
|
instructions=dynamic_instructions,
|
|
)
|
|
```
|
|
|
|
|
|
## Next steps
|
|
|
|
- For running agents, see [running_agents documentation](running_agents.md).
|
|
|
|
- For understanding what it returns, see [results documentation](results.md).
|
|
|
|
- For connecting Agents to external tools (Model Context Protocol), see [mcp documentation](mcp.md). |