Início rápido
Conecte askRunic e storeResult a um agente existente em poucos minutos.
Instalar
npm install @runic-labs/sdkpnpm add @runic-labs/sdkyarn add @runic-labs/sdkbun add @runic-labs/sdk@runic-labs/sdk depende de @runic-labs/cache e @runic-labs/ledger — você não precisa instalá-los separadamente, a menos que queira criar instâncias de armazenamento personalizadas (consulte Cache e Ledger).
Envolva a chamada que seu agente já faz
Encontre o local no seu agente onde ele transforma uma tarefa em uma chamada para um LLM ou ferramenta e envolva-a com askRunic / storeResult:
import { askRunic, storeResult } from "@runic-labs/sdk";
async function reviewFile(repo: string, file: string) {
const decision = { intent: "review_code", params: { repo, file } };
const cached = await askRunic(decision);
if (cached) {
console.log(`cache hit — saved ${cached.tokensSpent} tokens`);
return cached.artifact;
}
const response = await callYourLLM(promptFor(repo, file));
await storeResult(decision, response.text, response.tokensUsed);
return response.text;
}
Essa é toda a integração. Nenhuma configuração é necessária para começar — askRunic/storeResult usam um armazenamento padrão baseado em arquivos em .runic/ no seu diretório de trabalho.
Escolhendo intent e params
A assinatura é de correspondência exata, então decida o que de fato torna duas chamadas “a mesma decisão” no seu caso de uso:
- Bom:
{ intent: "summarize_pr", params: { repo: "acme/widgets", pr: 482 } }— mesmo repositório, mesmo número de PR, mesma intenção, sempre que esta PR exata for consultada. - Ruim:
{ intent: "summarize_pr", params: { prompt: fullPromptString } }— incluir o texto bruto do prompt como parâmetro significa que qualquer alteração na redação (até mesmo espaços em branco) produz uma falha de cache, anulando o propósito.
Coloque em params apenas os parâmetros que realmente identificam a decisão. Deixe o texto do prompt, rastros de raciocínio e qualquer coisa não determinística completamente fora da assinatura — consulte Como funciona para entender o motivo.
Inspecione o que está em cache
npm install -g @runic-labs/clipnpm add -g @runic-labs/clinpm install -g @runic-labs/clibun add -g @runic-labs/clirunic cache status
runic ledger status
Consulte CLI para exemplos completos de saída.
Aponte para outro local de armazenamento
Por padrão, o Runic grava em .runic/ em process.cwd(). Substitua isso com uma variável de ambiente se seu agente for executado a partir de um diretório de trabalho diferente daquele onde você deseja manter o estado:
RUNIC_HOME=/var/lib/my-agent/runic node agent.js
Use armazenamento em memória em vez disso (testes, execuções efêmeras)
import { createRunicClient } from "@runic-labs/sdk";
import { createCache, MemoryCacheStore } from "@runic-labs/cache";
import { createLedger, MemoryLedgerStore } from "@runic-labs/ledger";
const runic = createRunicClient({
cache: createCache(new MemoryCacheStore()),
ledger: createLedger(new MemoryLedgerStore()),
});
const cached = await runic.askRunic({ intent: "summarize_pr", params: { repo, pr } });
É exatamente isso que benchmarks/reuse-sweep e benchmarks/openrouter-savings usam, portanto nada persiste entre execuções separadas do script.
Próximos passos
- Como funciona — o algoritmo de assinatura em detalhes
- Benchmarks — reproduza números reais de economia de tokens