Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de markdown de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL.
See how MongoDB 9.0 delivers up to 2x higher throughput.
MongoDB Branding Shape
Register now >
Menu Docs

agente-engine-sdk-langgraph

Um SDK do MongoDB Atlas Agent Engine. Fornece um wrapper fino específico do LangChain sobre o tempo de execução da plataforma agent-engine-runner-shared.

pip install agent-engine-sdk-langgraph

Ou em um projeto uv:

uv add agent-engine-sdk-langgraph
from agent_engine_sdk_langgraph import App
from langgraph.graph import StateGraph, MessagesState
from langgraph.prebuilt import ToolNode
app = App(app_name="my-agent", app_version="1.0.0")
@app.tool()
def lookup(query: str) -> str:
"""Search the knowledge base."""
return "result for " + query
@app.entrypoint
def build_agent():
from langchain_openai import ChatOpenAI
llm = app.llm(ChatOpenAI(model="gpt-5.4"))
tools = app.get_tools()
def call_model(state: MessagesState):
response = llm.invoke(state["messages"])
return {"messages": [response]}
graph = StateGraph(MessagesState)
graph.add_node("agent", call_model)
graph.add_node("tools", ToolNode(tools))
graph.set_entry_point("agent")
graph.add_edge("tools", "agent")
return graph.compile(checkpointer=app.checkpointer())
app.run()

