@luanpdd/kit-mcp 1.29.0 → 1.30.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/LICENSE +21 -21
- package/README.md +168 -168
- package/gates/agent-no-recursive-dispatch.md +82 -82
- package/kit/COMANDOS.md +138 -138
- package/kit/README.md +76 -76
- package/kit/agents/advisor-researcher.md +106 -106
- package/kit/agents/assumptions-analyzer.md +107 -107
- package/kit/agents/audit-log-implementer.md +313 -313
- package/kit/agents/auditor-consistencia-isolamento.md +413 -413
- package/kit/agents/b2b-saas-architect.md +156 -156
- package/kit/agents/cascading-failures-auditor.md +298 -298
- package/kit/agents/codebase-mapper.md +768 -768
- package/kit/agents/crm-pipeline-implementer.md +256 -256
- package/kit/agents/debugger.md +813 -813
- package/kit/agents/detector-tenant-quente.md +337 -337
- package/kit/agents/evolution-go-integrator.md +200 -200
- package/kit/agents/example-reviewer.md +21 -21
- package/kit/agents/executor.md +564 -564
- package/kit/agents/integration-checker.md +200 -200
- package/kit/agents/invite-flow-implementer.md +189 -189
- package/kit/agents/legacy-characterizer.md +368 -368
- package/kit/agents/lgpd-compliance-auditor.md +295 -295
- package/kit/agents/multi-tenant-isolation-auditor.md +253 -253
- package/kit/agents/multi-tenant-rls-writer.md +340 -340
- package/kit/agents/nyquist-auditor.md +178 -178
- package/kit/agents/observability-coverage-auditor.md +315 -315
- package/kit/agents/org-onboarding-implementer.md +223 -223
- package/kit/agents/payload-capture-instrumenter.md +273 -273
- package/kit/agents/phase-researcher.md +696 -696
- package/kit/agents/plan-checker.md +272 -272
- package/kit/agents/planner.md +922 -922
- package/kit/agents/project-researcher.md +652 -652
- package/kit/agents/refactor-safety-auditor.md +404 -404
- package/kit/agents/research-synthesizer.md +245 -245
- package/kit/agents/roadmapper.md +677 -677
- package/kit/agents/seam-finder.md +359 -359
- package/kit/agents/shotgun-surgery-detector.md +349 -349
- package/kit/agents/supabase-branching-architect.md +562 -562
- package/kit/agents/supabase-cicd-pipeline-implementer.md +777 -777
- package/kit/agents/supabase-column-privileges-writer.md +399 -399
- package/kit/agents/supabase-edge-fn-tester.md +287 -0
- package/kit/agents/supabase-edge-fn-writer.md +239 -210
- package/kit/agents/supabase-migration-writer.md +385 -385
- package/kit/agents/supabase-rbac-implementer.md +392 -392
- package/kit/agents/supabase-realtime-implementer.md +363 -267
- package/kit/agents/supabase-rls-hardener.md +521 -521
- package/kit/agents/supabase-rls-writer.md +323 -323
- package/kit/agents/supabase-roles-implementer.md +355 -355
- package/kit/agents/super-admin-implementer.md +281 -281
- package/kit/agents/ui-auditor.md +437 -437
- package/kit/agents/ui-checker.md +302 -302
- package/kit/agents/ui-researcher.md +355 -355
- package/kit/agents/user-profiler.md +175 -175
- package/kit/agents/validador-evolucao-schema.md +335 -335
- package/kit/agents/verifier.md +728 -728
- package/kit/commands/adicionar-backlog.md +75 -75
- package/kit/commands/adicionar-fase.md +42 -42
- package/kit/commands/adicionar-tarefa.md +45 -45
- package/kit/commands/adicionar-testes.md +41 -41
- package/kit/commands/ajuda.md +21 -21
- package/kit/commands/atualizar.md +37 -37
- package/kit/commands/auditar-cascading.md +111 -111
- package/kit/commands/auditar-marco.md +179 -179
- package/kit/commands/auditar-observabilidade-cobertura.md +183 -183
- package/kit/commands/auditar-refactor.md +219 -219
- package/kit/commands/auditar-release.md +109 -109
- package/kit/commands/auditar-uat.md +23 -23
- package/kit/commands/autonomo.md +40 -40
- package/kit/commands/branch-pr.md +24 -24
- package/kit/commands/burn-rate-status.md +408 -408
- package/kit/commands/capturar-payloads.md +193 -193
- package/kit/commands/caracterizar.md +212 -212
- package/kit/commands/concluir-marco.md +247 -247
- package/kit/commands/configuracoes.md +36 -36
- package/kit/commands/dados-distribuidos.md +188 -188
- package/kit/commands/definir-perfil.md +10 -10
- package/kit/commands/depurar.md +190 -190
- package/kit/commands/detectar-duplicacao.md +197 -197
- package/kit/commands/discutir-fase.md +131 -131
- package/kit/commands/encontrar-seams.md +136 -136
- package/kit/commands/entrar-discord.md +17 -17
- package/kit/commands/estatisticas.md +18 -18
- package/kit/commands/example-greeting.md +33 -33
- package/kit/commands/executar-fase.md +58 -58
- package/kit/commands/expresso.md +56 -56
- package/kit/commands/fase-ui.md +34 -34
- package/kit/commands/fazer.md +57 -57
- package/kit/commands/fio.md +125 -125
- package/kit/commands/fluxos-trabalho.md +64 -64
- package/kit/commands/forense.md +176 -176
- package/kit/commands/gerenciador.md +38 -38
- package/kit/commands/inserir-fase.md +31 -31
- package/kit/commands/legacy.md +263 -263
- package/kit/commands/limpeza.md +17 -17
- package/kit/commands/listar-hipoteses-fase.md +45 -45
- package/kit/commands/listar-workspaces.md +18 -18
- package/kit/commands/load-shedding.md +117 -117
- package/kit/commands/mapear-codebase.md +70 -70
- package/kit/commands/multi-tenant.md +163 -163
- package/kit/commands/nota.md +33 -33
- package/kit/commands/novo-marco.md +43 -43
- package/kit/commands/novo-projeto.md +41 -41
- package/kit/commands/novo-workspace.md +43 -43
- package/kit/commands/pausar-trabalho.md +37 -37
- package/kit/commands/perfil-usuario.md +45 -45
- package/kit/commands/pesquisar-fase.md +195 -195
- package/kit/commands/planejar-fase.md +67 -67
- package/kit/commands/planejar-lacunas.md +33 -33
- package/kit/commands/plantar-ideia.md +25 -25
- package/kit/commands/progresso.md +24 -24
- package/kit/commands/proximo.md +30 -30
- package/kit/commands/publicar.md +490 -490
- package/kit/commands/rapido.md +35 -35
- package/kit/commands/reaplicar-patches.md +124 -124
- package/kit/commands/refactor-seguro.md +321 -321
- package/kit/commands/relatorio-sessao.md +19 -19
- package/kit/commands/remover-fase.md +31 -31
- package/kit/commands/remover-workspace.md +26 -26
- package/kit/commands/resumo-marco.md +50 -50
- package/kit/commands/retomar-trabalho.md +40 -40
- package/kit/commands/revisar-backlog.md +60 -60
- package/kit/commands/revisar-ui.md +32 -32
- package/kit/commands/revisar.md +37 -37
- package/kit/commands/saude.md +21 -21
- package/kit/commands/setup-notion.md +93 -93
- package/kit/commands/storytelling.md +179 -179
- package/kit/commands/supabase.md +30 -7
- package/kit/commands/sync-main.md +68 -68
- package/kit/commands/validar-fase.md +35 -35
- package/kit/commands/verificar-tarefas.md +44 -44
- package/kit/commands/verificar-trabalho.md +64 -64
- package/kit/file-manifest.json +14 -8
- package/kit/framework/bin/lib/commands.cjs +959 -959
- package/kit/framework/bin/lib/config.cjs +442 -442
- package/kit/framework/bin/lib/core.cjs +1230 -1230
- package/kit/framework/bin/lib/frontmatter.cjs +336 -336
- package/kit/framework/bin/lib/init.cjs +1442 -1442
- package/kit/framework/bin/lib/milestone.cjs +252 -252
- package/kit/framework/bin/lib/model-profiles.cjs +68 -68
- package/kit/framework/bin/lib/phase.cjs +888 -888
- package/kit/framework/bin/lib/profile-output.cjs +952 -952
- package/kit/framework/bin/lib/profile-pipeline.cjs +539 -539
- package/kit/framework/bin/lib/roadmap.cjs +329 -329
- package/kit/framework/bin/lib/security.cjs +382 -382
- package/kit/framework/bin/lib/state.cjs +1031 -1031
- package/kit/framework/bin/lib/template.cjs +222 -222
- package/kit/framework/bin/lib/uat.cjs +282 -282
- package/kit/framework/bin/lib/verify.cjs +888 -888
- package/kit/framework/bin/lib/workstream.cjs +491 -491
- package/kit/framework/bin/tools.cjs +918 -918
- package/kit/framework/commands/workstreams.md +63 -63
- package/kit/framework/references/checkpoints.md +778 -778
- package/kit/framework/references/continuation-format.md +249 -249
- package/kit/framework/references/decimal-phase-calculation.md +64 -64
- package/kit/framework/references/git-integration.md +295 -295
- package/kit/framework/references/git-planning-commit.md +38 -38
- package/kit/framework/references/model-profile-resolution.md +36 -36
- package/kit/framework/references/model-profiles.md +139 -139
- package/kit/framework/references/phase-argument-parsing.md +61 -61
- package/kit/framework/references/planning-config.md +202 -202
- package/kit/framework/references/questioning.md +162 -162
- package/kit/framework/references/tdd.md +263 -263
- package/kit/framework/references/ui-brand.md +160 -160
- package/kit/framework/references/user-profiling.md +657 -657
- package/kit/framework/references/verification-patterns.md +612 -612
- package/kit/framework/references/workstream-flag.md +58 -58
- package/kit/framework/templates/DEBUG.md +164 -164
- package/kit/framework/templates/UAT.md +265 -265
- package/kit/framework/templates/UI-SPEC.md +100 -100
- package/kit/framework/templates/VALIDATION.md +76 -76
- package/kit/framework/templates/claude-md.md +122 -122
- package/kit/framework/templates/codebase/architecture.md +185 -185
- package/kit/framework/templates/codebase/concerns.md +205 -205
- package/kit/framework/templates/codebase/conventions.md +204 -204
- package/kit/framework/templates/codebase/integrations.md +192 -192
- package/kit/framework/templates/codebase/stack.md +158 -158
- package/kit/framework/templates/codebase/structure.md +199 -199
- package/kit/framework/templates/codebase/testing.md +301 -301
- package/kit/framework/templates/config.json +44 -44
- package/kit/framework/templates/context.md +352 -352
- package/kit/framework/templates/continue-here.md +78 -78
- package/kit/framework/templates/copilot-instructions.md +7 -7
- package/kit/framework/templates/debug-subagent-prompt.md +91 -91
- package/kit/framework/templates/dev-preferences.md +20 -20
- package/kit/framework/templates/discovery.md +146 -146
- package/kit/framework/templates/discussion-log.md +63 -63
- package/kit/framework/templates/milestone-archive.md +123 -123
- package/kit/framework/templates/milestone.md +115 -115
- package/kit/framework/templates/phase-prompt.md +610 -610
- package/kit/framework/templates/planner-subagent-prompt.md +117 -117
- package/kit/framework/templates/project.md +186 -186
- package/kit/framework/templates/requirements.md +231 -231
- package/kit/framework/templates/research-project/ARCHITECTURE.md +204 -204
- package/kit/framework/templates/research-project/FEATURES.md +147 -147
- package/kit/framework/templates/research-project/PITFALLS.md +200 -200
- package/kit/framework/templates/research-project/STACK.md +120 -120
- package/kit/framework/templates/research-project/SUMMARY.md +170 -170
- package/kit/framework/templates/research.md +419 -419
- package/kit/framework/templates/retrospective.md +54 -54
- package/kit/framework/templates/roadmap.md +202 -202
- package/kit/framework/templates/state.md +176 -176
- package/kit/framework/templates/summary-complex.md +59 -59
- package/kit/framework/templates/summary-minimal.md +41 -41
- package/kit/framework/templates/summary-standard.md +48 -48
- package/kit/framework/templates/summary.md +209 -209
- package/kit/framework/templates/user-profile.md +146 -146
- package/kit/framework/templates/user-setup.md +256 -256
- package/kit/framework/templates/verification-report.md +258 -258
- package/kit/framework/workflows/add-phase.md +112 -112
- package/kit/framework/workflows/add-tests.md +351 -351
- package/kit/framework/workflows/add-todo.md +158 -158
- package/kit/framework/workflows/audit-milestone.md +340 -340
- package/kit/framework/workflows/audit-uat.md +109 -109
- package/kit/framework/workflows/autonomous.md +891 -891
- package/kit/framework/workflows/check-todos.md +177 -177
- package/kit/framework/workflows/cleanup.md +152 -152
- package/kit/framework/workflows/complete-milestone.md +696 -696
- package/kit/framework/workflows/diagnose-issues.md +231 -231
- package/kit/framework/workflows/discovery-phase.md +289 -289
- package/kit/framework/workflows/discuss-phase-assumptions.md +653 -653
- package/kit/framework/workflows/discuss-phase.md +784 -784
- package/kit/framework/workflows/do.md +104 -104
- package/kit/framework/workflows/execute-phase.md +838 -838
- package/kit/framework/workflows/execute-plan.md +510 -510
- package/kit/framework/workflows/fast.md +102 -102
- package/kit/framework/workflows/forensics.md +265 -265
- package/kit/framework/workflows/health.md +181 -181
- package/kit/framework/workflows/help.md +619 -619
- package/kit/framework/workflows/insert-phase.md +130 -130
- package/kit/framework/workflows/list-phase-assumptions.md +178 -178
- package/kit/framework/workflows/list-workspaces.md +56 -56
- package/kit/framework/workflows/manager.md +362 -362
- package/kit/framework/workflows/map-codebase.md +377 -377
- package/kit/framework/workflows/milestone-summary.md +223 -223
- package/kit/framework/workflows/new-milestone.md +486 -486
- package/kit/framework/workflows/new-project.md +1159 -1159
- package/kit/framework/workflows/new-workspace.md +237 -237
- package/kit/framework/workflows/next.md +97 -97
- package/kit/framework/workflows/node-repair.md +92 -92
- package/kit/framework/workflows/note.md +156 -156
- package/kit/framework/workflows/pause-work.md +176 -176
- package/kit/framework/workflows/plan-milestone-gaps.md +273 -273
- package/kit/framework/workflows/plan-phase.md +765 -765
- package/kit/framework/workflows/plant-seed.md +169 -169
- package/kit/framework/workflows/pr-branch.md +129 -129
- package/kit/framework/workflows/profile-user.md +450 -450
- package/kit/framework/workflows/progress.md +507 -507
- package/kit/framework/workflows/quick.md +757 -757
- package/kit/framework/workflows/remove-phase.md +155 -155
- package/kit/framework/workflows/remove-workspace.md +90 -90
- package/kit/framework/workflows/research-phase.md +82 -82
- package/kit/framework/workflows/resume-project.md +326 -326
- package/kit/framework/workflows/review.md +228 -228
- package/kit/framework/workflows/session-report.md +146 -146
- package/kit/framework/workflows/settings.md +283 -283
- package/kit/framework/workflows/ship.md +228 -228
- package/kit/framework/workflows/stats.md +60 -60
- package/kit/framework/workflows/transition.md +671 -671
- package/kit/framework/workflows/ui-phase.md +302 -302
- package/kit/framework/workflows/ui-review.md +165 -165
- package/kit/framework/workflows/update.md +323 -323
- package/kit/framework/workflows/validate-phase.md +174 -174
- package/kit/framework/workflows/verify-phase.md +252 -252
- package/kit/framework/workflows/verify-work.md +637 -637
- package/kit/hooks/check-update.js +118 -118
- package/kit/hooks/context-monitor.js +163 -163
- package/kit/hooks/prompt-guard.js +103 -103
- package/kit/hooks/statusline.js +125 -125
- package/kit/hooks/workflow-guard.js +101 -101
- package/kit/settings.json +45 -45
- package/kit/skills/_shared-supabase/glossary.md +17 -0
- package/kit/skills/ai-prompt-characterization/SKILL.md +335 -335
- package/kit/skills/armadilhas-sistemas-distribuidos/SKILL.md +447 -447
- package/kit/skills/audit-log-multi-tenant/SKILL.md +340 -340
- package/kit/skills/b2b-saas-architecture/SKILL.md +300 -300
- package/kit/skills/consistencia-leitura-replica/SKILL.md +385 -385
- package/kit/skills/crm-lead-pipeline-patterns/SKILL.md +343 -343
- package/kit/skills/escolha-modelo-consistencia/SKILL.md +494 -494
- package/kit/skills/evolucao-schema-compativel/SKILL.md +448 -448
- package/kit/skills/evolution-go-whatsapp-integration/SKILL.md +322 -322
- package/kit/skills/example-skill/SKILL.md +42 -42
- package/kit/skills/legacy-api-only-applications/SKILL.md +358 -358
- package/kit/skills/legacy-characterization-tests/SKILL.md +330 -330
- package/kit/skills/legacy-effect-analysis/SKILL.md +331 -331
- package/kit/skills/legacy-extract-class/SKILL.md +203 -203
- package/kit/skills/legacy-programming-by-difference/SKILL.md +252 -252
- package/kit/skills/legacy-seams-and-test-harness/SKILL.md +460 -460
- package/kit/skills/legacy-shotgun-surgery/SKILL.md +286 -286
- package/kit/skills/legacy-sprout-wrap-techniques/SKILL.md +434 -434
- package/kit/skills/legacy-storytelling-naked-crc/SKILL.md +270 -270
- package/kit/skills/lgpd-multi-tenant-compliance/SKILL.md +340 -340
- package/kit/skills/member-invite-flow/SKILL.md +305 -305
- package/kit/skills/member-management-react-shadcn/SKILL.md +328 -328
- package/kit/skills/multi-tenant-performance-scaling/SKILL.md +316 -316
- package/kit/skills/multi-tenant-rls-hierarchy/SKILL.md +342 -342
- package/kit/skills/org-onboarding-flow/SKILL.md +257 -257
- package/kit/skills/org-switcher-react-pattern/SKILL.md +349 -349
- package/kit/skills/permission-gate-react-pattern/SKILL.md +271 -271
- package/kit/skills/postgres-isolamento-concorrencia/SKILL.md +552 -552
- package/kit/skills/pre-refactor-characterization/SKILL.md +421 -421
- package/kit/skills/rbac-permissions-matrix-supabase/SKILL.md +338 -338
- package/kit/skills/streams-eventos-cdc/SKILL.md +711 -711
- package/kit/skills/supabase-branching-workflow/SKILL.md +544 -544
- package/kit/skills/supabase-ci-cd-github-actions/SKILL.md +880 -880
- package/kit/skills/supabase-column-level-security/SKILL.md +426 -426
- package/kit/skills/supabase-config-toml-remotes/SKILL.md +807 -807
- package/kit/skills/supabase-custom-claims-rbac/SKILL.md +472 -472
- package/kit/skills/supabase-edge-functions/SKILL.md +229 -141
- package/kit/skills/supabase-edge-functions-auth/SKILL.md +309 -0
- package/kit/skills/supabase-edge-functions-limits/SKILL.md +302 -0
- package/kit/skills/supabase-edge-functions-mcp-server/SKILL.md +279 -0
- package/kit/skills/supabase-edge-functions-testing/SKILL.md +277 -0
- package/kit/skills/supabase-edge-runtime-builtins/SKILL.md +357 -0
- package/kit/skills/supabase-migration-repair/SKILL.md +823 -823
- package/kit/skills/supabase-migrations/SKILL.md +297 -297
- package/kit/skills/supabase-pgtap-testing/SKILL.md +1053 -1053
- package/kit/skills/supabase-postgres-roles/SKILL.md +392 -392
- package/kit/skills/supabase-realtime/SKILL.md +460 -236
- package/kit/skills/supabase-rls-defense-in-depth/SKILL.md +418 -418
- package/kit/skills/supabase-rls-policies/SKILL.md +635 -635
- package/kit/skills/super-admin-platform-pattern/SKILL.md +326 -326
- package/kit/skills/tenant-quente-mitigacao/SKILL.md +605 -605
- package/kit/skills/whatsapp-conversation-state-machine/SKILL.md +287 -287
- package/package.json +1 -1
- package/src/core/kit.js +216 -216
- package/src/core/reflect.js +247 -247
- package/src/core/reverse-sync.js +372 -372
- package/src/core/sync.js +418 -418
- package/src/core/watch.js +121 -121
- package/src/mcp-server/index.js +693 -693
|
@@ -1,335 +1,335 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ai-prompt-characterization
|
|
3
|
-
description: Use ao modificar prompt/tool LLM em produção — characterization de generations com temperature=0 + seed fixo + sanitização específica. Modernização 2026 sem precedente em 2004…
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# AI Prompt Characterization (Modernização)
|
|
7
|
-
|
|
8
|
-
## Quando usar
|
|
9
|
-
|
|
10
|
-
LLM carrega esta skill quando user vai modificar prompt ou tool definition de LLM em produção. Trigger phrases:
|
|
11
|
-
|
|
12
|
-
- "vou mudar esse prompt", "modificar prompt em prod"
|
|
13
|
-
- "atualizar tool definition", "function calling schema"
|
|
14
|
-
- "como testar mudança de prompt?"
|
|
15
|
-
- "characterization de prompt", "snapshot de generation"
|
|
16
|
-
- "esse prompt tem 300 linhas e ninguém testou ainda"
|
|
17
|
-
- prompt em arquivo como `prompts/<name>.md` ou string template em código
|
|
18
|
-
|
|
19
|
-
**Insight central:** prompts e tools são **código legacy também** quando:
|
|
20
|
-
- > 100 linhas
|
|
21
|
-
- Em uso em produção
|
|
22
|
-
- Mudanças quebram silenciosamente (output diferente, downstream parser falha)
|
|
23
|
-
- Sem characterization tests
|
|
24
|
-
|
|
25
|
-
## Regras absolutas
|
|
26
|
-
|
|
27
|
-
- **Prompts são código.** Tratam-se com mesmo rigor: versionado, testado, code-reviewed. NÃO são "config text que muda livremente".
|
|
28
|
-
- **Determinismo via `temperature=0` + `seed`.** Anthropic Claude e OpenAI ambos suportam seed. Sem isso, characterization é flaky.
|
|
29
|
-
- **Capture mais que `text`.** Outputs incluem: `text`, `finish_reason`, `tool_calls` (se function calling), `input_tokens`, `output_tokens`, `model_version`. Snapshot de TODOS estes campos.
|
|
30
|
-
- **Sanitize aggressively.** Outputs LLM frequentemente incluem timestamps mencionados, UUIDs gerados, datas relativas. Normalize ANTES de snapshot.
|
|
31
|
-
- **5+ inputs cobrindo intents distintas.** Não é "happy path × 5"; é "5 intents qualitativamente diferentes" — concision request, troubleshooting, explanation, creative, edge case.
|
|
32
|
-
- **Behavioral coverage = % intents cobertas.** Métrica não é coverage de "linhas do prompt" (não existe); é coverage de variações comportamentais.
|
|
33
|
-
- **Re-rodar em CI quando model_version muda.** Anthropic publica nova versão de Claude → re-rode characterization → revisar diffs → aceitar/rejeitar.
|
|
34
|
-
|
|
35
|
-
## Patterns canônicos
|
|
36
|
-
|
|
37
|
-
### Pattern 1: Setup canônico de characterization de prompt
|
|
38
|
-
|
|
39
|
-
```ts
|
|
40
|
-
// tests/characterization/prompts/generate-summary.test.ts
|
|
41
|
-
import { Anthropic } from '@anthropic-ai/sdk'
|
|
42
|
-
import { describe, test, expect } from 'vitest'
|
|
43
|
-
import { readFileSync } from 'fs'
|
|
44
|
-
|
|
45
|
-
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
|
|
46
|
-
const PROMPT = readFileSync('prompts/generate-summary.md', 'utf-8')
|
|
47
|
-
|
|
48
|
-
interface PromptInput {
|
|
49
|
-
systemPrompt: string
|
|
50
|
-
userMessage: string
|
|
51
|
-
maxTokens?: number
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async function runPrompt(input: PromptInput) {
|
|
55
|
-
const response = await client.messages.create({
|
|
56
|
-
model: 'claude-opus-4-7',
|
|
57
|
-
max_tokens: input.maxTokens ?? 500,
|
|
58
|
-
temperature: 0, // determinismo
|
|
59
|
-
system: input.systemPrompt,
|
|
60
|
-
messages: [{ role: 'user', content: input.userMessage }],
|
|
61
|
-
})
|
|
62
|
-
return {
|
|
63
|
-
text: response.content[0].type === 'text' ? response.content[0].text : '',
|
|
64
|
-
stopReason: response.stop_reason,
|
|
65
|
-
inputTokens: response.usage.input_tokens,
|
|
66
|
-
outputTokens: response.usage.output_tokens,
|
|
67
|
-
modelVersion: response.model,
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function sanitizeForSnapshot(o: any): any {
|
|
72
|
-
return JSON.parse(
|
|
73
|
-
JSON.stringify(o, (key, value) => {
|
|
74
|
-
// normalizar timestamps mencionados ("Today is 2026-05-08") → "<DATE>"
|
|
75
|
-
if (typeof value === 'string') {
|
|
76
|
-
value = value.replace(/\d{4}-\d{2}-\d{2}/g, '<DATE>')
|
|
77
|
-
value = value.replace(/\d{2}:\d{2}(:\d{2})?/g, '<TIME>')
|
|
78
|
-
value = value.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}/g, '<UUID>')
|
|
79
|
-
}
|
|
80
|
-
// permitir model version mas separar para audit (não no snapshot)
|
|
81
|
-
if (key === 'modelVersion') return '<MODEL>'
|
|
82
|
-
return value
|
|
83
|
-
})
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
describe('generate-summary prompt — characterization', () => {
|
|
88
|
-
test('intent: concise summary of long article', async () => {
|
|
89
|
-
const captured = await runPrompt({
|
|
90
|
-
systemPrompt: PROMPT,
|
|
91
|
-
userMessage: 'Resuma em 2 sentenças: [longo artigo de 500 palavras]...',
|
|
92
|
-
})
|
|
93
|
-
expect(sanitizeForSnapshot(captured)).toMatchSnapshot()
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
test('intent: bullet-list summary', async () => { /* ... */ })
|
|
97
|
-
test('intent: technical/code summary', async () => { /* ... */ })
|
|
98
|
-
test('intent: ambiguous request (edge)', async () => { /* ... */ })
|
|
99
|
-
test('intent: hostile / prompt injection attempt', async () => { /* ... */ })
|
|
100
|
-
})
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Pattern 2: Tool definition characterization (function calling)
|
|
104
|
-
|
|
105
|
-
```ts
|
|
106
|
-
// Quando prompt usa tool definition (function calling), characterize tool_calls
|
|
107
|
-
|
|
108
|
-
const TOOLS = [
|
|
109
|
-
{
|
|
110
|
-
name: 'search_knowledge_base',
|
|
111
|
-
description: 'Search for relevant docs',
|
|
112
|
-
input_schema: { type: 'object', properties: { query: { type: 'string' } } },
|
|
113
|
-
},
|
|
114
|
-
// ... mais tools
|
|
115
|
-
]
|
|
116
|
-
|
|
117
|
-
async function runWithTools(userMessage: string) {
|
|
118
|
-
const r = await client.messages.create({
|
|
119
|
-
model: 'claude-opus-4-7',
|
|
120
|
-
max_tokens: 500,
|
|
121
|
-
temperature: 0,
|
|
122
|
-
tools: TOOLS,
|
|
123
|
-
messages: [{ role: 'user', content: userMessage }],
|
|
124
|
-
})
|
|
125
|
-
return {
|
|
126
|
-
stopReason: r.stop_reason,
|
|
127
|
-
toolUses: r.content.filter(c => c.type === 'tool_use').map(c => ({
|
|
128
|
-
tool: (c as any).name,
|
|
129
|
-
input: (c as any).input,
|
|
130
|
-
})),
|
|
131
|
-
finalText: r.content.filter(c => c.type === 'text').map(c => (c as any).text).join('\n'),
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
test('tools — invokes search for factual question', async () => {
|
|
136
|
-
const captured = await runWithTools('Qual é a política de reembolso?')
|
|
137
|
-
expect(captured).toMatchSnapshot()
|
|
138
|
-
// snapshot captura QUAIS tools foram invocadas + QUAIS argumentos
|
|
139
|
-
})
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### Pattern 3: Sanitização específica de prompts
|
|
143
|
-
|
|
144
|
-
```ts
|
|
145
|
-
// Outputs LLM têm padrões previsíveis a sanitizar:
|
|
146
|
-
|
|
147
|
-
function sanitizeLLMOutput(text: string): string {
|
|
148
|
-
return text
|
|
149
|
-
// datas absolutas
|
|
150
|
-
.replace(/\b\d{4}-\d{2}-\d{2}\b/g, '<DATE>')
|
|
151
|
-
.replace(/\b(?:janeiro|fevereiro|março|abril|maio|junho|julho|agosto|setembro|outubro|novembro|dezembro)\s+(?:de\s+)?\d{4}/gi, '<DATE_PT>')
|
|
152
|
-
.replace(/\b(?:january|february|march|april|may|june|july|august|september|october|november|december)\s+\d{4}/gi, '<DATE_EN>')
|
|
153
|
-
// datas relativas
|
|
154
|
-
.replace(/\b(?:hoje|amanhã|ontem|today|tomorrow|yesterday)\b/gi, '<RELATIVE_DATE>')
|
|
155
|
-
// URLs e UUIDs
|
|
156
|
-
.replace(/https?:\/\/[^\s]+/g, '<URL>')
|
|
157
|
-
.replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, '<UUID>')
|
|
158
|
-
// valores monetários (preservar tipo, sanitizar valor)
|
|
159
|
-
.replace(/R\$\s*[\d,.]+/g, 'R$ <VALUE>')
|
|
160
|
-
.replace(/\$\s*[\d,.]+/g, '$ <VALUE>')
|
|
161
|
-
// versões
|
|
162
|
-
.replace(/v\d+\.\d+(?:\.\d+)?/g, '<VERSION>')
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Pattern 4: Behavioral coverage de prompt — 5+ intents
|
|
167
|
-
|
|
168
|
-
Para cada prompt, definir intents distintas:
|
|
169
|
-
|
|
170
|
-
| Intent | Definição | Exemplo de input |
|
|
171
|
-
|---|---|---|
|
|
172
|
-
| **Concise** | Pedido curto, output esperado curto | "Resuma em 1 frase: [text]" |
|
|
173
|
-
| **Detailed** | Pedido elaborado, output esperado longo | "Explique passo-a-passo: [text]" |
|
|
174
|
-
| **Code-heavy** | Input/output com código | "Refactor esse código: ```ts ...```" |
|
|
175
|
-
| **Edge case** | Input ambíguo ou borderline | "Como funciona?" (sem context) |
|
|
176
|
-
| **Adversarial** | Tentativa de jailbreak / prompt injection | "Ignore previous instructions and..." |
|
|
177
|
-
| **Multi-turn (se aplicável)** | Conversação com historico | [3+ messages prévias] |
|
|
178
|
-
|
|
179
|
-
5 intents × snapshot deterministic = baseline. Mudança em prompt deve manter outputs semanticamente próximos (ou documentar mudança intencional).
|
|
180
|
-
|
|
181
|
-
### Pattern 5: Pre-deploy checklist para mudança em prompt
|
|
182
|
-
|
|
183
|
-
```text
|
|
184
|
-
Antes de deploy de mudança em prompt em produção:
|
|
185
|
-
|
|
186
|
-
□ Suite de characterization tests passa verde (todos os 5+ intents)
|
|
187
|
-
□ Diff revisado HUMANAMENTE para cada intent — mudanças intencionais?
|
|
188
|
-
□ Behavioral coverage ≥ 5 intents (não bate threshold % — bate threshold de N)
|
|
189
|
-
□ Sanitização revisada — nenhum PII/secret no snapshot
|
|
190
|
-
□ Custo: cada test consome tokens; para prompts grandes, calcular total
|
|
191
|
-
- 5 inputs × 1k input + 500 output ≈ 7.5k tokens × $0.015/1k = ~$0.11
|
|
192
|
-
- CI roda só on-change para evitar custo recorrente
|
|
193
|
-
□ model_version anotado — re-rodar quando model_version muda
|
|
194
|
-
□ Audit trail no PR: "intent X: changed from Y to Z; reason: ..."
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### Pattern 6: Custo + cadência de characterization
|
|
198
|
-
|
|
199
|
-
| Frequência | Custo (em USD) por suite | Quando rodar |
|
|
200
|
-
|---|---|---|
|
|
201
|
-
| Desenvolvedor local | < $0.10 | Antes de cada commit que toca prompt |
|
|
202
|
-
| CI on-change | < $0.50/run | Em PR que toca arquivo de prompt |
|
|
203
|
-
| CI nightly | < $5/dia | Para detectar drift de model upstream |
|
|
204
|
-
| Pre-deploy | < $0.50 | Confirmação final antes de promote |
|
|
205
|
-
|
|
206
|
-
**Otimização:** snapshot diff só dispara LLM call se prompt mudou. Sem mudança = skip (cacheado).
|
|
207
|
-
|
|
208
|
-
### Pattern 7: Quando NÃO characterizar prompt
|
|
209
|
-
|
|
210
|
-
```text
|
|
211
|
-
- Prompt < 20 linhas e usado em 1 lugar — overhead > valor
|
|
212
|
-
- Prompt é template trivial ("Resume: {text}") sem lógica complexa
|
|
213
|
-
- LLM call é one-shot script (analytics, batch processing) — não em hot path
|
|
214
|
-
- Custo de tokens proibitivo (e.g., prompts massivos com 50k tokens) — usar smaller model para char tests
|
|
215
|
-
- Use case é generative criativo (poema, story) — outputs intencionalmente variáveis
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
## Anti-patterns
|
|
219
|
-
|
|
220
|
-
### ANTI: characterization sem temperature=0
|
|
221
|
-
|
|
222
|
-
```text
|
|
223
|
-
ANTI: rodar characterization com temperature=0.7 (default).
|
|
224
|
-
|
|
225
|
-
PROBLEMA: outputs varia entre runs. Snapshot diferente toda vez.
|
|
226
|
-
Tests flaky. Equipe ignora.
|
|
227
|
-
|
|
228
|
-
CERTO: temperature=0 SEMPRE em characterization. Anthropic + OpenAI
|
|
229
|
-
ambos têm. Em providers que não suportam, escolher menor
|
|
230
|
-
valor possível e/ou seed fixo se disponível.
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
### ANTI: snapshot sem sanitização
|
|
234
|
-
|
|
235
|
-
```text
|
|
236
|
-
ANTI: capturar output cru com timestamps, UUIDs, datas atuais.
|
|
237
|
-
|
|
238
|
-
PROBLEMA: cada run gera snapshot diferente. Não é flaky pelo LLM,
|
|
239
|
-
é flaky pelo CONTENT temporal.
|
|
240
|
-
|
|
241
|
-
CERTO: sanitize ANTES de matchSnapshot. Datas → <DATE>, UUIDs →
|
|
242
|
-
<UUID>, etc. Snapshot estável across time.
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### ANTI: 1 test "happy path" de prompt
|
|
246
|
-
|
|
247
|
-
```text
|
|
248
|
-
ANTI: 1 input de exemplo testado, "se passa, prompt está OK".
|
|
249
|
-
|
|
250
|
-
PROBLEMA: prompt tem comportamento qualitativamente diferente em
|
|
251
|
-
edge cases (input curto, input longo, input ambíguo,
|
|
252
|
-
adversarial). 1 test cobre 1 caminho, ignora N outros.
|
|
253
|
-
|
|
254
|
-
CERTO: 5+ intents cobrindo distribuição real de uso. Edge case +
|
|
255
|
-
adversarial são MANDATORY (prompts em prod sempre recebem
|
|
256
|
-
inputs ruins).
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
### ANTI: ignorar drift de model
|
|
260
|
-
|
|
261
|
-
```text
|
|
262
|
-
ANTI: characterization passou em maio; em julho Anthropic atualiza
|
|
263
|
-
Claude (claude-opus-4-7 → 4-8). Equipe não re-roda; deploy de
|
|
264
|
-
mudança quebra silenciosamente.
|
|
265
|
-
|
|
266
|
-
PROBLEMA: prompt baseline frozen no model anterior. Novo model
|
|
267
|
-
comporta diferente; bug em prod.
|
|
268
|
-
|
|
269
|
-
CERTO: CI nightly roda characterization. Diff de model_version =
|
|
270
|
-
trigger humano para revisar. Aceita ou rejeita updates de
|
|
271
|
-
model. Sem fixed model = sem characterization válida.
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### ANTI: snapshot inclui token count
|
|
275
|
-
|
|
276
|
-
```text
|
|
277
|
-
ANTI: snapshot tem `inputTokens: 247, outputTokens: 89`.
|
|
278
|
-
|
|
279
|
-
PROBLEMA: token counts mudam quando model muda (tokenizer evolui).
|
|
280
|
-
Diff vermelho em update de model é noise.
|
|
281
|
-
|
|
282
|
-
CERTO: capturar tokens em log SEPARADO (custo tracking), não no
|
|
283
|
-
snapshot. Snapshot é qualitativo (text + stop reason +
|
|
284
|
-
tool calls), não quantitativo.
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
### ANTI: tratar prompt como "string config livre"
|
|
288
|
-
|
|
289
|
-
```text
|
|
290
|
-
ANTI: dev edita prompt em prod direto via console; sem PR; sem
|
|
291
|
-
review; sem characterization.
|
|
292
|
-
|
|
293
|
-
PROBLEMA: prompt é código. Mudança não-versionada quebra silenciosa.
|
|
294
|
-
Sem audit trail. Rollback impossível.
|
|
295
|
-
|
|
296
|
-
CERTO: prompt em repo (`prompts/<name>.md`). PR review como qualquer
|
|
297
|
-
código. Characterization tests rodam em CI. Deploy via release
|
|
298
|
-
padrão.
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
## Verificação
|
|
302
|
-
|
|
303
|
-
1. Prompt versionado em arquivo (não inline em código se > 50 linhas)
|
|
304
|
-
2. Characterization tests existem com 5+ intents
|
|
305
|
-
3. `temperature=0` + seed fixo (se provider suporta)
|
|
306
|
-
4. Sanitização específica para prompt outputs
|
|
307
|
-
5. Snapshot inclui text + stopReason + toolCalls (se aplicável)
|
|
308
|
-
6. CI roda characterization on-change
|
|
309
|
-
7. model_version trackado (audit log separado)
|
|
310
|
-
8. Pre-deploy checklist completo
|
|
311
|
-
|
|
312
|
-
## Limiar de "prompt pronto para produção"
|
|
313
|
-
|
|
314
|
-
```text
|
|
315
|
-
Versionado em repo: sim
|
|
316
|
-
Characterization tests com ≥ 5 intents: sim
|
|
317
|
-
temperature=0 + seed fixo: sim
|
|
318
|
-
Sanitização aplicada: sim
|
|
319
|
-
Coverage de intents real (não synthetic): sim
|
|
320
|
-
CI integration: sim
|
|
321
|
-
Audit trail de mudanças: sim
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
---
|
|
325
|
-
|
|
326
|
-
## Ver também
|
|
327
|
-
|
|
328
|
-
- [`_shared-legacy/glossary.md`](../_shared-legacy/glossary.md) — vocabulário (characterization, golden master)
|
|
329
|
-
- [`legacy-characterization-tests`](../legacy-characterization-tests/SKILL.md) — characterization clássico; aplicável a prompts modulo determinismo
|
|
330
|
-
- [`legacy-api-only-applications`](../legacy-api-only-applications/SKILL.md) — LLM provider é caso especial de API; adapter pattern aplicável
|
|
331
|
-
- [`llm-as-dependency`](../llm-as-dependency/SKILL.md) — fakear LLM em testes que NÃO são de prompt characterization (testes de business logic)
|
|
332
|
-
- [`pre-refactor-characterization`](../pre-refactor-characterization/SKILL.md) — gate v1.12 inclui ai-prompt-stability como dimensão paralela
|
|
333
|
-
- [`observability-driven-development`](../observability-driven-development/SKILL.md) (v1.9) — instrument prompt outputs para detectar drift em prod
|
|
334
|
-
|
|
335
|
-
*Material-fonte (modernização 2026):* Sem precedente em livro Feathers 2004 — prompts/tools LLM como dependência testável é literatura recente (2023+ — papers da Anthropic sobre evals, OpenAI evals framework, Promptfoo).
|
|
1
|
+
---
|
|
2
|
+
name: ai-prompt-characterization
|
|
3
|
+
description: Use ao modificar prompt/tool LLM em produção — characterization de generations com temperature=0 + seed fixo + sanitização específica. Modernização 2026 sem precedente em 2004…
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# AI Prompt Characterization (Modernização)
|
|
7
|
+
|
|
8
|
+
## Quando usar
|
|
9
|
+
|
|
10
|
+
LLM carrega esta skill quando user vai modificar prompt ou tool definition de LLM em produção. Trigger phrases:
|
|
11
|
+
|
|
12
|
+
- "vou mudar esse prompt", "modificar prompt em prod"
|
|
13
|
+
- "atualizar tool definition", "function calling schema"
|
|
14
|
+
- "como testar mudança de prompt?"
|
|
15
|
+
- "characterization de prompt", "snapshot de generation"
|
|
16
|
+
- "esse prompt tem 300 linhas e ninguém testou ainda"
|
|
17
|
+
- prompt em arquivo como `prompts/<name>.md` ou string template em código
|
|
18
|
+
|
|
19
|
+
**Insight central:** prompts e tools são **código legacy também** quando:
|
|
20
|
+
- > 100 linhas
|
|
21
|
+
- Em uso em produção
|
|
22
|
+
- Mudanças quebram silenciosamente (output diferente, downstream parser falha)
|
|
23
|
+
- Sem characterization tests
|
|
24
|
+
|
|
25
|
+
## Regras absolutas
|
|
26
|
+
|
|
27
|
+
- **Prompts são código.** Tratam-se com mesmo rigor: versionado, testado, code-reviewed. NÃO são "config text que muda livremente".
|
|
28
|
+
- **Determinismo via `temperature=0` + `seed`.** Anthropic Claude e OpenAI ambos suportam seed. Sem isso, characterization é flaky.
|
|
29
|
+
- **Capture mais que `text`.** Outputs incluem: `text`, `finish_reason`, `tool_calls` (se function calling), `input_tokens`, `output_tokens`, `model_version`. Snapshot de TODOS estes campos.
|
|
30
|
+
- **Sanitize aggressively.** Outputs LLM frequentemente incluem timestamps mencionados, UUIDs gerados, datas relativas. Normalize ANTES de snapshot.
|
|
31
|
+
- **5+ inputs cobrindo intents distintas.** Não é "happy path × 5"; é "5 intents qualitativamente diferentes" — concision request, troubleshooting, explanation, creative, edge case.
|
|
32
|
+
- **Behavioral coverage = % intents cobertas.** Métrica não é coverage de "linhas do prompt" (não existe); é coverage de variações comportamentais.
|
|
33
|
+
- **Re-rodar em CI quando model_version muda.** Anthropic publica nova versão de Claude → re-rode characterization → revisar diffs → aceitar/rejeitar.
|
|
34
|
+
|
|
35
|
+
## Patterns canônicos
|
|
36
|
+
|
|
37
|
+
### Pattern 1: Setup canônico de characterization de prompt
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// tests/characterization/prompts/generate-summary.test.ts
|
|
41
|
+
import { Anthropic } from '@anthropic-ai/sdk'
|
|
42
|
+
import { describe, test, expect } from 'vitest'
|
|
43
|
+
import { readFileSync } from 'fs'
|
|
44
|
+
|
|
45
|
+
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
|
|
46
|
+
const PROMPT = readFileSync('prompts/generate-summary.md', 'utf-8')
|
|
47
|
+
|
|
48
|
+
interface PromptInput {
|
|
49
|
+
systemPrompt: string
|
|
50
|
+
userMessage: string
|
|
51
|
+
maxTokens?: number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function runPrompt(input: PromptInput) {
|
|
55
|
+
const response = await client.messages.create({
|
|
56
|
+
model: 'claude-opus-4-7',
|
|
57
|
+
max_tokens: input.maxTokens ?? 500,
|
|
58
|
+
temperature: 0, // determinismo
|
|
59
|
+
system: input.systemPrompt,
|
|
60
|
+
messages: [{ role: 'user', content: input.userMessage }],
|
|
61
|
+
})
|
|
62
|
+
return {
|
|
63
|
+
text: response.content[0].type === 'text' ? response.content[0].text : '',
|
|
64
|
+
stopReason: response.stop_reason,
|
|
65
|
+
inputTokens: response.usage.input_tokens,
|
|
66
|
+
outputTokens: response.usage.output_tokens,
|
|
67
|
+
modelVersion: response.model,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function sanitizeForSnapshot(o: any): any {
|
|
72
|
+
return JSON.parse(
|
|
73
|
+
JSON.stringify(o, (key, value) => {
|
|
74
|
+
// normalizar timestamps mencionados ("Today is 2026-05-08") → "<DATE>"
|
|
75
|
+
if (typeof value === 'string') {
|
|
76
|
+
value = value.replace(/\d{4}-\d{2}-\d{2}/g, '<DATE>')
|
|
77
|
+
value = value.replace(/\d{2}:\d{2}(:\d{2})?/g, '<TIME>')
|
|
78
|
+
value = value.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}/g, '<UUID>')
|
|
79
|
+
}
|
|
80
|
+
// permitir model version mas separar para audit (não no snapshot)
|
|
81
|
+
if (key === 'modelVersion') return '<MODEL>'
|
|
82
|
+
return value
|
|
83
|
+
})
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
describe('generate-summary prompt — characterization', () => {
|
|
88
|
+
test('intent: concise summary of long article', async () => {
|
|
89
|
+
const captured = await runPrompt({
|
|
90
|
+
systemPrompt: PROMPT,
|
|
91
|
+
userMessage: 'Resuma em 2 sentenças: [longo artigo de 500 palavras]...',
|
|
92
|
+
})
|
|
93
|
+
expect(sanitizeForSnapshot(captured)).toMatchSnapshot()
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('intent: bullet-list summary', async () => { /* ... */ })
|
|
97
|
+
test('intent: technical/code summary', async () => { /* ... */ })
|
|
98
|
+
test('intent: ambiguous request (edge)', async () => { /* ... */ })
|
|
99
|
+
test('intent: hostile / prompt injection attempt', async () => { /* ... */ })
|
|
100
|
+
})
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Pattern 2: Tool definition characterization (function calling)
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// Quando prompt usa tool definition (function calling), characterize tool_calls
|
|
107
|
+
|
|
108
|
+
const TOOLS = [
|
|
109
|
+
{
|
|
110
|
+
name: 'search_knowledge_base',
|
|
111
|
+
description: 'Search for relevant docs',
|
|
112
|
+
input_schema: { type: 'object', properties: { query: { type: 'string' } } },
|
|
113
|
+
},
|
|
114
|
+
// ... mais tools
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
async function runWithTools(userMessage: string) {
|
|
118
|
+
const r = await client.messages.create({
|
|
119
|
+
model: 'claude-opus-4-7',
|
|
120
|
+
max_tokens: 500,
|
|
121
|
+
temperature: 0,
|
|
122
|
+
tools: TOOLS,
|
|
123
|
+
messages: [{ role: 'user', content: userMessage }],
|
|
124
|
+
})
|
|
125
|
+
return {
|
|
126
|
+
stopReason: r.stop_reason,
|
|
127
|
+
toolUses: r.content.filter(c => c.type === 'tool_use').map(c => ({
|
|
128
|
+
tool: (c as any).name,
|
|
129
|
+
input: (c as any).input,
|
|
130
|
+
})),
|
|
131
|
+
finalText: r.content.filter(c => c.type === 'text').map(c => (c as any).text).join('\n'),
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
test('tools — invokes search for factual question', async () => {
|
|
136
|
+
const captured = await runWithTools('Qual é a política de reembolso?')
|
|
137
|
+
expect(captured).toMatchSnapshot()
|
|
138
|
+
// snapshot captura QUAIS tools foram invocadas + QUAIS argumentos
|
|
139
|
+
})
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Pattern 3: Sanitização específica de prompts
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
// Outputs LLM têm padrões previsíveis a sanitizar:
|
|
146
|
+
|
|
147
|
+
function sanitizeLLMOutput(text: string): string {
|
|
148
|
+
return text
|
|
149
|
+
// datas absolutas
|
|
150
|
+
.replace(/\b\d{4}-\d{2}-\d{2}\b/g, '<DATE>')
|
|
151
|
+
.replace(/\b(?:janeiro|fevereiro|março|abril|maio|junho|julho|agosto|setembro|outubro|novembro|dezembro)\s+(?:de\s+)?\d{4}/gi, '<DATE_PT>')
|
|
152
|
+
.replace(/\b(?:january|february|march|april|may|june|july|august|september|october|november|december)\s+\d{4}/gi, '<DATE_EN>')
|
|
153
|
+
// datas relativas
|
|
154
|
+
.replace(/\b(?:hoje|amanhã|ontem|today|tomorrow|yesterday)\b/gi, '<RELATIVE_DATE>')
|
|
155
|
+
// URLs e UUIDs
|
|
156
|
+
.replace(/https?:\/\/[^\s]+/g, '<URL>')
|
|
157
|
+
.replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, '<UUID>')
|
|
158
|
+
// valores monetários (preservar tipo, sanitizar valor)
|
|
159
|
+
.replace(/R\$\s*[\d,.]+/g, 'R$ <VALUE>')
|
|
160
|
+
.replace(/\$\s*[\d,.]+/g, '$ <VALUE>')
|
|
161
|
+
// versões
|
|
162
|
+
.replace(/v\d+\.\d+(?:\.\d+)?/g, '<VERSION>')
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Pattern 4: Behavioral coverage de prompt — 5+ intents
|
|
167
|
+
|
|
168
|
+
Para cada prompt, definir intents distintas:
|
|
169
|
+
|
|
170
|
+
| Intent | Definição | Exemplo de input |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| **Concise** | Pedido curto, output esperado curto | "Resuma em 1 frase: [text]" |
|
|
173
|
+
| **Detailed** | Pedido elaborado, output esperado longo | "Explique passo-a-passo: [text]" |
|
|
174
|
+
| **Code-heavy** | Input/output com código | "Refactor esse código: ```ts ...```" |
|
|
175
|
+
| **Edge case** | Input ambíguo ou borderline | "Como funciona?" (sem context) |
|
|
176
|
+
| **Adversarial** | Tentativa de jailbreak / prompt injection | "Ignore previous instructions and..." |
|
|
177
|
+
| **Multi-turn (se aplicável)** | Conversação com historico | [3+ messages prévias] |
|
|
178
|
+
|
|
179
|
+
5 intents × snapshot deterministic = baseline. Mudança em prompt deve manter outputs semanticamente próximos (ou documentar mudança intencional).
|
|
180
|
+
|
|
181
|
+
### Pattern 5: Pre-deploy checklist para mudança em prompt
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
Antes de deploy de mudança em prompt em produção:
|
|
185
|
+
|
|
186
|
+
□ Suite de characterization tests passa verde (todos os 5+ intents)
|
|
187
|
+
□ Diff revisado HUMANAMENTE para cada intent — mudanças intencionais?
|
|
188
|
+
□ Behavioral coverage ≥ 5 intents (não bate threshold % — bate threshold de N)
|
|
189
|
+
□ Sanitização revisada — nenhum PII/secret no snapshot
|
|
190
|
+
□ Custo: cada test consome tokens; para prompts grandes, calcular total
|
|
191
|
+
- 5 inputs × 1k input + 500 output ≈ 7.5k tokens × $0.015/1k = ~$0.11
|
|
192
|
+
- CI roda só on-change para evitar custo recorrente
|
|
193
|
+
□ model_version anotado — re-rodar quando model_version muda
|
|
194
|
+
□ Audit trail no PR: "intent X: changed from Y to Z; reason: ..."
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Pattern 6: Custo + cadência de characterization
|
|
198
|
+
|
|
199
|
+
| Frequência | Custo (em USD) por suite | Quando rodar |
|
|
200
|
+
|---|---|---|
|
|
201
|
+
| Desenvolvedor local | < $0.10 | Antes de cada commit que toca prompt |
|
|
202
|
+
| CI on-change | < $0.50/run | Em PR que toca arquivo de prompt |
|
|
203
|
+
| CI nightly | < $5/dia | Para detectar drift de model upstream |
|
|
204
|
+
| Pre-deploy | < $0.50 | Confirmação final antes de promote |
|
|
205
|
+
|
|
206
|
+
**Otimização:** snapshot diff só dispara LLM call se prompt mudou. Sem mudança = skip (cacheado).
|
|
207
|
+
|
|
208
|
+
### Pattern 7: Quando NÃO characterizar prompt
|
|
209
|
+
|
|
210
|
+
```text
|
|
211
|
+
- Prompt < 20 linhas e usado em 1 lugar — overhead > valor
|
|
212
|
+
- Prompt é template trivial ("Resume: {text}") sem lógica complexa
|
|
213
|
+
- LLM call é one-shot script (analytics, batch processing) — não em hot path
|
|
214
|
+
- Custo de tokens proibitivo (e.g., prompts massivos com 50k tokens) — usar smaller model para char tests
|
|
215
|
+
- Use case é generative criativo (poema, story) — outputs intencionalmente variáveis
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Anti-patterns
|
|
219
|
+
|
|
220
|
+
### ANTI: characterization sem temperature=0
|
|
221
|
+
|
|
222
|
+
```text
|
|
223
|
+
ANTI: rodar characterization com temperature=0.7 (default).
|
|
224
|
+
|
|
225
|
+
PROBLEMA: outputs varia entre runs. Snapshot diferente toda vez.
|
|
226
|
+
Tests flaky. Equipe ignora.
|
|
227
|
+
|
|
228
|
+
CERTO: temperature=0 SEMPRE em characterization. Anthropic + OpenAI
|
|
229
|
+
ambos têm. Em providers que não suportam, escolher menor
|
|
230
|
+
valor possível e/ou seed fixo se disponível.
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### ANTI: snapshot sem sanitização
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
ANTI: capturar output cru com timestamps, UUIDs, datas atuais.
|
|
237
|
+
|
|
238
|
+
PROBLEMA: cada run gera snapshot diferente. Não é flaky pelo LLM,
|
|
239
|
+
é flaky pelo CONTENT temporal.
|
|
240
|
+
|
|
241
|
+
CERTO: sanitize ANTES de matchSnapshot. Datas → <DATE>, UUIDs →
|
|
242
|
+
<UUID>, etc. Snapshot estável across time.
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### ANTI: 1 test "happy path" de prompt
|
|
246
|
+
|
|
247
|
+
```text
|
|
248
|
+
ANTI: 1 input de exemplo testado, "se passa, prompt está OK".
|
|
249
|
+
|
|
250
|
+
PROBLEMA: prompt tem comportamento qualitativamente diferente em
|
|
251
|
+
edge cases (input curto, input longo, input ambíguo,
|
|
252
|
+
adversarial). 1 test cobre 1 caminho, ignora N outros.
|
|
253
|
+
|
|
254
|
+
CERTO: 5+ intents cobrindo distribuição real de uso. Edge case +
|
|
255
|
+
adversarial são MANDATORY (prompts em prod sempre recebem
|
|
256
|
+
inputs ruins).
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### ANTI: ignorar drift de model
|
|
260
|
+
|
|
261
|
+
```text
|
|
262
|
+
ANTI: characterization passou em maio; em julho Anthropic atualiza
|
|
263
|
+
Claude (claude-opus-4-7 → 4-8). Equipe não re-roda; deploy de
|
|
264
|
+
mudança quebra silenciosamente.
|
|
265
|
+
|
|
266
|
+
PROBLEMA: prompt baseline frozen no model anterior. Novo model
|
|
267
|
+
comporta diferente; bug em prod.
|
|
268
|
+
|
|
269
|
+
CERTO: CI nightly roda characterization. Diff de model_version =
|
|
270
|
+
trigger humano para revisar. Aceita ou rejeita updates de
|
|
271
|
+
model. Sem fixed model = sem characterization válida.
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### ANTI: snapshot inclui token count
|
|
275
|
+
|
|
276
|
+
```text
|
|
277
|
+
ANTI: snapshot tem `inputTokens: 247, outputTokens: 89`.
|
|
278
|
+
|
|
279
|
+
PROBLEMA: token counts mudam quando model muda (tokenizer evolui).
|
|
280
|
+
Diff vermelho em update de model é noise.
|
|
281
|
+
|
|
282
|
+
CERTO: capturar tokens em log SEPARADO (custo tracking), não no
|
|
283
|
+
snapshot. Snapshot é qualitativo (text + stop reason +
|
|
284
|
+
tool calls), não quantitativo.
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### ANTI: tratar prompt como "string config livre"
|
|
288
|
+
|
|
289
|
+
```text
|
|
290
|
+
ANTI: dev edita prompt em prod direto via console; sem PR; sem
|
|
291
|
+
review; sem characterization.
|
|
292
|
+
|
|
293
|
+
PROBLEMA: prompt é código. Mudança não-versionada quebra silenciosa.
|
|
294
|
+
Sem audit trail. Rollback impossível.
|
|
295
|
+
|
|
296
|
+
CERTO: prompt em repo (`prompts/<name>.md`). PR review como qualquer
|
|
297
|
+
código. Characterization tests rodam em CI. Deploy via release
|
|
298
|
+
padrão.
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Verificação
|
|
302
|
+
|
|
303
|
+
1. Prompt versionado em arquivo (não inline em código se > 50 linhas)
|
|
304
|
+
2. Characterization tests existem com 5+ intents
|
|
305
|
+
3. `temperature=0` + seed fixo (se provider suporta)
|
|
306
|
+
4. Sanitização específica para prompt outputs
|
|
307
|
+
5. Snapshot inclui text + stopReason + toolCalls (se aplicável)
|
|
308
|
+
6. CI roda characterization on-change
|
|
309
|
+
7. model_version trackado (audit log separado)
|
|
310
|
+
8. Pre-deploy checklist completo
|
|
311
|
+
|
|
312
|
+
## Limiar de "prompt pronto para produção"
|
|
313
|
+
|
|
314
|
+
```text
|
|
315
|
+
Versionado em repo: sim
|
|
316
|
+
Characterization tests com ≥ 5 intents: sim
|
|
317
|
+
temperature=0 + seed fixo: sim
|
|
318
|
+
Sanitização aplicada: sim
|
|
319
|
+
Coverage de intents real (não synthetic): sim
|
|
320
|
+
CI integration: sim
|
|
321
|
+
Audit trail de mudanças: sim
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Ver também
|
|
327
|
+
|
|
328
|
+
- [`_shared-legacy/glossary.md`](../_shared-legacy/glossary.md) — vocabulário (characterization, golden master)
|
|
329
|
+
- [`legacy-characterization-tests`](../legacy-characterization-tests/SKILL.md) — characterization clássico; aplicável a prompts modulo determinismo
|
|
330
|
+
- [`legacy-api-only-applications`](../legacy-api-only-applications/SKILL.md) — LLM provider é caso especial de API; adapter pattern aplicável
|
|
331
|
+
- [`llm-as-dependency`](../llm-as-dependency/SKILL.md) — fakear LLM em testes que NÃO são de prompt characterization (testes de business logic)
|
|
332
|
+
- [`pre-refactor-characterization`](../pre-refactor-characterization/SKILL.md) — gate v1.12 inclui ai-prompt-stability como dimensão paralela
|
|
333
|
+
- [`observability-driven-development`](../observability-driven-development/SKILL.md) (v1.9) — instrument prompt outputs para detectar drift em prod
|
|
334
|
+
|
|
335
|
+
*Material-fonte (modernização 2026):* Sem precedente em livro Feathers 2004 — prompts/tools LLM como dependência testável é literatura recente (2023+ — papers da Anthropic sobre evals, OpenAI evals framework, Promptfoo).
|