claudient 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +42 -0
- package/CONTEXT.md +58 -0
- package/README.md +165 -0
- package/agents/build-resolvers/de/python-resolver.md +64 -0
- package/agents/build-resolvers/de/typescript-resolver.md +65 -0
- package/agents/build-resolvers/es/python-resolver.md +64 -0
- package/agents/build-resolvers/es/typescript-resolver.md +65 -0
- package/agents/build-resolvers/fr/python-resolver.md +64 -0
- package/agents/build-resolvers/fr/typescript-resolver.md +65 -0
- package/agents/build-resolvers/nl/python-resolver.md +64 -0
- package/agents/build-resolvers/nl/typescript-resolver.md +65 -0
- package/agents/build-resolvers/python-resolver.md +62 -0
- package/agents/build-resolvers/typescript-resolver.md +63 -0
- package/agents/core/architect.md +64 -0
- package/agents/core/code-reviewer.md +78 -0
- package/agents/core/de/architect.md +66 -0
- package/agents/core/de/code-reviewer.md +80 -0
- package/agents/core/de/planner.md +63 -0
- package/agents/core/de/security-reviewer.md +93 -0
- package/agents/core/es/architect.md +66 -0
- package/agents/core/es/code-reviewer.md +80 -0
- package/agents/core/es/planner.md +63 -0
- package/agents/core/es/security-reviewer.md +93 -0
- package/agents/core/fr/architect.md +66 -0
- package/agents/core/fr/code-reviewer.md +80 -0
- package/agents/core/fr/planner.md +63 -0
- package/agents/core/fr/security-reviewer.md +93 -0
- package/agents/core/nl/architect.md +66 -0
- package/agents/core/nl/code-reviewer.md +80 -0
- package/agents/core/nl/planner.md +63 -0
- package/agents/core/nl/security-reviewer.md +93 -0
- package/agents/core/planner.md +61 -0
- package/agents/core/security-reviewer.md +91 -0
- package/guides/agent-orchestration.md +231 -0
- package/guides/de/agent-orchestration.md +174 -0
- package/guides/de/getting-started.md +164 -0
- package/guides/de/hooks-cookbook.md +160 -0
- package/guides/de/memory-management.md +153 -0
- package/guides/de/security.md +180 -0
- package/guides/de/skill-authoring.md +214 -0
- package/guides/de/token-optimization.md +156 -0
- package/guides/es/agent-orchestration.md +174 -0
- package/guides/es/getting-started.md +164 -0
- package/guides/es/hooks-cookbook.md +160 -0
- package/guides/es/memory-management.md +153 -0
- package/guides/es/security.md +180 -0
- package/guides/es/skill-authoring.md +214 -0
- package/guides/es/token-optimization.md +156 -0
- package/guides/fr/agent-orchestration.md +174 -0
- package/guides/fr/getting-started.md +164 -0
- package/guides/fr/hooks-cookbook.md +227 -0
- package/guides/fr/memory-management.md +169 -0
- package/guides/fr/security.md +180 -0
- package/guides/fr/skill-authoring.md +214 -0
- package/guides/fr/token-optimization.md +158 -0
- package/guides/getting-started.md +164 -0
- package/guides/hooks-cookbook.md +423 -0
- package/guides/memory-management.md +192 -0
- package/guides/nl/agent-orchestration.md +174 -0
- package/guides/nl/getting-started.md +164 -0
- package/guides/nl/hooks-cookbook.md +160 -0
- package/guides/nl/memory-management.md +153 -0
- package/guides/nl/security.md +180 -0
- package/guides/nl/skill-authoring.md +214 -0
- package/guides/nl/token-optimization.md +156 -0
- package/guides/security.md +229 -0
- package/guides/skill-authoring.md +226 -0
- package/guides/token-optimization.md +169 -0
- package/hooks/lifecycle/cost-tracker.md +49 -0
- package/hooks/lifecycle/cost-tracker.sh +59 -0
- package/hooks/lifecycle/pre-compact-save.md +56 -0
- package/hooks/lifecycle/pre-compact-save.sh +37 -0
- package/hooks/lifecycle/session-start.md +50 -0
- package/hooks/lifecycle/session-start.sh +47 -0
- package/hooks/post-tool-use/audit-log.md +53 -0
- package/hooks/post-tool-use/audit-log.sh +53 -0
- package/hooks/post-tool-use/prettier.md +53 -0
- package/hooks/post-tool-use/prettier.sh +49 -0
- package/hooks/pre-tool-use/block-dangerous.md +48 -0
- package/hooks/pre-tool-use/block-dangerous.sh +76 -0
- package/hooks/pre-tool-use/git-push-confirm.md +46 -0
- package/hooks/pre-tool-use/git-push-confirm.sh +36 -0
- package/mcp/configs/github.json +11 -0
- package/mcp/configs/postgres.json +11 -0
- package/mcp/de/recommended-servers.md +170 -0
- package/mcp/es/recommended-servers.md +170 -0
- package/mcp/fr/recommended-servers.md +170 -0
- package/mcp/nl/recommended-servers.md +170 -0
- package/mcp/recommended-servers.md +168 -0
- package/package.json +45 -0
- package/prompts/project-starters/de/fastapi-project.md +62 -0
- package/prompts/project-starters/de/nextjs-project.md +82 -0
- package/prompts/project-starters/es/fastapi-project.md +62 -0
- package/prompts/project-starters/es/nextjs-project.md +82 -0
- package/prompts/project-starters/fastapi-project.md +60 -0
- package/prompts/project-starters/fr/fastapi-project.md +62 -0
- package/prompts/project-starters/fr/nextjs-project.md +82 -0
- package/prompts/project-starters/nextjs-project.md +80 -0
- package/prompts/project-starters/nl/fastapi-project.md +62 -0
- package/prompts/project-starters/nl/nextjs-project.md +82 -0
- package/prompts/system-prompts/ai-product.md +80 -0
- package/prompts/system-prompts/data-pipeline.md +76 -0
- package/prompts/system-prompts/de/ai-product.md +82 -0
- package/prompts/system-prompts/de/data-pipeline.md +78 -0
- package/prompts/system-prompts/de/saas-backend.md +71 -0
- package/prompts/system-prompts/es/ai-product.md +82 -0
- package/prompts/system-prompts/es/data-pipeline.md +78 -0
- package/prompts/system-prompts/es/saas-backend.md +71 -0
- package/prompts/system-prompts/fr/ai-product.md +82 -0
- package/prompts/system-prompts/fr/data-pipeline.md +78 -0
- package/prompts/system-prompts/fr/saas-backend.md +71 -0
- package/prompts/system-prompts/nl/ai-product.md +82 -0
- package/prompts/system-prompts/nl/data-pipeline.md +78 -0
- package/prompts/system-prompts/nl/saas-backend.md +71 -0
- package/prompts/system-prompts/saas-backend.md +69 -0
- package/prompts/task-specific/changelog.md +81 -0
- package/prompts/task-specific/de/changelog.md +83 -0
- package/prompts/task-specific/de/debugging.md +78 -0
- package/prompts/task-specific/de/pr-description.md +69 -0
- package/prompts/task-specific/debugging.md +76 -0
- package/prompts/task-specific/es/changelog.md +83 -0
- package/prompts/task-specific/es/debugging.md +78 -0
- package/prompts/task-specific/es/pr-description.md +69 -0
- package/prompts/task-specific/fr/changelog.md +83 -0
- package/prompts/task-specific/fr/debugging.md +78 -0
- package/prompts/task-specific/fr/pr-description.md +69 -0
- package/prompts/task-specific/nl/changelog.md +83 -0
- package/prompts/task-specific/nl/debugging.md +78 -0
- package/prompts/task-specific/nl/pr-description.md +69 -0
- package/prompts/task-specific/pr-description.md +67 -0
- package/rules/common/coding-style.md +45 -0
- package/rules/common/de/coding-style.md +47 -0
- package/rules/common/de/git.md +48 -0
- package/rules/common/de/performance.md +40 -0
- package/rules/common/de/security.md +45 -0
- package/rules/common/de/testing.md +45 -0
- package/rules/common/es/coding-style.md +47 -0
- package/rules/common/es/git.md +48 -0
- package/rules/common/es/performance.md +40 -0
- package/rules/common/es/security.md +45 -0
- package/rules/common/es/testing.md +45 -0
- package/rules/common/fr/coding-style.md +47 -0
- package/rules/common/fr/git.md +48 -0
- package/rules/common/fr/performance.md +40 -0
- package/rules/common/fr/security.md +45 -0
- package/rules/common/fr/testing.md +45 -0
- package/rules/common/git.md +46 -0
- package/rules/common/nl/coding-style.md +47 -0
- package/rules/common/nl/git.md +48 -0
- package/rules/common/nl/performance.md +40 -0
- package/rules/common/nl/security.md +45 -0
- package/rules/common/nl/testing.md +45 -0
- package/rules/common/performance.md +38 -0
- package/rules/common/security.md +43 -0
- package/rules/common/testing.md +43 -0
- package/rules/language-specific/de/go.md +48 -0
- package/rules/language-specific/de/python.md +38 -0
- package/rules/language-specific/de/typescript.md +51 -0
- package/rules/language-specific/es/go.md +48 -0
- package/rules/language-specific/es/python.md +38 -0
- package/rules/language-specific/es/typescript.md +51 -0
- package/rules/language-specific/fr/go.md +48 -0
- package/rules/language-specific/fr/python.md +38 -0
- package/rules/language-specific/fr/typescript.md +51 -0
- package/rules/language-specific/go.md +46 -0
- package/rules/language-specific/nl/go.md +48 -0
- package/rules/language-specific/nl/python.md +38 -0
- package/rules/language-specific/nl/typescript.md +51 -0
- package/rules/language-specific/python.md +36 -0
- package/rules/language-specific/typescript.md +49 -0
- package/scripts/cli.js +161 -0
- package/scripts/link-skills.sh +35 -0
- package/scripts/list-skills.sh +34 -0
- package/skills/ai-engineering/agent-construction.md +285 -0
- package/skills/ai-engineering/claude-api.md +248 -0
- package/skills/ai-engineering/de/agent-construction.md +287 -0
- package/skills/ai-engineering/de/claude-api.md +250 -0
- package/skills/ai-engineering/es/agent-construction.md +287 -0
- package/skills/ai-engineering/es/claude-api.md +250 -0
- package/skills/ai-engineering/fr/agent-construction.md +287 -0
- package/skills/ai-engineering/fr/claude-api.md +250 -0
- package/skills/ai-engineering/nl/agent-construction.md +287 -0
- package/skills/ai-engineering/nl/claude-api.md +250 -0
- package/skills/backend/dotnet/csharp.md +304 -0
- package/skills/backend/dotnet/de/csharp.md +306 -0
- package/skills/backend/dotnet/es/csharp.md +306 -0
- package/skills/backend/dotnet/fr/csharp.md +306 -0
- package/skills/backend/dotnet/nl/csharp.md +306 -0
- package/skills/backend/go/de/go.md +307 -0
- package/skills/backend/go/es/go.md +307 -0
- package/skills/backend/go/fr/go.md +307 -0
- package/skills/backend/go/go.md +305 -0
- package/skills/backend/go/nl/go.md +307 -0
- package/skills/backend/nodejs/de/nestjs.md +274 -0
- package/skills/backend/nodejs/de/nextjs.md +222 -0
- package/skills/backend/nodejs/es/nestjs.md +274 -0
- package/skills/backend/nodejs/es/nextjs.md +222 -0
- package/skills/backend/nodejs/fr/nestjs.md +274 -0
- package/skills/backend/nodejs/fr/nextjs.md +222 -0
- package/skills/backend/nodejs/nestjs.md +272 -0
- package/skills/backend/nodejs/nextjs.md +220 -0
- package/skills/backend/nodejs/nl/nestjs.md +274 -0
- package/skills/backend/nodejs/nl/nextjs.md +222 -0
- package/skills/backend/python/de/django.md +285 -0
- package/skills/backend/python/de/fastapi.md +244 -0
- package/skills/backend/python/django.md +283 -0
- package/skills/backend/python/es/django.md +285 -0
- package/skills/backend/python/es/fastapi.md +244 -0
- package/skills/backend/python/fastapi.md +242 -0
- package/skills/backend/python/fr/django.md +285 -0
- package/skills/backend/python/fr/fastapi.md +244 -0
- package/skills/backend/python/nl/django.md +285 -0
- package/skills/backend/python/nl/fastapi.md +244 -0
- package/skills/data-ml/dbt-data-pipelines.md +155 -0
- package/skills/data-ml/de/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/de/pandas-polars.md +147 -0
- package/skills/data-ml/de/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/es/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/es/pandas-polars.md +147 -0
- package/skills/data-ml/es/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/fr/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/fr/pandas-polars.md +147 -0
- package/skills/data-ml/fr/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/nl/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/nl/pandas-polars.md +147 -0
- package/skills/data-ml/nl/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/pandas-polars.md +145 -0
- package/skills/data-ml/pytorch-tensorflow.md +169 -0
- package/skills/database/de/graphql.md +181 -0
- package/skills/database/es/graphql.md +181 -0
- package/skills/database/fr/graphql.md +181 -0
- package/skills/database/graphql.md +179 -0
- package/skills/database/nl/graphql.md +181 -0
- package/skills/devops-infra/de/docker.md +133 -0
- package/skills/devops-infra/de/github-actions.md +179 -0
- package/skills/devops-infra/de/kubernetes.md +129 -0
- package/skills/devops-infra/de/terraform.md +130 -0
- package/skills/devops-infra/docker.md +131 -0
- package/skills/devops-infra/es/docker.md +133 -0
- package/skills/devops-infra/es/github-actions.md +179 -0
- package/skills/devops-infra/es/kubernetes.md +129 -0
- package/skills/devops-infra/es/terraform.md +130 -0
- package/skills/devops-infra/fr/docker.md +133 -0
- package/skills/devops-infra/fr/github-actions.md +179 -0
- package/skills/devops-infra/fr/kubernetes.md +129 -0
- package/skills/devops-infra/fr/terraform.md +130 -0
- package/skills/devops-infra/github-actions.md +177 -0
- package/skills/devops-infra/kubernetes.md +127 -0
- package/skills/devops-infra/nl/docker.md +133 -0
- package/skills/devops-infra/nl/github-actions.md +179 -0
- package/skills/devops-infra/nl/kubernetes.md +129 -0
- package/skills/devops-infra/nl/terraform.md +130 -0
- package/skills/devops-infra/terraform.md +128 -0
- package/skills/finance-payments/de/stripe.md +187 -0
- package/skills/finance-payments/es/stripe.md +187 -0
- package/skills/finance-payments/fr/stripe.md +187 -0
- package/skills/finance-payments/nl/stripe.md +187 -0
- package/skills/finance-payments/stripe.md +185 -0
- package/workflows/code-review.md +151 -0
- package/workflows/de/code-review.md +153 -0
- package/workflows/de/debugging-session.md +146 -0
- package/workflows/de/feature-development.md +155 -0
- package/workflows/de/new-project-bootstrap.md +175 -0
- package/workflows/de/refactor-safely.md +150 -0
- package/workflows/debugging-session.md +144 -0
- package/workflows/es/code-review.md +153 -0
- package/workflows/es/debugging-session.md +146 -0
- package/workflows/es/feature-development.md +155 -0
- package/workflows/es/new-project-bootstrap.md +175 -0
- package/workflows/es/refactor-safely.md +150 -0
- package/workflows/feature-development.md +153 -0
- package/workflows/fr/code-review.md +153 -0
- package/workflows/fr/debugging-session.md +146 -0
- package/workflows/fr/feature-development.md +155 -0
- package/workflows/fr/new-project-bootstrap.md +175 -0
- package/workflows/fr/refactor-safely.md +150 -0
- package/workflows/new-project-bootstrap.md +173 -0
- package/workflows/nl/code-review.md +153 -0
- package/workflows/nl/debugging-session.md +146 -0
- package/workflows/nl/feature-development.md +155 -0
- package/workflows/nl/new-project-bootstrap.md +175 -0
- package/workflows/nl/refactor-safely.md +150 -0
- package/workflows/refactor-safely.md +148 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
> 🇪🇸 Esta es la traducción en español. [Versión en inglés](../claude-api.md).
|
|
2
|
+
|
|
3
|
+
# Skill de Claude API
|
|
4
|
+
|
|
5
|
+
## Cuándo activar
|
|
6
|
+
- Escribir código que llama a la API de Claude de Anthropic (SDK de Python o TypeScript)
|
|
7
|
+
- Implementar caché de prompts, streaming o procesamiento por lotes
|
|
8
|
+
- Diseñar la gestión de conversaciones multi-turno
|
|
9
|
+
- Seleccionar el modelo de Claude adecuado (Haiku, Sonnet, Opus) para una tarea
|
|
10
|
+
- Agregar uso de herramientas / llamadas a funciones a una integración de Claude
|
|
11
|
+
- Optimizar el costo o la latencia en una aplicación Claude de producción
|
|
12
|
+
|
|
13
|
+
## Cuándo NO usar
|
|
14
|
+
- APIs de OpenAI u otros proveedores — SDK diferente, patrones diferentes
|
|
15
|
+
- Consejos genéricos sobre LLM no relacionados con la API de Anthropic
|
|
16
|
+
- Proyectos que ya usan abstracciones de LangChain o LlamaIndex — abordar la capa de abstracción directamente
|
|
17
|
+
|
|
18
|
+
## Instrucciones
|
|
19
|
+
|
|
20
|
+
### Guía de selección de modelos
|
|
21
|
+
| Modelo | Usar cuando | Evitar cuando |
|
|
22
|
+
|-------|----------|------------|
|
|
23
|
+
| `claude-haiku-4-5-20251001` | Clasificación, extracción, routing, Q&A simple, alto volumen bajo costo | Razonamiento complejo, generación de código multi-paso |
|
|
24
|
+
| `claude-sonnet-4-6` | Uso general: código, análisis, escritura, flujos de trabajo agénticos | Presupuestos de tokens muy ajustados a escala masiva |
|
|
25
|
+
| `claude-opus-4-7` | Razonamiento de nivel experto, juicio matizado, contenido largo complejo | La mayoría de tareas — Sonnet suele ser suficiente |
|
|
26
|
+
|
|
27
|
+
### Llamada básica a messages (Python)
|
|
28
|
+
```python
|
|
29
|
+
import anthropic
|
|
30
|
+
|
|
31
|
+
client = anthropic.Anthropic() # lee ANTHROPIC_API_KEY del entorno
|
|
32
|
+
|
|
33
|
+
message = client.messages.create(
|
|
34
|
+
model="claude-sonnet-4-6",
|
|
35
|
+
max_tokens=1024,
|
|
36
|
+
system="You are a helpful assistant specialized in Python.",
|
|
37
|
+
messages=[
|
|
38
|
+
{"role": "user", "content": "Explain Python's GIL in 3 sentences."}
|
|
39
|
+
]
|
|
40
|
+
)
|
|
41
|
+
print(message.content[0].text)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Caché de prompts (crítico para el costo)
|
|
45
|
+
La caché de prompts puede reducir costos hasta un 90% para contexto repetido. Cachea contenido estable (prompts de sistema, documentos grandes, ejemplos few-shot).
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
message = client.messages.create(
|
|
49
|
+
model="claude-sonnet-4-6",
|
|
50
|
+
max_tokens=1024,
|
|
51
|
+
system=[
|
|
52
|
+
{
|
|
53
|
+
"type": "text",
|
|
54
|
+
"text": "You are a code review assistant. Here are our coding standards: ...",
|
|
55
|
+
"cache_control": {"type": "ephemeral"} # Cachear este bloque
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
messages=[
|
|
59
|
+
{
|
|
60
|
+
"role": "user",
|
|
61
|
+
"content": [
|
|
62
|
+
{
|
|
63
|
+
"type": "text",
|
|
64
|
+
"text": large_document,
|
|
65
|
+
"cache_control": {"type": "ephemeral"} # También cachear el documento
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"type": "text",
|
|
69
|
+
"text": "Summarize the key points."
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
)
|
|
75
|
+
# Verificar uso de caché en la respuesta
|
|
76
|
+
print(message.usage.cache_read_input_tokens) # tokens leídos de la caché
|
|
77
|
+
print(message.usage.cache_creation_input_tokens) # tokens escritos en la caché
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Reglas de caché:
|
|
81
|
+
- Bloque mínimo cacheable: 1024 tokens (Sonnet/Opus), 2048 tokens (Haiku)
|
|
82
|
+
- TTL de caché: 5 minutos
|
|
83
|
+
- Solo el último bloque `cache_control` en un array de mensajes importa — los puntos de caché son acumulativos
|
|
84
|
+
|
|
85
|
+
### Streaming
|
|
86
|
+
```python
|
|
87
|
+
with client.messages.stream(
|
|
88
|
+
model="claude-sonnet-4-6",
|
|
89
|
+
max_tokens=1024,
|
|
90
|
+
messages=[{"role": "user", "content": prompt}]
|
|
91
|
+
) as stream:
|
|
92
|
+
for text in stream.text_stream:
|
|
93
|
+
print(text, end="", flush=True)
|
|
94
|
+
|
|
95
|
+
# O con eventos:
|
|
96
|
+
with client.messages.stream(...) as stream:
|
|
97
|
+
for event in stream:
|
|
98
|
+
if event.type == "content_block_delta":
|
|
99
|
+
print(event.delta.text, end="")
|
|
100
|
+
elif event.type == "message_stop":
|
|
101
|
+
print() # nueva línea al terminar
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Uso de herramientas
|
|
105
|
+
```python
|
|
106
|
+
tools = [
|
|
107
|
+
{
|
|
108
|
+
"name": "get_weather",
|
|
109
|
+
"description": "Get current weather for a city",
|
|
110
|
+
"input_schema": {
|
|
111
|
+
"type": "object",
|
|
112
|
+
"properties": {
|
|
113
|
+
"city": {"type": "string", "description": "City name"},
|
|
114
|
+
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
|
|
115
|
+
},
|
|
116
|
+
"required": ["city"]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
response = client.messages.create(
|
|
122
|
+
model="claude-sonnet-4-6",
|
|
123
|
+
max_tokens=1024,
|
|
124
|
+
tools=tools,
|
|
125
|
+
messages=[{"role": "user", "content": "What's the weather in Paris?"}]
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Verificar si Claude quiere usar una herramienta
|
|
129
|
+
if response.stop_reason == "tool_use":
|
|
130
|
+
tool_use = next(b for b in response.content if b.type == "tool_use")
|
|
131
|
+
tool_result = call_tool(tool_use.name, tool_use.input)
|
|
132
|
+
|
|
133
|
+
# Continuar la conversación con el resultado de la herramienta
|
|
134
|
+
follow_up = client.messages.create(
|
|
135
|
+
model="claude-sonnet-4-6",
|
|
136
|
+
max_tokens=1024,
|
|
137
|
+
tools=tools,
|
|
138
|
+
messages=[
|
|
139
|
+
{"role": "user", "content": "What's the weather in Paris?"},
|
|
140
|
+
{"role": "assistant", "content": response.content},
|
|
141
|
+
{
|
|
142
|
+
"role": "user",
|
|
143
|
+
"content": [{
|
|
144
|
+
"type": "tool_result",
|
|
145
|
+
"tool_use_id": tool_use.id,
|
|
146
|
+
"content": json.dumps(tool_result)
|
|
147
|
+
}]
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Conversación multi-turno
|
|
154
|
+
```python
|
|
155
|
+
class Conversation:
|
|
156
|
+
def __init__(self, system: str, model: str = "claude-sonnet-4-6"):
|
|
157
|
+
self.client = anthropic.Anthropic()
|
|
158
|
+
self.model = model
|
|
159
|
+
self.system = system
|
|
160
|
+
self.messages: list[dict] = []
|
|
161
|
+
|
|
162
|
+
def chat(self, user_message: str, max_tokens: int = 1024) -> str:
|
|
163
|
+
self.messages.append({"role": "user", "content": user_message})
|
|
164
|
+
response = self.client.messages.create(
|
|
165
|
+
model=self.model,
|
|
166
|
+
max_tokens=max_tokens,
|
|
167
|
+
system=self.system,
|
|
168
|
+
messages=self.messages,
|
|
169
|
+
)
|
|
170
|
+
assistant_message = response.content[0].text
|
|
171
|
+
self.messages.append({"role": "assistant", "content": assistant_message})
|
|
172
|
+
return assistant_message
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Procesamiento por lotes
|
|
176
|
+
```python
|
|
177
|
+
from anthropic.types.message_create_params import MessageCreateParamsNonStreaming
|
|
178
|
+
from anthropic.types.messages.batch_create_params import Request
|
|
179
|
+
|
|
180
|
+
requests = [
|
|
181
|
+
Request(
|
|
182
|
+
custom_id=f"review-{i}",
|
|
183
|
+
params=MessageCreateParamsNonStreaming(
|
|
184
|
+
model="claude-haiku-4-5-20251001",
|
|
185
|
+
max_tokens=256,
|
|
186
|
+
messages=[{"role": "user", "content": f"Classify: {review}"}],
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
for i, review in enumerate(reviews)
|
|
190
|
+
]
|
|
191
|
+
|
|
192
|
+
batch = client.messages.batches.create(requests=requests)
|
|
193
|
+
print(f"Batch ID: {batch.id}")
|
|
194
|
+
|
|
195
|
+
# Sondear resultados (o usar webhooks)
|
|
196
|
+
import time
|
|
197
|
+
while True:
|
|
198
|
+
batch = client.messages.batches.retrieve(batch.id)
|
|
199
|
+
if batch.processing_status == "ended":
|
|
200
|
+
break
|
|
201
|
+
time.sleep(60)
|
|
202
|
+
|
|
203
|
+
for result in client.messages.batches.results(batch.id):
|
|
204
|
+
print(result.custom_id, result.result.message.content[0].text)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Manejo de errores y reintentos
|
|
208
|
+
```python
|
|
209
|
+
from anthropic import APIStatusError, APITimeoutError, RateLimitError
|
|
210
|
+
|
|
211
|
+
def call_with_retry(client, **kwargs, max_retries=3):
|
|
212
|
+
for attempt in range(max_retries):
|
|
213
|
+
try:
|
|
214
|
+
return client.messages.create(**kwargs)
|
|
215
|
+
except RateLimitError:
|
|
216
|
+
wait = 2 ** attempt
|
|
217
|
+
time.sleep(wait)
|
|
218
|
+
except APITimeoutError:
|
|
219
|
+
if attempt == max_retries - 1:
|
|
220
|
+
raise
|
|
221
|
+
time.sleep(1)
|
|
222
|
+
except APIStatusError as e:
|
|
223
|
+
if e.status_code >= 500 and attempt < max_retries - 1:
|
|
224
|
+
time.sleep(2 ** attempt)
|
|
225
|
+
else:
|
|
226
|
+
raise
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Lista de verificación de optimización de costos
|
|
230
|
+
- Usar Haiku para clasificación, routing y tareas de extracción simple
|
|
231
|
+
- Habilitar caché de prompts para cualquier prompt de sistema > 1024 tokens
|
|
232
|
+
- Usar la API de lotes para cargas de trabajo offline/asíncronas — 50% de reducción de costo
|
|
233
|
+
- Establecer `max_tokens` al mínimo necesario — pagas por los tokens de salida generados
|
|
234
|
+
- Cachear documentos grandes en el mensaje del usuario, no solo en el prompt del sistema
|
|
235
|
+
- Monitorear la relación `cache_read_input_tokens` vs `input_tokens` — objetivo >80% para contextos estables
|
|
236
|
+
|
|
237
|
+
## Ejemplo
|
|
238
|
+
|
|
239
|
+
**Usuario:** Construir una clase Python que clasifica tickets de soporte al cliente en categorías usando Claude, con caché de prompts para la lista de categorías y streaming para la explicación.
|
|
240
|
+
|
|
241
|
+
**Salida esperada:**
|
|
242
|
+
- Clase `TicketClassifier` con `ANTHROPIC_API_KEY` del entorno
|
|
243
|
+
- Prompt de sistema con todas las categorías cacheadas mediante `cache_control: ephemeral`
|
|
244
|
+
- `classify(ticket_text)` → devuelve `{category: str, confidence: str}` parseado de salida estructurada
|
|
245
|
+
- `classify_and_explain(ticket_text)` → transmite la explicación a stdout
|
|
246
|
+
- Usa `claude-haiku-4-5-20251001` para clasificación (eficiente en costo), `claude-sonnet-4-6` para explicación
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
> **Trabaja con nosotros:** Claudient está respaldado por [Uitbreiden](https://uitbreiden.com/) — construimos productos de IA y soluciones B2B con comunidades de desarrolladores. [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
> 🇫🇷 This is the French translation. [English version](../agent-construction.md).
|
|
2
|
+
|
|
3
|
+
# Compétence Construction d'Agents
|
|
4
|
+
|
|
5
|
+
## Quand activer
|
|
6
|
+
- Concevoir un système multi-agents avec Claude (orchestrateur + sous-agents)
|
|
7
|
+
- Construire un agent alimenté par Claude qui utilise des outils sur plusieurs tours
|
|
8
|
+
- Concevoir la mémoire pour un agent long-running (en contexte vs. externe)
|
|
9
|
+
- Gérer les erreurs, les réessais et les conditions d'arrêt des agents
|
|
10
|
+
- Implémenter les transferts d'agent entre sous-agents spécialisés
|
|
11
|
+
|
|
12
|
+
## Quand NE PAS utiliser
|
|
13
|
+
- Appels API Claude à tour unique — la compétence API Claude est suffisante
|
|
14
|
+
- Chatbots simples sans utilisation d'outils ou prise de décision autonome
|
|
15
|
+
- Abstractions LangChain/LlamaIndex — adresser la couche d'abstraction directement
|
|
16
|
+
|
|
17
|
+
## Instructions
|
|
18
|
+
|
|
19
|
+
### Patterns d'architecture d'agent
|
|
20
|
+
|
|
21
|
+
**Agent unique avec outils** — une instance Claude, plusieurs outils, boucle jusqu'à l'achèvement de la tâche :
|
|
22
|
+
```
|
|
23
|
+
User → Agent → [Tool A] → [Tool B] → Agent → User
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Orchestrateur + sous-agents** — un parent crée des enfants spécialisés :
|
|
27
|
+
```
|
|
28
|
+
User → Orchestrator → [ResearchAgent] → [WriterAgent] → Orchestrator → User
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Pipeline** — les agents transmettent les résultats en séquence :
|
|
32
|
+
```
|
|
33
|
+
User → Agent1(classify) → Agent2(extract) → Agent3(generate) → User
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Choisir l'architecture la plus simple qui résout le problème. Un agent unique avec des outils gère la plupart des cas.
|
|
37
|
+
|
|
38
|
+
### Conception des outils
|
|
39
|
+
```python
|
|
40
|
+
# Définitions d'outils pour la boucle d'agent multi-tours
|
|
41
|
+
tools = [
|
|
42
|
+
{
|
|
43
|
+
"name": "search_web",
|
|
44
|
+
"description": "Search the web for current information. Use when you need facts not in your training data.",
|
|
45
|
+
"input_schema": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"properties": {
|
|
48
|
+
"query": {"type": "string", "description": "Search query"}
|
|
49
|
+
},
|
|
50
|
+
"required": ["query"]
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "read_file",
|
|
55
|
+
"description": "Read contents of a file by path.",
|
|
56
|
+
"input_schema": {
|
|
57
|
+
"type": "object",
|
|
58
|
+
"properties": {
|
|
59
|
+
"path": {"type": "string", "description": "Absolute file path"}
|
|
60
|
+
},
|
|
61
|
+
"required": ["path"]
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "write_file",
|
|
66
|
+
"description": "Write content to a file. Creates the file if it doesn't exist.",
|
|
67
|
+
"input_schema": {
|
|
68
|
+
"type": "object",
|
|
69
|
+
"properties": {
|
|
70
|
+
"path": {"type": "string"},
|
|
71
|
+
"content": {"type": "string"}
|
|
72
|
+
},
|
|
73
|
+
"required": ["path", "content"]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Règles de conception des outils :
|
|
80
|
+
- La description doit dire à Claude QUAND l'utiliser, pas seulement ce qu'il fait
|
|
81
|
+
- Garder `input_schema` minimal — uniquement les champs requis, pas de bruit optionnel
|
|
82
|
+
- Retourner des données structurées (JSON), pas de prose, pour que Claude puisse les utiliser de façon fiable
|
|
83
|
+
- Un outil par action — ne pas regrouper lecture+écriture dans un seul outil
|
|
84
|
+
|
|
85
|
+
### Boucle d'agent
|
|
86
|
+
```python
|
|
87
|
+
import anthropic
|
|
88
|
+
import json
|
|
89
|
+
|
|
90
|
+
client = anthropic.Anthropic()
|
|
91
|
+
|
|
92
|
+
def run_agent(task: str, max_iterations: int = 20) -> str:
|
|
93
|
+
messages = [{"role": "user", "content": task}]
|
|
94
|
+
|
|
95
|
+
for iteration in range(max_iterations):
|
|
96
|
+
response = client.messages.create(
|
|
97
|
+
model="claude-sonnet-4-6",
|
|
98
|
+
max_tokens=4096,
|
|
99
|
+
system=AGENT_SYSTEM_PROMPT,
|
|
100
|
+
tools=tools,
|
|
101
|
+
messages=messages,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Ajouter la réponse de l'assistant
|
|
105
|
+
messages.append({"role": "assistant", "content": response.content})
|
|
106
|
+
|
|
107
|
+
if response.stop_reason == "end_turn":
|
|
108
|
+
# Extraire la réponse textuelle finale
|
|
109
|
+
return next(b.text for b in response.content if hasattr(b, "text"))
|
|
110
|
+
|
|
111
|
+
if response.stop_reason == "tool_use":
|
|
112
|
+
# Exécuter tous les appels d'outils dans cette réponse
|
|
113
|
+
tool_results = []
|
|
114
|
+
for block in response.content:
|
|
115
|
+
if block.type == "tool_use":
|
|
116
|
+
result = execute_tool(block.name, block.input)
|
|
117
|
+
tool_results.append({
|
|
118
|
+
"type": "tool_result",
|
|
119
|
+
"tool_use_id": block.id,
|
|
120
|
+
"content": json.dumps(result) if not isinstance(result, str) else result
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
messages.append({"role": "user", "content": tool_results})
|
|
124
|
+
else:
|
|
125
|
+
# Raison d'arrêt inattendue
|
|
126
|
+
break
|
|
127
|
+
|
|
128
|
+
raise RuntimeError(f"Agent exceeded {max_iterations} iterations without completing")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def execute_tool(name: str, inputs: dict) -> any:
|
|
132
|
+
match name:
|
|
133
|
+
case "search_web":
|
|
134
|
+
return search(inputs["query"])
|
|
135
|
+
case "read_file":
|
|
136
|
+
return Path(inputs["path"]).read_text()
|
|
137
|
+
case "write_file":
|
|
138
|
+
Path(inputs["path"]).write_text(inputs["content"])
|
|
139
|
+
return {"success": True, "path": inputs["path"]}
|
|
140
|
+
case _:
|
|
141
|
+
return {"error": f"Unknown tool: {name}"}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### System prompt pour les agents
|
|
145
|
+
```
|
|
146
|
+
AGENT_SYSTEM_PROMPT = """You are an autonomous agent completing tasks step by step.
|
|
147
|
+
|
|
148
|
+
Approach:
|
|
149
|
+
1. Analyze the task before acting
|
|
150
|
+
2. Use the minimum tools necessary
|
|
151
|
+
3. Check your work before declaring done
|
|
152
|
+
4. If a tool returns an error, diagnose and retry once — if it fails again, report the error
|
|
153
|
+
|
|
154
|
+
Stopping conditions — declare "DONE: <result>" when:
|
|
155
|
+
- The task is fully complete
|
|
156
|
+
- You've hit an unrecoverable error after retrying
|
|
157
|
+
- You've been asked to do something harmful or impossible
|
|
158
|
+
|
|
159
|
+
Never loop more than 3 times on the same tool call with the same inputs.
|
|
160
|
+
"""
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Patterns de mémoire
|
|
164
|
+
|
|
165
|
+
**Mémoire en contexte** (tableau de messages) — pour une seule session, petit état :
|
|
166
|
+
```python
|
|
167
|
+
# Résumer quand le contexte devient trop grand
|
|
168
|
+
if count_tokens(messages) > 150_000:
|
|
169
|
+
summary = summarize_messages(messages[:-5]) # garder les 5 derniers tours
|
|
170
|
+
messages = [
|
|
171
|
+
{"role": "user", "content": f"[Previous context summary]\n{summary}"},
|
|
172
|
+
{"role": "assistant", "content": "Understood. Continuing from where we left off."},
|
|
173
|
+
*messages[-5:]
|
|
174
|
+
]
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Mémoire externe** (pour les agents multi-sessions) :
|
|
178
|
+
```python
|
|
179
|
+
# Mémoire simple basée sur des fichiers
|
|
180
|
+
class AgentMemory:
|
|
181
|
+
def __init__(self, path: str):
|
|
182
|
+
self.path = Path(path)
|
|
183
|
+
self.data = json.loads(self.path.read_text()) if self.path.exists() else {}
|
|
184
|
+
|
|
185
|
+
def remember(self, key: str, value: any):
|
|
186
|
+
self.data[key] = {"value": value, "timestamp": datetime.utcnow().isoformat()}
|
|
187
|
+
self.path.write_text(json.dumps(self.data, indent=2))
|
|
188
|
+
|
|
189
|
+
def recall(self, key: str) -> any:
|
|
190
|
+
entry = self.data.get(key)
|
|
191
|
+
return entry["value"] if entry else None
|
|
192
|
+
|
|
193
|
+
def as_context(self) -> str:
|
|
194
|
+
if not self.data:
|
|
195
|
+
return ""
|
|
196
|
+
lines = [f"- {k}: {v['value']}" for k, v in self.data.items()]
|
|
197
|
+
return "Known context:\n" + "\n".join(lines)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Pattern d'orchestration
|
|
201
|
+
```python
|
|
202
|
+
def orchestrate(task: str) -> str:
|
|
203
|
+
# Étape 1 : L'agent de planification décompose la tâche
|
|
204
|
+
plan = run_subagent(
|
|
205
|
+
model="claude-sonnet-4-6",
|
|
206
|
+
system="You are a planner. Decompose tasks into numbered steps.",
|
|
207
|
+
task=f"Decompose this task into steps: {task}",
|
|
208
|
+
tools=[] # Pas d'outils nécessaires pour la planification
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
# Étape 2 : Exécuter chaque étape avec des agents spécialisés
|
|
212
|
+
results = []
|
|
213
|
+
for step in parse_steps(plan):
|
|
214
|
+
agent_type = classify_step(step) # "research" | "code" | "write"
|
|
215
|
+
result = run_subagent(
|
|
216
|
+
model=agent_model(agent_type),
|
|
217
|
+
system=agent_system_prompt(agent_type),
|
|
218
|
+
task=step,
|
|
219
|
+
tools=agent_tools(agent_type),
|
|
220
|
+
context="\n".join(results) # Donner le contexte des étapes précédentes
|
|
221
|
+
)
|
|
222
|
+
results.append(f"Step result: {result}")
|
|
223
|
+
|
|
224
|
+
# Étape 3 : L'agent de synthèse combine les résultats
|
|
225
|
+
return run_subagent(
|
|
226
|
+
model="claude-sonnet-4-6",
|
|
227
|
+
system="You are a synthesizer. Combine step results into a final answer.",
|
|
228
|
+
task=f"Original task: {task}\n\nStep results:\n" + "\n".join(results),
|
|
229
|
+
tools=[]
|
|
230
|
+
)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Gestion des erreurs et conditions d'arrêt
|
|
234
|
+
```python
|
|
235
|
+
class AgentError(Exception):
|
|
236
|
+
pass
|
|
237
|
+
|
|
238
|
+
class MaxIterationsError(AgentError):
|
|
239
|
+
pass
|
|
240
|
+
|
|
241
|
+
class ToolFailureError(AgentError):
|
|
242
|
+
pass
|
|
243
|
+
|
|
244
|
+
def execute_tool_safe(name: str, inputs: dict, consecutive_failures: dict) -> dict:
|
|
245
|
+
try:
|
|
246
|
+
result = execute_tool(name, inputs)
|
|
247
|
+
consecutive_failures[name] = 0
|
|
248
|
+
return {"success": True, "result": result}
|
|
249
|
+
except Exception as e:
|
|
250
|
+
consecutive_failures[name] = consecutive_failures.get(name, 0) + 1
|
|
251
|
+
if consecutive_failures[name] >= 3:
|
|
252
|
+
raise ToolFailureError(f"Tool {name} failed 3 consecutive times: {e}")
|
|
253
|
+
return {"success": False, "error": str(e), "retry": True}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Pattern de transfert
|
|
257
|
+
```python
|
|
258
|
+
# L'agent parent passe le contexte explicitement — les sous-agents n'ont pas de mémoire de session
|
|
259
|
+
def handoff_to_specialist(context: dict, task: str, specialist: str) -> str:
|
|
260
|
+
handoff_prompt = f"""
|
|
261
|
+
Context from orchestrator:
|
|
262
|
+
{json.dumps(context, indent=2)}
|
|
263
|
+
|
|
264
|
+
Your task:
|
|
265
|
+
{task}
|
|
266
|
+
"""
|
|
267
|
+
return run_subagent(
|
|
268
|
+
system=SPECIALIST_PROMPTS[specialist],
|
|
269
|
+
task=handoff_prompt,
|
|
270
|
+
tools=SPECIALIST_TOOLS[specialist]
|
|
271
|
+
)
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Exemple
|
|
275
|
+
|
|
276
|
+
**Utilisateur :** Construire un agent de recherche qui prend un sujet, recherche sur le web 3 sources, lit chaque URL et rédige un résumé de 500 mots avec citations dans un fichier.
|
|
277
|
+
|
|
278
|
+
**Sortie attendue :**
|
|
279
|
+
- Liste `tools` : `search_web`, `fetch_url`, `write_file`
|
|
280
|
+
- System prompt : demande à l'agent de chercher → récupérer 3 URLs → synthétiser → écrire le fichier avant de déclarer terminé
|
|
281
|
+
- Boucle `run_agent(task)` avec `max_iterations=15`
|
|
282
|
+
- Gestion des erreurs : si `fetch_url` échoue, essayer le prochain résultat de recherche
|
|
283
|
+
- Sortie finale : chemin vers le fichier de résumé écrit
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
> **Travaillez avec nous :** Claudient est soutenu par [Uitbreiden](https://uitbreiden.com/) — nous construisons des produits IA et des solutions B2B avec des communautés de développeurs. [uitbreiden.com](https://uitbreiden.com/)
|