app.memory é a face unificada `agent-engine-sdk-memory <../agent-engine-sdk-memory/README.md>'__ Memory (limitada à aplicação durante o tempo de execução da plataforma). A identidade é resolvida por chamada do argumento, de um contexto vinculado ou do contexto de execução do ambiente.

app = App(app_name="my-agent")
# Save a semantic fact — returns CreateSemanticResult
result = app.memory.save_semantic(
text="User prefers dark mode",
label="pref-theme",
user_id="u1",
metadata={"channel": "web", "priority": "high"}, # optional caller-supplied metadata
)
if result.acknowledged:
...
# Search — returns list[MemoryChunk]
chunks = app.memory.search_semantic(query="user preferences", user_id="u1")
for chunk in chunks:
print(chunk.content)
# Build prompt context — returns ContextResponse
# Default sources are LTM (episodic + semantic); pass
# enabled_sources={"stm", ...} to include recent turns.
context = app.memory.build_context(query="help me", user_id="u1")
prompt_block = context.formatted_context # str (or structured list, depending on format)

build_context_from_sources (modos de recuperação por fonte, filtros e top_k) está disponível no tempo de execução ambiente app.memory. Ele retorna ContextResponse completo, então os metadados por fonte (ranking_strategy, source_outcomes) sobrevivem; a plataforma carimbos de aluguel e carrega a resposta de volta por meio da execução durável. session_id é necessário somente quando a origem stm é solicitada.

from agent_engine_sdk_langgraph import Memory reexporta a mesma classe que agent_engine_sdk_memory.Memory. Construir você mesmo Memory(api_key=...) / Memory(base_url=...) é o caminho HTTP/direto , não vinculado ao aplicativo ambiente.

Quando isso quebra

Este é um corte forçado: não há API dupla e nenhum ajuste de compatibilidade no app.memory. Os agentes do cliente quebram somente quando reconstróem uma imagem do agente que pega as discos da base do executor que contêm esse SDK. A mesclagem de plataformas por si só ou a reimplantação de uma imagem antiga de agente não altera o código do SDK já incorporado a essa imagem. Não há migração de dados de memória armazenada - apenas as formas de retorno do cliente e as convenções de chamada mudam.

Migração da superfície pré-fachada

  • Tipos de retorno / veracidade / metadados / ``build_context``: grava resultados digitados de retorno (CreateSemanticResult, CreateEpisodicResult etc.) com acknowledged — não apenas bool/dicts. Prefira if result.acknowledged: (não if result: – os modelos pydentic são sempre verdadeiros). As pesquisas de similaridade retornam list[MemoryChunk] (chunk.content, chunk.similarity_score opcional). Campos livres que costumavam ser chaves de dicionário de nível superior (title, summary, tags, term, definition, related_terms, ...) vivem sob chunk.metadata (por exemplo, ep.metadata.get("title") em vez de ep.get("title")). build_context retorna ContextResponse; use context.formatted_context, não o valor de retorno como uma string.

  • Os ajudantes de gravação são somente palavras-chave (save_semantic(text=..., label=..., …)). As chamadas posicionais aumentam TypeError.

  • As leituras com ``visibility="private"`` mantêm o filtro de usuário ambiente (anteriormente a aprovação de qualquer argumento visibility o descartou): pesquisas de visibilidade privada agora retornam apenas as memória do usuário atual, a menos que um user_id explícito seja passado.

  • ``top_k``: por fonte search_semantic / search_episodes / search_taxonomic padrão para top_k=50 (geralmente era 10). discover_procedures ainda é padronizado como 10. O Memory.search() unificado ainda tem como padrão top_k=10. O build_context público não tem nenhum parâmetro top_k. Use max_tokens para um orçamento bruto de construção de contexto (não um custo de busca). Após a recuperação e a classificação, o servidor subtrai uma reserva de formatação de token 500 e, em seguida, seleciona avidamente chunks de memória inteiros que cabem no restante. Valores positivos iguais ou inferiores a 500 não deixam orçamento para recordações. Valores acima de 500 ainda podem gerar um contexto vazio quando nenhum chunk se encaixa. Passe um top_k explícito sobre os auxiliares de pesquisa se precisar do limite antigo.

  • Identidade: os campos obrigatórios que não podem ser resolvidos aumentam MemoryIdentityError (chega de None suave / salto silencioso). save_episode requer um session_id resolvível (o contexto de invocação do ambiente é adequado; caso contrário, passe-o explicitamente ou vincule um MemoryRequestContext). Os valores em branco não contam como definidos.

  • Fidelidade de criação vinculada ao aplicativo: create-result id pode ser "" e has_embedding normalmente False — sucesso do Gate em .acknowledged, não id. Os detalhes por operação estão na matriz de capacidade do pacote de memória.

  • Obtém versus pesquisa: get_semantic / get_taxonomic_term / list_episodes ainda retornam dicionários de tipo livre no limite do aplicativo. Somente os métodos search* retornam list[MemoryChunk].

  • Renomeia: se alguém chamou os nomes da pré-fachada, use a API pública da fase — create_taxonomic → save_taxonomic; list_taxonomic_domains → list_domains.

Antes / depois

# save_semantic: bool → .acknowledged; positional → keyword-only
# before
ok = app.memory.save_semantic("User prefers dark mode", "pref-theme", user_id="u1")
if ok:
...
# after
result = app.memory.save_semantic(
text="User prefers dark mode",
label="pref-theme",
user_id="u1",
)
if result.acknowledged:
...
# save_episode: str|None → CreateEpisodicResult (.acknowledged / .id)
# before
doc_id = app.memory.save_episode(title="Quote chat", content=summary, user_id="u1")
if doc_id:
...
# after
episode = app.memory.save_episode(
title="Quote chat",
content=summary,
user_id="u1",
metadata={"channel": "web", "priority": "high"}, # optional caller-supplied metadata
# session_id from ambient context, or pass explicitly
)
if episode.acknowledged:
print(episode.id) # may be "" on app-bound
# search_episodes: dict.get → MemoryChunk metadata + content; pin top_k if needed
# before
episodes = app.memory.search_episodes(query="policy quote", top_k=10)
for ep in episodes:
print(ep.get("title"), ep.get("content"))
# after
episodes = app.memory.search_episodes(query="policy quote", top_k=10)
for ep in episodes:
print(ep.metadata.get("title"), ep.content)
# build_context: str → ContextResponse.formatted_context
# before
prompt = app.memory.build_context(query="help me", user_id="u1")
# after
context = app.memory.build_context(query="help me", user_id="u1")
prompt = context.formatted_context

Migração de referência (no repositório de exemplos do Agent Engine):

  • agents/insurance-agent/src/insurance_agent/main.py

As diferenças de capacidade por backend e as lacunas vinculadas ao aplicativo são documentadas na matriz de recursos do pacote de memória. Documentos em nível de métodopara a face Memory estão ativos em Agent-engine-sdk-memory.

Habilite a memória com features.memory: true em agent.yaml ou com a variável de ambiente ENABLE_MEMORY=true legado quando esse sinalizador de recurso for omitido. Os aplicativos existentes ainda podem passar enable_memory=... ou enable_tracing=... para App(...), mas esses sinalizadores de construtor estão obsoletos: mova a memória para agent.yaml e remova enable_tracing completamente porque o rastreamento está sempre ativado.

As habilitações são arquivos de marcação nomeados (SKILL.md) que o LLM pode carregar sob demanda por meio de abertura gradual. Use-os para codificar a experiência do domínio (por exemplo, regras de revisão de segurança, convenções de codificação) que sobrecarregariam o prompt do sistema se sempre incluídos.

my_agent/
skills/
security-checklist/
SKILL.md
style-guide/
SKILL.md

Passe o diretório principal skills/ para skills=[...]. No tempo de execução, os agentes listam esse diretório por meio do backend configurado e descobrem cada diretório filho imediato que contém SKILL.md como uma habilidade. A descoberta é um nível de profundidade, não recursiva.

---
name: security-checklist
description: Security review rules for Python code, focusing on injection and auth
---
# Security Checklist
## REVIEW-RULE-ID-SEC-1: SQL injection
Never concatenate user input into SQL...
## REVIEW-RULE-ID-SEC-2: Command / path injection
Calls to `subprocess.run`, `os.system`, `shell=True`, and `open()` must not
interpolate untrusted input...

agentes secretos validam o frontmatter da habilidade no tempo de execução. Ele ignora frontmatter ilegível ou analisável e habilidades faltando name ou description; As violações de nomenclatura de habilidades do agente ou de nome de diretório produzem avisos, mas ainda podem carregar. O SDK encaminha caminhos declarados sem inspecioná-los ou filtrá-los.

Observação

Pré-requisitos: agent.yaml deve incluir features.deep_agent: true ou App.deep_agent() aumentará RuntimeError no momento da construção:

features:
deep_agent: true
from langchain_openai import ChatOpenAI
from agent_engine_sdk_langgraph import App
app = App(app_name="My Reviewer")
@app.entrypoint
def build_agent():
return app.deep_agent(
llm=ChatOpenAI(model="gpt-5.4"),
system_prompt="You are a code reviewer.",
skills=["skills"],
)
app.run()

Cada entrada skills=[...] é um diretório de origem principal, não um diretório de habilidade de folha ou um arquivo SKILL.md. Os caminhos são relativos ao diretório que contém agent.yaml, então skills=["skills"] funciona para imagens de agente único (/app/skills) e imagens de monorepo (/app/<agent-subdirectory>/skills). Se suas habilidades estiverem em outro lugar dentro da árvore de origem do agente , defina AGENTIC_SKILLS_DIR para esse diretório relativo e torne skills=[...] relativo a ele. No tempo de execução, o deepagents lê o frontmatter de cada habilidade descoberta e passa seus metadados (nome, descrição e caminho resolvido) para o LLM como um bloco de sistema de habilidades no prompt do sistema.

Na curva 1, o LLM vê apenas os metadados das habilidades, não os corpos. Quando um usuário pergunta sobre segurança, o LLM decide fazer read_file("<agent-dir>/skills/security-checklist/SKILL.md"), e o corpo inteiro chega como ToolMessage no contexto da vez 2.

Isso mantém o prompt de base simples (os metadados são de aproximadamente 50 tokens por habilidade), permitindo que experiência profunda seja carregada sob demanda.

O sistema de arquivos gravável do ToolPod e os manipuladores de shell ainda usam WORKSPACE_DIR, que é padronizado como /tmp/agent-workspace. Mantenha isso como espaço zero.

Em vez disso, as habilidades agrupadas são tratadas como recursos somente leitura. O ToolPod deriva a raiz de habilitações padrão de AGENTIC_AGENT_CONFIG_PATH ou AGENTIC_AGENT_WORKDIR: se a configuração de tempo de execução for /app/agent.yaml, a raiz de habilitações será /app/skills; se a configuração de tempo de execução for /app/agents/reviewer/agent.yaml, a raiz das habilitações será /app/agents/reviewer/skills. AGENTIC_SKILLS_DIR substitui essa raiz e deve ser relativo à raiz de origem do agente . As ferramentas do sistema de arquivos somente leitura podem carregar arquivos nessa raiz sem definir WORKSPACE_DIR no diretório de habilidades. As operações de gravação, edição e shell ainda permanecem no espaço de trabalho gravável. A raiz de habilidades é resolvida na inicialização do Pod da Ferramenta, não no momento da importação do SDK, portanto, uma importação normal do SDK estática funciona — nenhuma solução alternativa na ordem de importação é necessária.

As habilidades são visíveis apenas para o agente que as declara. Se o seu agente gerar subagentes (por meio da ferramenta task), esses subagentes não herdarão as habilidades dos pais. Passe skills=[...] em cada especificação de subagente que precisa de arquivos de habilidade.

O tempo de execução do agente secreto reserva 9 nomes de ferramentas para integrados.Não registre @app.tool() com nenhum desses nomes — ele sombreia silenciosamente o comportamento integrado e quebra as habilidades/sandbox:

  • read_file, write_file, edit_file, ls, glob, grep (sistema de arquivos)

  • execute (shell)

  • write_todos (planejamento)

  • task (subagent dispatch)

Escolher um nome que corresponda sombreará silenciosamente o integrado — não há erro de tempo de importação.

Meta < 200 linhas por corpo SKILL.md. Competências maiores:

  • Consome mais contexto quando carregado (cada read_file é um despejo de corpo inteiro)

  • Corre o risco de atingir o limite de contexto de mensagem única do LLM em voltas complexas

  • Sugerir que a habilidade deve ser divisão em vários arquivos focados

O tempo de execução armazena em cache skills_metadata no estado do agente durante a vida útil de um thread. Se você editar um arquivo SKILL.md, os threads existentes continuarão usando os metadados obsoletos até a redefinição. Em desenvolvimento: exclua o tópico ou inicie uma nova sessão. Em produção: as mudanças de habilidades devem ser emparelhadas com um novo modelo/lançamento de versão de prompt.

Consulte o repositório de exemplos do Code Analyzer Agent no Agent Engine para ver uma implementação de referência:

  • Repositório de exemplos do Agent Engine agents/code-reviewer-agent/src/code_reviewer_agent/main.py — fiação

  • Repositório de exemplos do Agent Engine agents/code-reviewer-agent/skills/*/SKILL.md — exemplo de habilidades

LangGraphBaseAgent.stream() produz StreamEvent objetos. Itere com async for para receber atualizações em nível de token, marcadores de ciclo de vida de subagentes e o resultado final.

event
Quando disparado
data Campos

token

Cada chunk de token LLM do agente raiz ou de qualquer subagente ativo.

content: texto do token. source: "" para o agente raiz ou o nome do gráfico do subagente. tool_call_id: o tool_call_id task dos pais quando um está a bordo para esse subagente (pode ser "" até ser montado).

subagent_start

Tem início uma execução de subagente. Emitido de um dos dois caminhos: (1) primário - a ferramenta_call task do agente pai é observada; (2) fallback sintético — um token de origem chega antes que o tool_call principal tenha sido montado (buffered-dispatch providers). Os dois caminhos se comparam, de modo que exatamente um dispara de início por subagente por vez.

source / subagent_name: o nome do gráfico do subagente. tool_call_id: o tool_call_id task dos pais, ou "" se o fallback sintético for disparado antes da montagem do tool_call. description: o description arg que o pai passou para task (vazio quando o sintético é acionado primeiro).

subagent_end

Uma execução de subagente é concluída. Caminho primário: o gráfico principal observa um Command-close cujo tool_call_id corresponde a um subagente aberto. Caminho defensivo: erros de fluxo ou conclusão com subagentes pendentes — um subagent_end é emitido por órfão para que os consumidores possam fechar o estado da interface do usuário.

source / subagent_name: igual ao início. tool_call_id: o tool_call_id de fechamento ou "" para extremidades órfãs de um início somente sintético que nunca recebeu um tool_call real. summary: o conteúdo final ToolMessage do subagente (vazio para fins defensivos).

result

Conclusão final do agente raiz .

response além da lista completa de mensagens.

suspend

Interrupção HITL — o gráfico está pausado aguardando revisão humana.

suspend_payload, checkpoint_id.

Notas para consumidores:

  • subagent_start e subagent_end estão sempre emparelhados, inclusive em encerramento anormal. O braço de limpeza em stream() distingue GeneratorExit (desconexão do consumidor - cai o estado sem ceder, uma vez que nenhum consumidor permanece) dos erros do lado do provedor (produz subagent_end defensivo e depois aumenta novamente).

  • Para despachos paralelos do mesmo tipo de subagente, cada invocação tem seu próprio tool_call_id. Prefira tool_call_id para tokens de roteamento e volte para source somente quando tool_call_id == "".

  • subagent_end.summary é o texto de resposta final do subagente — a mesma string que o agente pai verá como o valor de retorno da ferramenta task.

Fluxos de trabalho duráveis reproduzem a chamada interrupt() nativa do LangGraph e traduzem seu ID nativo recém-gerado para a posição de atividade OE registrada anteriormente. Consulte Interrupção e retomada do Durable LangGraph para o fluxo completo de suspensão, repetição e Command(resume=...) e seus sites de chamada de código.

Consulte docs/api.md para a superfície App/LingGraph gerada automaticamente. Para a aparência do Memory (métodos, tipos de retorno, regras de identidade), consulte Agent-engine-sdk-memory e sua matriz de capacidade.

Variável de ambiente
Default
Descrição

MDB_AGENTIC_STORE_DB

mdb_store

Nome de base para o armazenamento MongoDB por projeto usado para checkpoints LangGraph (somente modo AER). O escopo/descoberta do projeto ainda se aplica, a menos que seja substituído abaixo.

CHECKPOINT_DB_NAME

(desconfigurar)

Nome exato do banco de dados MongoDBSaver quando definido. Ignora o escopo e a descoberta do projeto . Opte por DBs de checkpoint compartilhados de tempo de execução duplo (definidos no pod AER do agente env / SecretRefs).

CHECKPOINTER_SERVER_SELECTION_TIMEOUT

5.0

Segundos para a seleção do servidor de checkpointer do MongoDB antes que o checkpoint IO falhe.

CHECKPOINTER_CONNECT_TIMEOUT

5.0

Segundos para o estabelecimento da conexão do checkpointer do MongoDB .

CHECKPOINTER_SOCKET_TIMEOUT

15.0

Segundos para leituras/gravações do soquete do checkpointer do MongoDB .

Por padrão, o checkpoint do LangGraph thread_id é session_id:workspace_id. Os agentes podem substituir isso por @app.resolve_thread_id (valor de retorno usado textualmente em novos e currículos). As chaves personalizadas são invisíveis para as pesquisas de histórico /query/sessions* do Atlas Agent Engine, que ainda usam apenas as chaves padrão derivadas da sessão/espaço de trabalho. Os agentes que ignoram o escopo do espaço de trabalho também possuem isolamento de colisão dentro do banco de dados de checkpoint .

A viagem no tempo do LangGraph corrigiria a origem thread_id. Em vez disso, o Atlas Agent Engine cria uma nova sessão. As sessões de checkpoint nativo copiam um checkpoint concluído para uma nova thread; ramificação de sessões de fluxo de trabalho durável do estado validado pelo OE reconstruído em arranhões protegidos. Consulte Session fork vs LangGraph time-travel.

Documentos de aprendizado da plataforma (o que é fluxo de trabalho durável, primitivos, habilitações, restrições): fluxo de trabalho durável. O modelo de repetição compartilhado de Ferramenta e LLM é descrito em Identidade de atividade durável. Consulte Subgrafos compilados duráveis e Delegação de agente profundo durável para obter diagramas de sequência completos, exemplos e mapas de site de chamada de código. Somente os efeitos roteados pelos wrappers seguros de LLM e Ferramentas do Atlas Agent Engine participam de registros/replays duráveis. Para uma repetição durável da ferramenta, o ToolCall deve vir do wrapper LLM seguro e ser executado por meio de uma ferramenta retornada por app.get_tools().

Fluxos de trabalho duráveis não expõem a função dinâmica `Send< https://docs.langchain.com/oss/python/langgraph/graph-api#send>'__ fa-out. O checkpoint normal da plataforma rejeita escritas Send criadas pelo aplicativo. Os gráficos criados por app.deep_agent() são uma exceção opaca porque o LangChain usa Send internamente para rotear ToolsCalls; essa compatibilidade privada não torna a Send uma API de aplicação compatível. Em vez disso, use bordas de gráfico fixas, subgráficos compilados ou delegação de tarefas do Open Agent. Os fluxos de trabalho dos pontos de verificação nativos não são afetados.

