SGS como ferramenta de IA

Wire the Central Bank indicators into an LLM via function calling

A SGS API foi desenhada para ser uma tool de IA: slugs amigáveis, busca por nome (PT/EN), saída normalizada e padrão enxuto (12 observações) que não estoura o contexto. Este guia mostra como expor a API como duas funções e deixar o modelo descobrir e ler indicadores sozinho.

The SGS API is built to be an AI tool: friendly slugs, name search (PT/EN), normalized output, and a lean default (12 observations) that won't blow up the context window. This guide exposes the API as two functions and lets the model discover and read indicators on its own.

Base: https://sgs.api.insyde.one — aberta, sem autenticação / open, no auth.

1. O fluxo de duas etapas / The two-step flow

O modelo raramente sabe o código SGS de cabeça. Dê a ele duas ferramentas e ele encadeia sozinho: buscar a série, depois ler os dados.

The model rarely knows the SGS code by heart. Give it two tools and it chains them: search for the series, then read the data.

// 1. Usuário: "qual a inflação dos últimos 6 meses?"
// 2. Modelo chama: sgs_search({ q: "inflação" })   → descobre slug "ipca"
// 3. Modelo chama: sgs_series({ id: "ipca", last: 6 })
// 4. Modelo responde com os números + unidade ("% a.m.")

2. Schema das ferramentas / Tool schemas

OpenAI (tools / function calling):

[
  {
    "type": "function",
    "function": {
      "name": "sgs_search",
      "description": "Search the Banco Central (SGS) catalog for an economic indicator by name. Returns matching series with their slug, code and unit.",
      "parameters": {
        "type": "object",
        "properties": {
          "q": { "type": "string", "description": "Term in PT or EN, e.g. 'inflação', 'selic', 'dollar'" }
        },
        "required": ["q"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "sgs_series",
      "description": "Read observations for a Banco Central series by slug (e.g. 'ipca') or numeric SGS code. Returns ISO dates and numeric values with unit and frequency.",
      "parameters": {
        "type": "object",
        "properties": {
          "id":    { "type": "string", "description": "Series slug or SGS code" },
          "last":  { "type": "integer", "description": "Last N observations (default 12)" },
          "start": { "type": "string", "description": "Range start, YYYY-MM-DD" },
          "end":   { "type": "string", "description": "Range end, YYYY-MM-DD" }
        },
        "required": ["id"]
      }
    }
  }
]

Anthropic (tools): mesma ideia — o campo input_schema recebe o mesmo objeto de parameters acima. / same idea — input_schema takes the same object as parameters above.

{
  "name": "sgs_series",
  "description": "Read observations for a Banco Central series by slug or SGS code.",
  "input_schema": {
    "type": "object",
    "properties": {
      "id": { "type": "string" },
      "last": { "type": "integer" }
    },
    "required": ["id"]
  }
}

3. Executor das ferramentas / The tool executor

As duas funções são apenas fetch na SGS API. Sem estado, sem chave:

Both functions are just a fetch against the SGS API. Stateless, keyless:

const BASE = 'https://sgs.api.insyde.one';

async function runTool(name, args) {
  if (name === 'sgs_search') {
    const r = await fetch(`${BASE}/series?q=${encodeURIComponent(args.q)}`);
    return r.json(); // [{ code, slug, name, unit, frequency, aliases }]
  }
  if (name === 'sgs_series') {
    const qs = new URLSearchParams();
    if (args.last)  qs.set('last', args.last);
    if (args.start) qs.set('start', args.start);
    if (args.end)   qs.set('end', args.end);
    const r = await fetch(`${BASE}/series/${encodeURIComponent(args.id)}?${qs}`);
    if (!r.ok) return { error: (await r.json()).error };
    return r.json(); // { code, slug, name, unit, frequency, count, observations }
  }
}

4. Exemplo end-to-end (OpenAI) / End-to-end (OpenAI)

import OpenAI from 'openai';
const client = new OpenAI();

const messages = [{ role: 'user', content: 'A Selic subiu ou caiu no último ano? E a inflação?' }];

while (true) {
  const res = await client.chat.completions.create({
    model: 'gpt-4o', messages, tools: SGS_TOOLS,
  });
  const msg = res.choices[0].message;
  messages.push(msg);
  if (!msg.tool_calls) { console.log(msg.content); break; }

  for (const call of msg.tool_calls) {
    const out = await runTool(call.function.name, JSON.parse(call.function.arguments));
    messages.push({ role: 'tool', tool_call_id: call.id, content: JSON.stringify(out) });
  }
}
Por que funciona bem: a resposta type=ai já traz name, unit e frequency — o modelo interpreta 0.21 como "0,21% ao mês" sem contexto extra.
Why it works: the type=ai response carries name, unit and frequency, so the model reads 0.21 as "0.21% per month" with no extra context.

5. Boas práticas / Best practices

Dica: respostas de dados são cacheadas por ~1 h. Para um agente que monitora, isso é desejável — evita marteladas no BC e mantém latência baixa.
Tip: data responses are cached for ~1 h. For a monitoring agent that's a feature — it avoids hammering BCB and keeps latency low.

API reference · Live demo · Back to Insyde APIs