# Skill: Configure Claude / Anthropic

Use when you want to configure Anthropic's Claude models as your LLM provider.
Claude is the default provider in this framework.

## API Key Setup

```bash
# .env
ANTHROPIC_API_KEY=sk-ant-api03-...
```

`arccrew/config.py` reads `ANTHROPIC_API_KEY` from `.env` and exports it to `os.environ`
via `_export_api_keys()` so that `langchain-anthropic` finds it automatically.

Get your key at: https://console.anthropic.com/settings/keys

## Model IDs and Use Cases

All current Claude model IDs (as of mid-2025):

### Claude Haiku 4.5
```
anthropic/claude-haiku-4-5-20251001
```
- Fastest and cheapest Claude model
- Best for: tool-calling agents with many iterations, reviewer/verifier agents, classifiers
- Context: 200K tokens
- When to use: any agent that calls tools repeatedly and needs fast turnaround

### Claude Sonnet 4
```
anthropic/claude-sonnet-4-20250514
```
- Balanced — strong reasoning at moderate cost
- Best for: complex multi-step reasoning, long-form writing, code generation
- Context: 200K tokens
- When to use: agents that need to reason deeply or produce long structured outputs

### Claude Opus 4
```
anthropic/claude-opus-4-20250514
```
- Most capable Claude model
- Best for: the hardest tasks — ambiguous requirements, complex analysis, highest quality output
- Context: 200K tokens
- When to use: sparingly, only for the most critical agents where quality > cost

## Setting the Default Model

```bash
# .env
AGENT_MODEL=anthropic/claude-haiku-4-5-20251001
```

This is the default in `arccrew/config.py`. Change it to Sonnet or Opus for better quality:

```bash
AGENT_MODEL=anthropic/claude-sonnet-4-20250514
```

## Mixing Haiku and Sonnet Strategically

The typical pattern: use Haiku for fast tool-calling agents, Sonnet for reasoning agents.

```bash
# .env
AGENT_MODEL=anthropic/claude-haiku-4-5-20251001     # default (fast agents)
RESEARCHER_MODEL=anthropic/claude-haiku-4-5-20251001 # research: tool calls, Haiku is fine
WRITER_MODEL=anthropic/claude-sonnet-4-20250514      # writing: needs better reasoning
REVIEWER_MODEL=anthropic/claude-haiku-4-5-20251001   # review: short task, Haiku is enough
```

For per-agent overrides to work, declare each agent's model field in `arccrew/config.py`:

```python
class Settings(BaseSettings):
    ...
    # Per-agent Claude model overrides
    researcher_model: str = ""
    writer_model: str = ""
    reviewer_model: str = ""
```

Empty string falls back to `AGENT_MODEL`.

## Max Tokens Considerations

The default `LLM_MAX_TOKENS=4096` works well for Haiku on short tasks. For Sonnet producing
long structured outputs (reports, detailed analysis), increase it:

```bash
# .env
LLM_MAX_TOKENS=8192    # for Sonnet writing long content
```

Or set it conservatively for reviewer agents that only output short JSON:

```bash
REVIEWER_MAX_TOKENS=1024   # not a built-in setting — would require code change
```

The current framework applies `llm_max_tokens` globally. If you need per-agent token limits,
you would need to create the model directly in the agent instead of using `get_model()`.

## Temperature for Claude

The default `LLM_TEMPERATURE=0.3` is appropriate for structured JSON output and
deterministic reasoning. Values:

- `0.0` — maximally deterministic, same input → same output (good for testing)
- `0.3` — default, reliable JSON structure with slight variation (good for production)
- `0.7` — more creative, more variation (good for brainstorming / content agents)
- `1.0` — maximum creativity (not recommended for tool-calling agents)

```bash
# .env
LLM_TEMPERATURE=0.3
```

## Extended Thinking (Anthropic)

Claude's extended thinking feature (where the model shows its reasoning chain) is **not
directly supported** via `init_chat_model()` in the standard framework. This is because
`init_chat_model` uses the standard messages API without the `thinking` parameter.

**Workaround — use langchain-anthropic directly in an agent:**

```python
from anthropic import Anthropic

class ThinkingAgent(BaseAgent):
    def __init__(self):
        super().__init__(name="thinker", use_llm=False)  # skip default model init
        self._anthropic = Anthropic()  # direct client

    @property
    def system_prompt(self) -> str:
        return self.get_prompt_manager().assemble_prompt("thinker")

    @track_timing
    async def execute(self, state: dict) -> Command:
        import asyncio
        loop = asyncio.get_event_loop()

        def _call():
            return self._anthropic.messages.create(
                model="claude-sonnet-4-20250514",
                max_tokens=16000,
                thinking={"type": "enabled", "budget_tokens": 10000},
                messages=[{"role": "user", "content": f"Analyze: {state.get('context')}"}],
            )

        from concurrent.futures import ThreadPoolExecutor
        with ThreadPoolExecutor() as ex:
            response = await loop.run_in_executor(ex, _call)

        text = response.content[-1].text  # last content block is the answer
        data = self.extract_json(text) or {"raw": text}
        return Command(goto="next", update={"result": data})
```

This is a valid pattern when you need extended thinking, but note it bypasses `run_react()`
and the tool-calling loop.

## Install

```bash
pip install langchain-anthropic
```

Verify the key and model are configured:
```bash
arccrew check
```