As leituras são somente com escopo. O histórico de sessões expande cada Atlas Agent Engine session_id apenas para sua chave composta com escopo de espaço de trabalho; a chave simples sem escopo nunca é consultada depois que o escopo do espaço de trabalho é conhecido, porque as chaves vazias são legíveis e graváveis por todos os espaços de trabalho no armazenamento compartilhado. Portanto, os checkpoints legados escritos antes da existência do escopo não são mais atendidos pelos endpoints do histórico; não adicione novamente o fallback. Um escopo vazio é legítimo somente em tempos de execução explicitamente sem escopo (desenvolvimento / testes locais, não APP_ID). AERs gerenciados carregam REQUIRE_PROJECT_SCOPED_DB; se APP_ID estiver ausente lá, as leituras e as gravações falharão fechadas em vez de confiar no espaço de trabalho do fio ou usar chaves simples. Os usuários de produção de chaves personalizadas ainda devem tratar a exclusividade da chave de checkpoint dentro de um banco de dados compartilhado como de propriedade do agente.

  • Python >= 3.11

  • uv

uv sync --extra dev

Para as mesmas verificações executadas de CI (lint + formato + pyright + testes), use o executor unificado: ./scripts/test.sh agent-engine-sdk-langgraph da raiz do repositório.

uv run pytest
uv run pyright
make docs
# Check for lint errors
uv run ruff check src
# Auto-fix lint errors
uv run ruff check --fix src
# Format code
uv run ruff format src
Avalie esta página