Memória para LangChain e LangGraph.js.
Em Python, com langchain-core só: context_runnable() coloca o contexto nas mensagens do prompt, NiadraCallbackHandler registra os turnos e history_tools() entrega o kit como StructuredTool. Em JavaScript, @niadra/sdk/langchain traz niadraContext() para cadeias LCEL, withNiadraContext() para nós de LangGraph.js, o callback handler e niadraTools().
A memória de conversa do LangChain é o histórico desta cadeia, numa sessão da sua aplicação. Ela não cruza fornecedor, não cruza canal e não sabe o que um sistema de registro mudou. Cada agente da empresa fica com a própria versão do cliente.
A Niadra entra como um runnable no meio da cadeia: as mensagens do prompt entram, e saem com o contexto da cliente como SystemMessage logo depois das mensagens de sistema e o turn_block no fim. O callback registra o que o cliente disse e o que o modelo respondeu, com o usage_metadata.
pip install 'niadra[langchain]' # langchain-core 1.6 or newer, below 2"""An LCEL chain with the customer's context and the history tools."""
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from niadra import Niadra, phone
from niadra.integrations.langchain import NiadraCallbackHandler, context_runnable, history_tools
niadra = Niadra(channel="chat")
prompt = ChatPromptTemplate.from_messages([("system", "You are Acme's agent."), ("human", "{question}")])
with niadra.conversation("thread-81", subject=phone("+5511912345678")) as conversation:
model = ChatOpenAI(model="gpt-4.1").bind_tools(history_tools(conversation))
chain = prompt | context_runnable(conversation) | model
reply = chain.invoke(
{"question": "Where is my replacement lid?"},
config={"callbacks": [NiadraCallbackHandler(conversation)]},
)
print(reply.content)npm install @niadra/sdk @langchain/core # @langchain/core 1.x, as an optional peer dependency// A LangGraph.js agent: the context goes into the model call inside the node (never into the
// graph's state), the history tools run through ToolNode, and the callback records the answers.
import { HumanMessage, SystemMessage } from "@langchain/core/messages";
import { END, MessagesAnnotation, START, StateGraph } from "@langchain/langgraph";
import { ToolNode, toolsCondition } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { Niadra, handles } from "@niadra/sdk";
import { NiadraCallbackHandler, niadraTools, withNiadraContext } from "@niadra/sdk/langchain";
const niadra = new Niadra();
/** One customer message in; `userId` comes from your session, never from the model. */
export async function reply(userId: string, threadId: string, text: string): Promise<string> {
const convo = niadra.conversation({ subject: handles.appUserId(userId), channel: "web_chat", conversation_id: threadId });
const tools = niadraTools(convo);
const model = new ChatOpenAI({ model: "gpt-4.1" }).bindTools(tools);
const graph = new StateGraph(MessagesAnnotation)
.addNode("agent", async (state) => ({ messages: [await model.invoke(await withNiadraContext(convo, state.messages))] }))
.addNode("tools", new ToolNode(tools))
.addEdge(START, "agent")
.addConditionalEdges("agent", toolsCondition, ["tools", END])
.addEdge("tools", "agent")
.compile();
const result = await graph.invoke(
{ messages: [new SystemMessage("You are Acme's support agent. Be brief."), new HumanMessage(text)] },
{ callbacks: [new NiadraCallbackHandler(convo)] },
);
return result.messages.at(-1)?.text ?? "";
}- Python
- TypeScript
O mesmo código está em examples/langchain_chain.py, examples/langgraph-js.ts nos repositórios dos SDKs, onde roda na CI contra os tipos reais do framework e o emulador da Niadra. Para testar sem a nuvem da Niadra, niadra-mock e NIADRA_BASE_URL=http://127.0.0.1:8765.
Como o adaptador se liga
As cinco primitivas de toda integração da Niadra, nos pontos de extensão deste framework.
- Contexto
- Em Python, context_runnable() recebe as mensagens do prompt, uma lista ou um PromptValue, e devolve com o contexto como SystemMessage logo depois das mensagens de sistema iniciais e o turn_block como SystemMessage no fim; with_context() e awith_context() fazem o mesmo numa lista sua. Em JavaScript, niadraContext(session) é um runnable para cadeias LCEL (niadraContext(convo).pipe(model)); withNiadraContext(session, messages) faz o mesmo dentro de um nó do LangGraph.js, logo antes da chamada ao modelo, então nada entra no estado do grafo.
- Turnos
- NiadraCallbackHandler registra as mensagens do cliente quando um chat model começa, chaveadas pela posição, e a resposta do modelo com o usage_metadata quando termina. Em JavaScript, registra as respostas com o usage_metadata que o LangChain padroniza; respostas que só chamam ferramentas não registram nada.
- Ferramentas
- history_tools(): StructuredTool com os nomes, descrições e esquemas do kit, amarradas ao cliente. Em JavaScript, niadraTools(session).
- Verificação
- conversation.verify() antes da chamada.
- Transbordo
- conversation.handoff() onde a cadeia transfere.
O que o agente recebe
O contexto é compilado quando a memória muda e servido pronto, sem modelo de IA na leitura. O que outro canal disse durante a conversa chega como delta, no fim do prompt.
- Quem é o cliente, pelo que a conversa já provou: o nível de verificação decide o que entra
- Fatos, pendências e promessas, com a data e o canal de origem
- O que outros agentes fizeram por dentro, confirmado pelo sistema de registro
- Padrões calculados por regra, com as evidências e o prazo
- As três ferramentas do histórico: buscar, linha do tempo e abrir um item, amarradas ao cliente no seu código
- Comprovante de cada leitura, encadeado por SHA-256
O que o adaptador não faz
- Sem BaseChatMessageHistory nem BaseStore próprios: a Niadra não é o armazenamento de estado da cadeia nem do grafo, e o checkpointer nunca guarda um contexto.
- Nada aqui derruba a cadeia: com a Niadra lenta ou fora, as mensagens vão ao modelo como vieram.
- Testado contra langchain-core 1.6 e @langchain/core 1.2 com um chat model falso e a Niadra no emulador.
Perguntas frequentes
Preciso de langchain inteiro ou só do core?
Em Python, só de langchain-core: o runnable, o callback e as ferramentas usam as interfaces do core. O exemplo usa langchain-openai para o modelo, mas qualquer chat model serve.
A memória de conversa do LangChain continua funcionando?
Continua, e é sua. O histórico da cadeia é o que o modelo viu nesta sessão; a Niadra é o que a empresa sabe da pessoa, vindo de todos os canais e sistemas. O callback registra os turnos uma vez, pela posição, então o histórico repetido na próxima chamada não entra duas vezes.
E numa cadeia que chama ferramentas várias vezes?
Em JavaScript, respostas que só chamam ferramentas não registram nada; o turno do agente é a resposta com texto. As ferramentas do histórico rodam pelo ToolNode, como qualquer outra, amarradas ao cliente que o seu código abriu.
Preciso trocar de modelo, de prompt ou de fornecedor?
Não. O adaptador coloca o contexto depois das suas instruções e o delta no fim do prompt, nos pontos de extensão que o framework já tem. O seu modelo, o seu prompt e o seu fornecedor continuam os mesmos, e trocar qualquer um deles depois não apaga a memória.
Onde ficam os dados e quanto custa?
Os dados ficam numa região só, informada no contrato, cifrados com AES-256-GCM e chave exclusiva por empresa, protegida em HSM FIPS 140-3. O preço é por conversa ou tarefa em que um agente leu a memória: de US$ 2 a 3 a cada mil, conforme o volume, com leituras, buscas e eventos de sistema incluídos. A Niadra está abrindo para empresas por pedido, antes do lançamento.
Conte o que você está construindo.
E-mail corporativo e duas linhas sobre os seus agentes bastam. Quem responde é quem escreve o código, com uma proposta de acesso antecipado para o seu caso.
Prefere contar mais sobre a sua empresa? Use o formulário completo