A medida que los agentes de IA se vuelven más autónomos y capaces, su papel está cambiando de asistentes pasivos a actores proactivos.Los grandes modelos de lenguaje (LLM) de hoy no solo generan texto: ejecutan tareas, acceden a APIs, modifican bases de datos e incluso controlan la infraestructura. Los agentes de IA están tomando acciones que una vez estaban reservadas estrictamente para los usuarios humanos, ya sea programando una reunión, desplegando un servicio o accediendo a un documento sensible. , de Un solo comando alucinado, una advertencia mal entendida o un permiso demasiado amplio pueden resultar en fugas de datos, violaciones de la conformidad o sistemas rotos. When agents operate without guardrails they can inadvertently make harmful or unauthorized decisions Por eso la integración Los flujos de trabajo son esenciales para la seguridad y la responsabilidad de los agentes. human-in-the-loop (HITL) es un marco diseñado para permitir a los agentes de IA con la capacidad de de la acción, permitiendo al mismo tiempo . Solicitud de acceso MCP de Permit.io request humans to remain the final decision-makers Solicitud de acceso MCP de Permit.io Construido en y integrado en frameworks de agentes populares como y , este sistema le permite insertar flujos de trabajo de aprobación directamente en sus aplicaciones alimentadas por LLM. Permiso.io LangChain LangGraph En este tutorial aprenderás: Por qué la delegación de permisos sensibles a los humanos es crucial para una IA confiable, Cómo el Protocolo de Contexto Modelo (MCP) de Permit.io permite flujos de trabajo de solicitudes de acceso, Cómo construir un sistema en el mundo real que combine la inteligencia de LLM con la supervisión humana, utilizando la característica interrupt() de LangGraph. Antes de sumergirnos en nuestros pasos de aplicación y implementación de demostración, discutiremos brevemente la importancia de delegar permisos de IA a los humanos. Por qué la delegación de permisos de IA a los humanos es crítica Los agentes de IA son poderosos, pero, como todos sabemos, no son infalibles. Siguen instrucciones, pero no entienden el contexto como lo hacen los humanos.Generan respuestas, pero no pueden juzgar las consecuencias.Y cuando esos agentes se integran en sistemas reales – herramientas bancarias, dashboards internos, controles de infraestructura – eso es una brecha peligrosa. En este contexto, todo lo que puede ir mal es bastante claro: Agentes excesivamente permisivos: Los LLM pueden recibir acceso a herramientas que no deben tocar, ya sea por diseño o por accidente. Llamadas a herramientas alucinadas: Los agentes pueden fabricar comandos, argumentos o IDs que nunca existieron. Falta de auditabilidad: Sin puntos de control humanos, no hay un registro claro de quién aprobó qué, o por qué. Delegation is the solution. En lugar de dar a los agentes poder sin control, les damos un protocolo: “Puedes preguntar, pero el hombre decide”. Por la introducción Aprobación en los puntos clave de decisión, usted obtiene: human-in-the-loop (HITL) Seguridad: Evitar acciones irreversibles antes de que ocurran. Responsabilidad: Requiere un registro humano explícito para operaciones de alta cuota. Control: Deja que las personas establezcan las reglas: quién puede aprobar, qué puede ser aprobado y cuándo. Es la diferencia entre un agente Algo y un agente para hacer algo. Hacer Solicitar Y es exactamente lo que El MCP permite la solicitud de acceso. Permiso.io Solicitud de acceso MCP de Permit.io Es una parte fundamental de Model Context Protocol (MCP) es una especificación que proporciona a los agentes de IA acceso seguro y consciente de las políticas a herramientas y recursos. The Access Request MCP Permiso.io Piensa en él como un puente entre y . LLMs that want to act humans who need control Lo que hace Permit's Access Request MCP permite a los agentes de IA: to restricted resources (e.g., "Can I access this restaurant?") Request access Solicitar la aprobación para realizar operaciones sensibles (por ejemplo, "¿Puedo pedir este plato restringido?") Espere la entrada humana antes de proceder—a través del mecanismo de interrupción() de LangGraph Lograr la solicitud y la decisión de auditoría y cumplimiento Dentro de los escenarios, se utiliza capacidades de autorización construidas para apoyar: Permiso.io ReBAC (Relationship-Based Access Control) y otras políticas de autorización de grano fino (FGA). Aprobación de flujos de trabajo Elementos respaldados por políticas que funcionan a través de UI, API y contextos LLM rebaño Autorización de granos finos (FGA) Aprobación de flujos de trabajo Elementos apoyados por la política Plug-and-play con LangChain y LangGraph El MCP de Permit se integra directamente en el y El Ecosistema: LangChain MCP Adapter LangGraph Puede exponer Permit Elements como herramientas compatibles con LangGraph. Puede parar el agente con interrupt() cuando se produzcan acciones sensibles. Puede reanudar la ejecución basada en decisiones humanas reales. Es la forma más fácil de No es necesario un backend personalizado. inject human judgment into AI behavior Entendiendo la implementación y sus beneficios, entremos en nuestra aplicación demo. Lo que vamos a construir - Descripción general de la aplicación de demostración En este tutorial vamos a crear un En la que un de ellos. real-time approval workflow AI agent can request access or perform sensitive actions, but only a human can approve Categoría: Sistema de Ordenamiento de Alimentos Familiares Para ver cómo el MCP de Permit puede ayudar a habilitar un flujo de trabajo HITL en una aplicación de usuario, modelaremos Para una familia: food ordering system Los padres pueden acceder y administrar todos los restaurantes y platos. Los niños pueden ver objetos públicos, pero deben solicitar acceso a restaurantes restringidos o platos caros. Cuando un niño presenta una solicitud, un padre la recibe para su revisión y debe aprobarla explícitamente o rechazarla antes de proceder a la acción. Este caso de uso refleja un patrón común: “Los agentes pueden ayudar, pero los humanos deciden”. Tecnología Stack Construiremos este agente habilitado por HITL usando: Permit.io - Gestiona la autorización, roles, políticas y aprobaciones Permitir MCP Server - Exponer Permitir flujos de trabajo como herramientas que el agente puede usar Adaptadores MCP de LangChain - Puentes que permiten las herramientas MCP de LangChain en LangGraph y LangChain LangGraph - Orquesta el flujo de trabajo del agente con interrupt() soporte Gemini 2.0 Flash - LLM ligero, multimodal utilizado como motor de razonamiento del agente Python - El adhesivo que lo sostiene todo Usted acabará con un sistema de trabajo donde los agentes pueden colaborar con los humanos para garantizar un comportamiento seguro y intencional, utilizando políticas reales, herramientas reales y aprobaciones en tiempo real. A repository with the full code for this application is available here. Un repositorio con el código completo para esta aplicación está disponible aquí. Tutorial paso a paso En esta sección, analizaremos cómo implementar un sistema de agentes humanos totalmente funcional utilizando y el Langgraph. Permiso.io Vamos a cubrir: Modelo de permisos con permiso Configuración del permiso MCP Server Crear un cliente LangGraph + LangChain MCP Añadiendo Human-in-the-Loop con interrupt() Ejecutar el flujo de trabajo completo Vamos a entrar en ella - Modelo de permisos con permiso Comenzaremos definiendo las reglas de acceso de su sistema dentro del Esto le permite modelar qué usuarios pueden hacer qué y qué acciones deben desencadenar un flujo de aprobación. Descargar Dashboard Create a ReBAC Resource Navegación a la página de la barra lateral, a continuación: Policy Haz clic en la pestaña de recursos Clic para crear un recurso Nombre del producto: Restaurantes Under , define two roles: ReBAC Options parent child-can-order Haz clic en Save Ahora, vamos a la Tab y asignación de permisos: Policy Editor Parental: acceso completo (crear, leer, actualizar, borrar) Enfermería infantil: Leer Set Up Permit Elements Vaya a la Tab de la barra lateral. en la Sección, clic . Elements User Management Create Element Configure the element as follows: : Restaurant Requests Name : ReBAC Resource Roles Configure elements based on : restaurants Resource Type Role permission levels Level 1 – Workspace Owner: parent Assignable Roles: child-can-order Click Crear En la tarjeta de elementos recién creada, haga clic en Obtener código y tome nota de la identificación de configuración: solicitudes de restaurante. Add Operation Approval Elements Create a new element: Operation Approval : Dish Approval Name : restaurants Resource Type Click Crear Then create an element: Approval Management : Dish Requests Name Haga clic en Obtener código y copie el identificador de configuración: dish-requests. Add Test Users & Resource Instances Navegación a Directorios > Instancias Click Add Instance : restaurants Resource Type : Instance Key pizza-palace : Default Tenant (or your working tenant) Tenant Cambiar a la pestaña de usuarios Click Add User : Key joe : Instance Access restaurants:pizza-palace#parent Click Save Create another user with the key henry Don’t assign a role Once Permit is configured, we’re ready to clone the MCP server and connect your policies to a working agent. Configuración del permiso MCP Server Con sus políticas modeladas en el panel de control de Permit, es hora de llevarlas a la vida configurando el un servicio local que expone su solicitud de acceso y flujos de aprobación como herramientas que un agente de IA puede usar. Permit MCP server Clone and Install the MCP Server Comience clonando el repositorio del servidor MCP y configurando un entorno virtual. git clone <https://github.com/permitio/permit-mcp> cd permit-mcp # Create virtual environment, activate it and install dependencies uv venv source .venv/bin/activate # For Windows: .venv\\Scripts\\activate uv pip install -e . Add Environment Configuration Creación a archivo en la raíz del proyecto basado en el , y llenarlo con los valores correctos de su configuración de Permiso: .env .env.example bash CopyEdit RESOURCE_KEY=restaurants ACCESS_ELEMENTS_CONFIG_ID=restaurant-requests OPERATION_ELEMENTS_CONFIG_ID=dish-requests TENANT= # e.g. default LOCAL_PDP_URL= PERMIT_API_KEY= PROJECT_ID= ENV_ID= Puede recuperar estos valores utilizando los siguientes recursos: Localidad_PDP_URL PERMIT_API clave Proyecto_ID Env_ID ☀️ Nota: Estamos utilizando para este tutorial para apoyar la evaluación de ReBAC y las pruebas de baja latencia y offline. Permit Local PDP (Punto de Decisión de Políticas) Start the Server Con todo en su lugar, ahora puede ejecutar el servidor MCP localmente: uv run -m src.permit_mcp Una vez que el servidor se ejecute, expondrá sus elementos de permiso configurados (petición de acceso, gestión de aprobación, etc.) como herramientas que el agente puede llamar a través del protocolo MCP. Crear un cliente LangGraph + LangChain MCP Ahora que el servidor Permit MCP está en funcionamiento, construiremos un cliente de agente de IA que pueda interactuar con él. Utilice un LLM alimentado por Gemini para decidir qué acciones tomarDinámicamente invocar herramientas de MCP como request_access, approve_operation_approval, etc. Se ejecuta completamente dentro de un flujo de trabajo de LangGraph Pausa para la revisión humana usando interrupt() (en la sección siguiente) Conectemos los puntos. Install Required Dependencies Dentro de su directorio de proyectos MCP, instale los paquetes necesarios: uv add langchain-mcp-adapters langgraph langchain-google-genai Esto te da: Adaptadores langchain-mcp: Convierte automáticamente las herramientas Permit MCP en herramientas compatibles con LangGraph Langgraph: para orquestar flujos de trabajo basados en gráficos langchain-google-genai: Para interactuar con Gemini 2.0 Flash Add Google API Key Necesitarás una clave de Utilización de Gemini. Google y el estudio Añade la clave a tu El archivo: .env GOOGLE_API_KEY=your-key-here Build the MCP Client Crear un archivo con el nombre en su proyecto Root. client.py Dividiremos este archivo en bloques lógicos: Imports and Setup Start by importing dependencies and loading environment variables: import os from typing_extensions import TypedDict, Literal, Annotated from dotenv import load_dotenv from langchain_google_genai import ChatGoogleGenerativeAI from langgraph.graph import StateGraph, START, END from langgraph.types import Command, interrupt from langgraph.checkpoint.memory import MemorySaver from langgraph.prebuilt import ToolNode from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client from langchain_mcp_adapters.tools import load_mcp_tools import asyncio from langgraph.graph.message import add_messages Then, load the environment and set up your Gemini LLM: load_dotenv() global_llm_with_tools = None llm = ChatGoogleGenerativeAI( model="gemini-2.0-flash", google_api_key=os.getenv('GOOGLE_API_KEY') ) Tell LangGraph how to communicate with the running MCP server: Configure MCP Server Parameters server_params = StdioServerParameters( command="python", args=["src/permit_mcp/server.py"], ) Define el estado de agente compartido: class State(TypedDict): messages: Annotated[list, add_messages] and the : Define Workflow Nodes graph builder Here’s the logic to route between calling the LLM and invoking tools: async def call_llm(state): response = await global_llm_with_tools.ainvoke(state["messages"]) return {"messages": [response]} def route_after_llm(state) -> Literal[END, "run_tool"]: return END if len(state["messages"][-1].tool_calls) == 0 else "run_tool" async def setup_graph(tools): builder = StateGraph(State) run_tool = ToolNode(tools) builder.add_node(call_llm) builder.add_node('run_tool', run_tool) builder.add_edge(START, "call_llm") builder.add_conditional_edges("call_llm", route_after_llm) builder.add_edge("run_tool", "call_llm") memory = MemorySaver() return builder.compile(checkpointer=memory) En el código anterior, hemos definido un nodo LLM y su borde condicional, que se dirige a la nodo si hay una llamada de herramientas en el mensaje del estado, o termina el gráfico. También hemos definido una función para configurar y compilar el gráfico con un puntero de verificación en memoria. run_tool A continuación, agrega la siguiente línea de código para fluir la respuesta del gráfico y agrega una loop de chat interactiva, que se ejecutará hasta que se salga explícitamente. and an : Stream Output and Handle Chat Input, infinite loop for user interaction async def stream_responses(graph, config, invokeWith): async for event in graph.astream(invokeWith, config, stream_mode='updates'): for key, value in event.items(): if key == 'call_llm': content = value["messages"][-1].content if content: print('\\n' + ", ".join(content) if isinstance(content, list) else content) async def chat_loop(graph): while True: try: user_input = input("\\nQuery: ").strip() if user_input in ["quit", "exit", "q"]: print("Goodbye!") break sys_m = """ Always provide the resource instance key during tool calls, as the ReBAC authorization model is being used. To obtain the resource instance key, use the list_resource_instances tool to view available resource instances. Always parse the provided data before displaying it. If the user has initially provided their ID, use that for subsequent tool calls without asking them again. """ invokeWith = {"messages": [ {"role": "user", "content": sys_m + '\\n\\n' + user_input}]} config = {"configurable": {"thread_id": "1"}} await stream_responses(graph, config, invokeWith) except Exception as e: print(f"Error: {e}") Final Assembly Add the main entry point where we will convert the Permit MCP server tool to LangGraph-compatible tools, bind our LLM to the resulting tools, set up the graph, draw it to a file, and fire up the chat loop: python CopyEdit async def main(): async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools = await load_mcp_tools(session) llm_with_tools = llm.bind_tools(tools) graph = await setup_graph(tools) global global_llm_with_tools global_llm_with_tools = llm_with_tools with open("workflow_graph.png", "wb") as f: f.write(graph.get_graph().draw_mermaid_png()) await chat_loop(graph) if __name__ == "__main__": asyncio.run(main()) Lastly, Run the Client Una vez que hayas guardado todo, inicia el cliente: uv run client.py After running, a new image file called se creará, lo que muestra el gráfico. workflow_graph.png Con todo configurado, ahora podemos especificar consultas como esta: Query: My user id is henry, request access to pizza palace with the reason: I am now 18, and the role child-can-order Query: My user id is joe, list all access requests Your agent is now able to call MCP tools dynamically! Añadiendo Human-in-the-Loop con interrupt() Con su cliente MCP con LangGraph en funcionamiento, las herramientas de Permit ahora se pueden invocar automáticamente. como conceder acceso a un recurso restringido o aprobar una operación de alto riesgo? sensitive, Aquí es donde se encuentra Langgraph Se hace útil. interrupt() Ahora vamos a añadir a interceptar y interrumpir el flujo de trabajo cada vez que el agente intenta invocar herramientas críticas como: human approval node aprobar_acceso_requerimiento Aprueban - Aprueban Se pedirá a un hombre que la herramienta antes de que el agente proceda. manually approve or deny Define the Human Review Node En la parte superior de su Archivo (antes de ), añade la siguiente función: client.py setup_graph async def human_review_node(state) -> Command[Literal["call_llm", "run_tool"]]: """Handle human review process.""" last_message = state["messages"][-1] tool_call = last_message.tool_calls[-1] high_risk_tools = ['approve_access_request', 'approve_operation_approval'] if tool_call["name"] not in high_risk_tools: return Command(goto="run_tool") human_review = interrupt({ "question": "Do you approve this tool call? (yes/no)", "tool_call": tool_call, }) review_action = human_review["action"] if review_action == "yes": return Command(goto="run_tool") return Command(goto="call_llm", update={"messages": [{ "role": "tool", "content": f"The user declined your request to execute the {tool_call.get('name', 'Unknown')} tool, with arguments {tool_call.get('args', 'N/A')}", "name": tool_call["name"], "tool_call_id": tool_call["id"], }]}) Este nodo verifica si la herramienta que se llama se considera “alto riesgo”. Update Graph Routing Modificar el función de modo que la herramienta llama la ruta al nodo de revisión humano en lugar de correr inmediatamente: route_after_llm def route_after_llm(state) -> Literal[END, "human_review_node"]: """Route logic after LLM processing.""" return END if len(state["messages"][-1].tool_calls) == 0 else "human_review_node" Wire in the HITL Node Actualizar el Función para agregar el Como un nodo en el gráfico: setup_graph human_review_node async def setup_graph(tools): builder = StateGraph(State) run_tool = ToolNode(tools) builder.add_node(call_llm) builder.add_node('run_tool', run_tool) builder.add_node(human_review_node) # Add the interrupt node here builder.add_edge(START, "call_llm") builder.add_conditional_edges("call_llm", route_after_llm) builder.add_edge("run_tool", "call_llm") memory = MemorySaver() return builder.compile(checkpointer=memory) Handle Human Input During Runtime Por último, vamos a mejorar su función para detectar cuando el gráfico se interrumpe, pedir una decisión, y reanudar con la entrada humana utilizando . stream_responses Command(resume={"action": user_input}) Después de ejecutar el cliente, el gráfico no debería parecer así: Después de ejecutar el cliente, su diagrama gráfico ( ) ahora incluirá un nodo de revisión humana entre las etapas de ejecución del LLM y la herramienta: workflow_graph.png This ensures that Cada vez que el agente intenta tomar una decisión que pueda alterar los permisos o eludir las restricciones. you remain in control Con esto, ha añadido con éxito la supervisión humana a su agente de IA, sin reescribir sus herramientas o la lógica de backend. Conclusión En este tutorial, hemos construido un agente de IA seguro y consciente del ser humano usando . Permit.io’s Access Request MCP , de LangGraph , y Adaptadores LangChain MCP Solicitud de acceso MCP de Permit.io Lenguas Adaptadores LangChain MCP En lugar de dejar al agente operar sin control, le dimos el poder de Acceso y Tal como lo haría un miembro del equipo. request defer critical decisions to human users, We covered: Cómo modelar permisos y flujos de aprobación usando Permit Elements y ReBAC Cómo exponer esos flujos a través del servidor Permit MCP Cómo construir un cliente con LangGraph que invoca estas herramientas de forma natural Y cómo insertar verificaciones humanas en tiempo real (HITL) usando interrupt() ¿Quieres ver la demo completa en acción? . GitHub Repo Further Reading - Segurar la colaboración de IA a través de un portal de permisos Permite MCP GitHub Repo Adaptadores LangChain MCP Permitir políticas de rebaja LangGraph interrupt() Referencia