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
|
+
> 🇫🇷 This is the French translation. [English version](../claude-api.md).
|
|
2
|
+
|
|
3
|
+
# Compétence API Claude
|
|
4
|
+
|
|
5
|
+
## Quand activer
|
|
6
|
+
- Rédiger du code qui appelle l'API Claude Anthropic (SDK Python ou TypeScript)
|
|
7
|
+
- Implémenter le prompt caching, le streaming ou le traitement par lots
|
|
8
|
+
- Concevoir la gestion des conversations multi-tours
|
|
9
|
+
- Sélectionner le bon modèle Claude (Haiku, Sonnet, Opus) pour une tâche
|
|
10
|
+
- Ajouter l'utilisation d'outils / function calling à une intégration Claude
|
|
11
|
+
- Optimiser le coût ou la latence dans une application Claude de production
|
|
12
|
+
|
|
13
|
+
## Quand NE PAS utiliser
|
|
14
|
+
- APIs OpenAI ou autres fournisseurs — SDK différent, patterns différents
|
|
15
|
+
- Conseils génériques sur les LLM sans rapport avec l'API Anthropic
|
|
16
|
+
- Projets utilisant déjà des abstractions LangChain ou LlamaIndex — adresser la couche d'abstraction à la place
|
|
17
|
+
|
|
18
|
+
## Instructions
|
|
19
|
+
|
|
20
|
+
### Guide de sélection du modèle
|
|
21
|
+
| Modèle | Utiliser quand | Éviter quand |
|
|
22
|
+
|--------|---------------|--------------|
|
|
23
|
+
| `claude-haiku-4-5-20251001` | Classification, extraction, routage, Q&R simple, haut volume faible coût | Raisonnement complexe, génération de code multi-étapes |
|
|
24
|
+
| `claude-sonnet-4-6` | Usage général : code, analyse, rédaction, workflows agentiques | Budgets token contraints à très grande échelle |
|
|
25
|
+
| `claude-opus-4-7` | Raisonnement expert, jugement nuancé, longues formes complexes | La plupart des tâches — Sonnet est généralement suffisant |
|
|
26
|
+
|
|
27
|
+
### Appel de message basique (Python)
|
|
28
|
+
```python
|
|
29
|
+
import anthropic
|
|
30
|
+
|
|
31
|
+
client = anthropic.Anthropic() # lit ANTHROPIC_API_KEY depuis l'env
|
|
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
|
+
### Prompt caching (critique pour le coût)
|
|
45
|
+
Le prompt caching peut réduire les coûts jusqu'à 90% pour les contextes répétés. Mettre en cache le contenu stable (system prompts, grands documents, exemples 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"} # Mettre ce bloc en cache
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
messages=[
|
|
59
|
+
{
|
|
60
|
+
"role": "user",
|
|
61
|
+
"content": [
|
|
62
|
+
{
|
|
63
|
+
"type": "text",
|
|
64
|
+
"text": large_document,
|
|
65
|
+
"cache_control": {"type": "ephemeral"} # Mettre le document en cache aussi
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"type": "text",
|
|
69
|
+
"text": "Summarize the key points."
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
)
|
|
75
|
+
# Vérifier l'utilisation du cache dans la réponse
|
|
76
|
+
print(message.usage.cache_read_input_tokens) # tokens lus depuis le cache
|
|
77
|
+
print(message.usage.cache_creation_input_tokens) # tokens écrits dans le cache
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Règles du cache :
|
|
81
|
+
- Bloc minimum cacheable : 1024 tokens (Sonnet/Opus), 2048 tokens (Haiku)
|
|
82
|
+
- TTL du cache : 5 minutes
|
|
83
|
+
- Seul le dernier bloc `cache_control` dans un tableau de messages compte — les points de cache sont cumulatifs
|
|
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
|
+
# Ou avec des événements :
|
|
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() # retour à la ligne quand c'est terminé
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Utilisation d'outils
|
|
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
|
+
# Vérifier si Claude veut utiliser un outil
|
|
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
|
+
# Continuer la conversation avec le résultat de l'outil
|
|
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
|
+
### Conversation multi-tours
|
|
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
|
+
### Traitement par lots
|
|
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
|
+
# Interroger pour les résultats (ou utiliser des 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
|
+
### Gestion des erreurs et réessais
|
|
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
|
+
### Liste de contrôle d'optimisation des coûts
|
|
230
|
+
- Utiliser Haiku pour la classification, le routage et les tâches d'extraction simples
|
|
231
|
+
- Activer le prompt caching pour tout system prompt > 1024 tokens
|
|
232
|
+
- Utiliser l'API batch pour les workloads offline/async — réduction des coûts de 50%
|
|
233
|
+
- Définir `max_tokens` au minimum nécessaire — vous payez pour les tokens de sortie générés
|
|
234
|
+
- Mettre en cache les grands documents dans le message utilisateur, pas seulement dans le system prompt
|
|
235
|
+
- Surveiller le ratio `cache_read_input_tokens` vs `input_tokens` — viser >80% pour les contextes stables
|
|
236
|
+
|
|
237
|
+
## Exemple
|
|
238
|
+
|
|
239
|
+
**Utilisateur :** Construire une classe Python qui classe des tickets de support client dans des catégories avec Claude, avec prompt caching pour la liste des catégories et streaming pour l'explication.
|
|
240
|
+
|
|
241
|
+
**Sortie attendue :**
|
|
242
|
+
- Classe `TicketClassifier` avec `ANTHROPIC_API_KEY` depuis l'env
|
|
243
|
+
- System prompt avec toutes les catégories en cache via `cache_control: ephemeral`
|
|
244
|
+
- `classify(ticket_text)` → retourne `{category: str, confidence: str}` parsé depuis la sortie structurée
|
|
245
|
+
- `classify_and_explain(ticket_text)` → streame l'explication vers stdout
|
|
246
|
+
- Utilise `claude-haiku-4-5-20251001` pour la classification (économique), `claude-sonnet-4-6` pour l'explication
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
> **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/)
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
> 🇳🇱 Dit is de Nederlandse vertaling. [Engelse versie](../agent-construction.md).
|
|
2
|
+
|
|
3
|
+
# Agent Construction Skill
|
|
4
|
+
|
|
5
|
+
## Wanneer te activeren
|
|
6
|
+
- Een multi-agent systeem ontwerpen met Claude (orchestrator + subagenten)
|
|
7
|
+
- Een Claude-aangedreven agent bouwen die tools gebruikt over meerdere beurten
|
|
8
|
+
- Geheugen ontwerpen voor een langlopende agent (in-context vs. extern)
|
|
9
|
+
- Agentfouten, herhaalpogingen en stopomstandigheden afhandelen
|
|
10
|
+
- Agent-overdrachten implementeren tussen gespecialiseerde subagenten
|
|
11
|
+
|
|
12
|
+
## Wanneer NIET te gebruiken
|
|
13
|
+
- Enkelvoudige Claude API-aanroepen — de Claude API skill is voldoende
|
|
14
|
+
- Eenvoudige chatbots zonder toolgebruik of autonome besluitvorming
|
|
15
|
+
- LangChain/LlamaIndex-abstracties — adresseer de abstractielaag direct
|
|
16
|
+
|
|
17
|
+
## Instructies
|
|
18
|
+
|
|
19
|
+
### Agent-architectuurpatronen
|
|
20
|
+
|
|
21
|
+
**Enkele agent met tools** — één Claude-instantie, meerdere tools, loopt totdat taak is voltooid:
|
|
22
|
+
```
|
|
23
|
+
Gebruiker → Agent → [Tool A] → [Tool B] → Agent → Gebruiker
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Orchestrator + subagenten** — één ouder verwekt gespecialiseerde kinderen:
|
|
27
|
+
```
|
|
28
|
+
Gebruiker → Orchestrator → [ResearchAgent] → [WriterAgent] → Orchestrator → Gebruiker
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Pipeline** — agenten geven resultaten door in volgorde:
|
|
32
|
+
```
|
|
33
|
+
Gebruiker → Agent1(classificeer) → Agent2(extraheer) → Agent3(genereer) → Gebruiker
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Kies de eenvoudigste architectuur die het probleem oplost. Enkele agent met tools handelt de meeste gevallen af.
|
|
37
|
+
|
|
38
|
+
### Tool-ontwerp
|
|
39
|
+
```python
|
|
40
|
+
# Tool-definities voor multi-beurt agent-loop
|
|
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
|
+
Tool-ontwerpregels:
|
|
80
|
+
- Beschrijving moet Claude vertellen WANNEER het te gebruiken, niet alleen wat het doet
|
|
81
|
+
- Houd `input_schema` minimaal — alleen vereiste velden, geen optionele ruis
|
|
82
|
+
- Retourneer gestructureerde data (JSON), geen proza, zodat Claude het betrouwbaar kan gebruiken
|
|
83
|
+
- Één tool per actie — bundel lezen+schrijven niet in één tool
|
|
84
|
+
|
|
85
|
+
### Agent-loop
|
|
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
|
+
# Voeg het antwoord van de assistent toe
|
|
105
|
+
messages.append({"role": "assistant", "content": response.content})
|
|
106
|
+
|
|
107
|
+
if response.stop_reason == "end_turn":
|
|
108
|
+
# Extraheer definitief tekstantwoord
|
|
109
|
+
return next(b.text for b in response.content if hasattr(b, "text"))
|
|
110
|
+
|
|
111
|
+
if response.stop_reason == "tool_use":
|
|
112
|
+
# Voer alle tool-aanroepen in dit antwoord uit
|
|
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
|
+
# Onverwachte stopreden
|
|
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
|
+
### Systeemprompt voor agenten
|
|
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
|
+
### Geheugenpatronen
|
|
164
|
+
|
|
165
|
+
**In-context geheugen** (berichtarray) — voor enkele sessie, kleine state:
|
|
166
|
+
```python
|
|
167
|
+
# Samenvatten wanneer context te groot wordt
|
|
168
|
+
if count_tokens(messages) > 150_000:
|
|
169
|
+
summary = summarize_messages(messages[:-5]) # bewaar laatste 5 beurten
|
|
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
|
+
**Extern geheugen** (voor multi-sessie agenten):
|
|
178
|
+
```python
|
|
179
|
+
# Eenvoudig bestandsgebaseerd geheugen
|
|
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
|
+
### Orchestratorpatroon
|
|
201
|
+
```python
|
|
202
|
+
def orchestrate(task: str) -> str:
|
|
203
|
+
# Stap 1: Planning-agent decomponeert de taak
|
|
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=[] # Geen tools nodig voor planning
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
# Stap 2: Voer elke stap uit met gespecialiseerde agenten
|
|
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) # Geef context van vorige stappen
|
|
221
|
+
)
|
|
222
|
+
results.append(f"Step result: {result}")
|
|
223
|
+
|
|
224
|
+
# Stap 3: Synthese-agent combineert resultaten
|
|
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
|
+
### Foutafhandeling en stopomstandigheden
|
|
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
|
+
### Overdrachtspatroon
|
|
257
|
+
```python
|
|
258
|
+
# Ouderagent geeft context expliciet door — subagenten hebben geen sessieheugen
|
|
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
|
+
## Voorbeeld
|
|
275
|
+
|
|
276
|
+
**Gebruiker:** Bouw een onderzoeksagent die een onderwerp neemt, het web doorzoekt op 3 bronnen, elke URL leest en een samenvatting van 500 woorden met citaten naar een bestand schrijft.
|
|
277
|
+
|
|
278
|
+
**Verwachte output:**
|
|
279
|
+
- `tools`-lijst: `search_web`, `fetch_url`, `write_file`
|
|
280
|
+
- Systeemprompt: instrueert agent om te zoeken → 3 URL's op te halen → samen te vatten → bestand te schrijven voor klaar te melden
|
|
281
|
+
- `run_agent(task)`-loop met `max_iterations=15`
|
|
282
|
+
- Foutafhandeling: als `fetch_url` mislukt, probeer volgend zoekresultaat
|
|
283
|
+
- Definitieve output: pad naar het geschreven samenvattingsbestand
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
> **Werk met ons:** Claudient wordt ondersteund door [Uitbreiden](https://uitbreiden.com/) — we bouwen AI-producten en B2B-oplossingen met ontwikkelaarsgemeenschappen. [uitbreiden.com](https://uitbreiden.com/)
|