Guía principiante para la automatización de flujos de trabajo con OpenAI, LangChain y API integradas
Este es unContent Creation, Multimodal AIflujo de automatización del dominio deautomatización que contiene 33 nodos.Utiliza principalmente nodos como If, Set, Code, Merge, Webhook. Guía de iniciación a la automatización de flujos de trabajo con OpenAI, LangChain e integración de API
- •Punto final de HTTP Webhook (n8n generará automáticamente)
- •Pueden requerirse credenciales de autenticación para la API de destino
- •Clave de API de OpenAI
Nodos utilizados (33)
Categoría
{
"meta": {
"instanceId": "cfcdd4aa7acb600106c0a4bff4e6959e8e3b32b3b8cbc7d93531b2a4c9012a32"
},
"nodes": [
{
"id": "0a919d77-d00e-46a4-9dd4-c89f16cb5467",
"name": "Inicio Aquí - Disparador Manual",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-400,
288
],
"parameters": {},
"typeVersion": 1
},
{
"id": "af159130-a22f-4a30-a426-3c3dece6777b",
"name": "Nota de Bienvenida",
"type": "n8n-nodes-base.stickyNote",
"position": [
-528,
-128
],
"parameters": {
"color": 4,
"width": 348,
"height": 596,
"content": "## Welcome to n8n!\n\nThis is a **Sticky Note** - used for documentation.\n\n### What you'll learn:\n1. **Triggers** - How workflows start\n2. **Data Processing** - Manipulating data\n3. **Conditionals** - Making decisions\n4. **API Calls** - External integrations\n5. **AI Agents** - Using LangChain\n\n👉 Click \"Execute Workflow\" to start!"
},
"typeVersion": 1
},
{
"id": "7e354aac-bf00-4137-b6a2-fb96971b27a9",
"name": "Establecer Datos Iniciales",
"type": "n8n-nodes-base.set",
"position": [
-48,
288
],
"parameters": {
"options": {}
},
"typeVersion": 3.3
},
{
"id": "597d33d2-acf4-4f37-8d9b-b91b8e632500",
"name": "Acerca del Nodo Set",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
-128
],
"parameters": {
"color": 5,
"width": 340,
"height": 592,
"content": "## Set Node\n\n**Purpose:** Create or modify data fields\n\n**Key Features:**\n- Add new fields to your data\n- Set static or dynamic values\n- Support for strings, numbers, booleans, arrays, objects\n\n**Expressions:**\n- `={{ $now }}` - Current timestamp\n- `={{ $workflow.name }}` - Workflow name\n- `={{ $json.fieldName }}` - Access previous data"
},
"typeVersion": 1
},
{
"id": "6ed38d45-da78-4c65-80c3-31622b13df7a",
"name": "Nodo Code - Procesamiento Personalizado",
"type": "n8n-nodes-base.code",
"position": [
320,
288
],
"parameters": {
"jsCode": "// Code Node - Write custom JavaScript\n\n// Access all input items\nconst items = $input.all();\n\n// Process each item\nconst results = items.map((item, index) => {\n const data = item.json;\n \n return {\n json: {\n // Keep original data\n ...data,\n // Add new calculated fields\n doubled_number: data.sample_number * 2,\n message_length: data.message.length,\n processed_at: new Date().toISOString(),\n item_index: index,\n // Example of string manipulation\n uppercase_message: data.message.toUpperCase(),\n // Example array\n tags: ['beginner', 'tutorial', 'n8n']\n }\n };\n});\n\nreturn results;"
},
"typeVersion": 2
},
{
"id": "1721a18e-125b-4b05-a49a-61751809244d",
"name": "Acerca del Nodo Code",
"type": "n8n-nodes-base.stickyNote",
"position": [
192,
-176
],
"parameters": {
"color": 5,
"width": 340,
"height": 648,
"content": "## Code Node\n\n**Purpose:** Execute custom JavaScript\n\n**Available Context:**\n- `$input.all()` - All input items\n- `$input.first()` - First item only\n- `$json` - Current item data\n\n**Built-in Libraries:**\n- lodash, moment, luxon\n- mathjs, uuid, crypto\n\n**Pattern:**\n```javascript\nconst items = $input.all();\nconst results = items.map(item => ({\n json: { ...item.json, newField: 'value' }\n}));\nreturn results;\n```"
},
"typeVersion": 1
},
{
"id": "b1b6de48-2d84-4133-a9ca-c40efd8d40cb",
"name": "Condición IF - Enrutar Datos",
"type": "n8n-nodes-base.if",
"position": [
688,
288
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "condition-001",
"operator": {
"type": "number",
"operation": "smaller"
},
"leftValue": "={{ $json.sample_number }}",
"rightValue": 50
}
]
}
},
"typeVersion": 2
},
{
"id": "dd24f45a-9770-49ee-bf1d-dafce878acb1",
"name": "Acerca del Nodo IF",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
-160
],
"parameters": {
"color": 5,
"width": 340,
"height": 636,
"content": "## IF Node\n\n**Purpose:** Conditional branching\n\n**Outputs:**\n- ✅ **True** - Condition met\n- ❌ **False** - Condition not met\n\n**Comparison Types:**\n- Number: equals, larger, smaller\n- String: equals, contains, regex\n- Boolean: true, false\n- Array: contains, length\n\n**Logic:**\n- AND - All conditions must be true\n- OR - Any condition can be true"
},
"typeVersion": 1
},
{
"id": "982434c7-64a0-46b3-a3d0-ce388c5a3447",
"name": "Datos de Rama Verdadera",
"type": "n8n-nodes-base.set",
"position": [
976,
128
],
"parameters": {
"options": {}
},
"typeVersion": 3.3
},
{
"id": "d418f9a5-197b-4754-a242-e41130fdfd37",
"name": "Datos de Rama Falsa",
"type": "n8n-nodes-base.set",
"position": [
976,
320
],
"parameters": {
"options": {}
},
"typeVersion": 3.3
},
{
"id": "35c673ad-958d-45fd-bf70-a659862ad007",
"name": "Unir Ambas Ramas",
"type": "n8n-nodes-base.merge",
"position": [
1280,
224
],
"parameters": {
"mode": "combine",
"options": {}
},
"typeVersion": 3
},
{
"id": "a8fa8326-b655-4f81-81b5-6188ac70213b",
"name": "Acerca del Nodo Merge",
"type": "n8n-nodes-base.stickyNote",
"position": [
1152,
-160
],
"parameters": {
"color": 5,
"width": 340,
"height": 540,
"content": "## Merge Node\n\n**Purpose:** Combine data streams\n\n**Modes:**\n- **Append** - Stack items\n- **Combine by Position** - Merge paired items\n- **Combine by Fields** - Join on matching values\n- **Multiplex** - Create combinations\n\n**Use Cases:**\n- Reunite split branches\n- Join data from different sources\n- Create data combinations"
},
"typeVersion": 1
},
{
"id": "e68f97f4-e769-4e19-b005-81afe32e19bd",
"name": "Solicitud HTTP - Obtener Usuarios",
"type": "n8n-nodes-base.httpRequest",
"position": [
-16,
944
],
"parameters": {
"url": "https://jsonplaceholder.typicode.com/users",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "aec22fa9-c3b0-493f-9e7d-18396bbc89e7",
"name": "Acerca de Solicitud HTTP",
"type": "n8n-nodes-base.stickyNote",
"position": [
-144,
480
],
"parameters": {
"color": 6,
"width": 360,
"height": 656,
"content": "## HTTP Request Node\n\n**Purpose:** Call external APIs\n\n**Methods:**\n- GET - Retrieve data\n- POST - Create data\n- PUT/PATCH - Update data\n- DELETE - Remove data\n\n**Authentication:**\n- None, Basic Auth, OAuth2\n- API Key, Bearer Token\n\n**Example:** Fetching from JSONPlaceholder API\n\n💡 **Tip:** Test APIs with free endpoints first!"
},
"typeVersion": 1
},
{
"id": "2a386f39-b829-4fa6-9feb-a3514cdce8e0",
"name": "Dividir Array de Usuarios",
"type": "n8n-nodes-base.splitOut",
"position": [
320,
944
],
"parameters": {
"options": {},
"fieldToSplitOut": "data"
},
"typeVersion": 1
},
{
"id": "b7224087-b8e0-4aa3-ac02-420d8cf48e85",
"name": "Acerca de Split Out",
"type": "n8n-nodes-base.stickyNote",
"position": [
224,
480
],
"parameters": {
"color": 6,
"width": 308,
"height": 648,
"content": "## Split Out Node\n\n**Purpose:** Convert arrays to individual items\n\n**Example:**\nBefore: 1 item with array of 10 users\nAfter: 10 separate items\n\n**Why?**\n- Process each item individually\n- Apply conditions per item\n- Send separate API calls\n\n**Pattern:**\n```\nHTTP Request → Split Out → Process Each\n```"
},
"typeVersion": 1
},
{
"id": "ae144427-e63f-47d6-9e3a-a01fff3eba3f",
"name": "Extraer Campos de Usuario",
"type": "n8n-nodes-base.set",
"position": [
576,
944
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "assignment-001",
"name": "user_name",
"type": "string",
"value": "={{ $json.name }}"
},
{
"id": "assignment-002",
"name": "user_email",
"type": "string",
"value": "={{ $json.email }}"
},
{
"id": "assignment-003",
"name": "company",
"type": "string",
"value": "={{ $json.company.name }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "9a02665d-32f7-41d3-8961-584d39a24fde",
"name": "OpenAI API - Generar Dato Curioso",
"type": "n8n-nodes-base.httpRequest",
"position": [
864,
944
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"options": {},
"sendBody": true,
"sendHeaders": true,
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "model",
"value": "gpt-4o-mini"
},
{
"name": "messages",
"value": "=[{\"role\": \"user\", \"content\": \"Generate a fun fact about {{ $json.user_name }}'s company: {{ $json.company }}\"}]"
},
{
"name": "temperature",
"value": "0.7"
},
{
"name": "max_tokens",
"value": "100"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "openAiApi"
},
"typeVersion": 4.2
},
{
"id": "f06c7f4c-8577-472d-bdd2-ffea5d6f4abf",
"name": "Acerca de OpenAI",
"type": "n8n-nodes-base.stickyNote",
"position": [
736,
480
],
"parameters": {
"color": 6,
"width": 360,
"height": 652,
"content": "## OpenAI Integration\n\n**Purpose:** AI-powered processing\n\n**Setup:**\n1. Add OpenAI credentials\n2. Use HTTP Request node\n3. Configure model & parameters\n\n**Models:**\n- gpt-4o - Most capable\n- gpt-4o-mini - Fast & cost-effective\n- gpt-3.5-turbo - Legacy\n\n**Parameters:**\n- temperature: 0-1 (creativity)\n- max_tokens: Response length"
},
"typeVersion": 1
},
{
"id": "27523b11-3a92-4b5f-b457-811ee30e188f",
"name": "Webhook - Recibir Datos",
"type": "n8n-nodes-base.webhook",
"position": [
1344,
944
],
"webhookId": "88d6f248-451b-477a-b754-1b9ce326e67c",
"parameters": {
"path": "beginner-webhook",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "40cee779-e780-4766-a057-3457c27dc1ea",
"name": "Acerca de Webhooks",
"type": "n8n-nodes-base.stickyNote",
"position": [
1264,
480
],
"parameters": {
"color": 7,
"width": 492,
"height": 660,
"content": "## Webhook Node\n\n**Purpose:** HTTP endpoint for external systems\n\n**URL Pattern:**\n`https://your-instance/webhook/path-name`\n\n**Use Cases:**\n- Receive form submissions\n- Handle API callbacks\n- Integrate with third-party services\n\n**Test It:**\n```bash\ncurl -X POST \\\n https://your-n8n/webhook/beginner-webhook \\\n -H 'Content-Type: application/json' \\\n -d '{\"name\":\"Test\",\"value\":123}'\n```"
},
"typeVersion": 1
},
{
"id": "5d91498e-32e9-4f9e-89aa-3d4a079f1109",
"name": "Enviar Respuesta Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1552,
944
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ { \"status\": \"success\", \"received\": $json.body, \"processed_at\": $now.toISO() } }}"
},
"typeVersion": 1.1
},
{
"id": "2bf3244b-8dfd-4cb8-8daa-47e6617d91f0",
"name": "Disparador de Chat - Asistente de IA",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
-400,
1568
],
"webhookId": "beginner-chat-assistant",
"parameters": {
"public": true,
"options": {
"title": "n8n Beginner's Assistant",
"subtitle": "Your AI helper for learning n8n",
"responseMode": "lastNode"
},
"initialMessages": "Hello! I'm an n8n AI assistant. Ask me anything about n8n workflows!\n\nTry asking:\n- How do I use the IF node?\n- What's the Code node for?\n- How do I call external APIs?"
},
"typeVersion": 1.1
},
{
"id": "ac85dfaf-f606-44b5-b2eb-65f3988f1874",
"name": "Acerca de Chat + IA",
"type": "n8n-nodes-base.stickyNote",
"position": [
-528,
1168
],
"parameters": {
"color": 3,
"width": 380,
"height": 576,
"content": "## Chat Trigger + AI Agent\n\n**Purpose:** Create AI chatbots\n\n**Components:**\n1. **Chat Trigger** - Receives messages\n2. **AI Agent** - Processes with AI\n3. **Memory** - Remembers context\n4. **Tools** - Actions agent can take\n\n**Perfect for:**\n- Customer support bots\n- Internal assistants\n- Interactive tutorials\n\n**Try it:** Open the chat interface and ask questions!"
},
"typeVersion": 1
},
{
"id": "597eee76-e669-439b-a063-d1efc915d67f",
"name": "Memoria de Búfer de Ventana",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
192,
1536
],
"parameters": {
"contextWindowLength": 10
},
"typeVersion": 1.2
},
{
"id": "29e89cad-0ecb-4bd4-9c70-1b11a78a8dad",
"name": "Modelo de Chat OpenAI",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
0,
1536
],
"parameters": {
"options": {
"maxTokens": 500,
"temperature": 0.7
}
},
"typeVersion": 1
},
{
"id": "c835131a-07ec-4e77-82bc-aaf9644d17b7",
"name": "Herramienta: Hora Actual",
"type": "@n8n/n8n-nodes-langchain.toolCode",
"position": [
448,
1584
],
"parameters": {
"name": "get_current_time",
"description": "Returns the current date and time. Use this when users ask about the current time, date, day of week, etc."
},
"typeVersion": 1
},
{
"id": "68818e55-db72-4660-9810-709877f2f90b",
"name": "Herramienta: Calculadora",
"type": "@n8n/n8n-nodes-langchain.toolCode",
"position": [
640,
1584
],
"parameters": {
"name": "calculate",
"jsCode": "// Parse input string and calculate\nconst input = $input;\nconst expression = typeof input === 'string' ? input : JSON.stringify(input);\n\ntry {\n // Simple eval for basic math (in production, use a proper math parser)\n const result = eval(expression.replace(/[^0-9+\\-*/().\\s]/g, ''));\n return JSON.stringify({ result: result, expression: expression });\n} catch (error) {\n return JSON.stringify({ error: 'Invalid mathematical expression', input: expression });\n}",
"description": "Performs mathematical calculations. Input should be a mathematical expression as a string, like '5 + 3' or '10 * 2'."
},
"typeVersion": 1
},
{
"id": "9bfbc587-b48c-445d-afa4-32ed86183ce5",
"name": "Agente de IA - Asistente n8n",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
0,
1232
],
"parameters": {
"options": {
"systemMessage": "=You are a helpful n8n workflow assistant for beginners.\n\nYour role:\n- Explain n8n concepts in simple terms\n- Provide examples and best practices\n- Help users understand nodes and their connections\n- Be encouraging and patient\n\nKey Topics:\n- Triggers (Manual, Webhook, Schedule, Chat)\n- Data Processing (Set, Code, Edit Fields)\n- Logic (IF, Switch, Merge)\n- Integrations (HTTP Request, APIs)\n- AI Features (Chat Trigger, AI Agent, Tools)\n\nAlways:\n- Use clear, beginner-friendly language\n- Provide practical examples\n- Suggest next learning steps"
},
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "3c1d13db-6558-4296-9928-cebe9163de4c",
"name": "Acerca de Herramientas de IA",
"type": "n8n-nodes-base.stickyNote",
"position": [
400,
1152
],
"parameters": {
"color": 3,
"width": 360,
"height": 588,
"content": "## AI Agent Tools\n\n**Purpose:** Give AI capabilities\n\n**Tool Types:**\n- **Code Tools** - Custom JavaScript\n- **Workflow Tools** - Call other workflows\n- **HTTP Tools** - API calls\n- **Vector Store** - Knowledge retrieval\n- **Calculator** - Math operations\n\n**How it works:**\n1. User asks question\n2. AI decides which tool to use\n3. Tool executes and returns result\n4. AI formats response"
},
"typeVersion": 1
},
{
"id": "098527ad-4c10-4865-8fd4-922bf0e8a3ef",
"name": "Programar - Cada Lunes 9 AM",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-400,
976
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * 1"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "051f647b-7a26-495a-b268-3c32f4b97185",
"name": "Acerca de Programaciones",
"type": "n8n-nodes-base.stickyNote",
"position": [
-528,
480
],
"parameters": {
"color": 7,
"width": 360,
"height": 660,
"content": "## Schedule Trigger\n\n**Purpose:** Run workflows on schedule\n\n**Options:**\n- **Seconds/Minutes** - Short intervals\n- **Hours** - Hourly tasks\n- **Days** - Daily jobs\n- **Weeks** - Weekly reports\n- **Cron** - Custom schedules\n\n**Example Cron:**\n- `0 9 * * 1` - Monday 9 AM\n- `0 */6 * * *` - Every 6 hours\n- `0 0 1 * *` - First day of month\n\n**Use Cases:**\n- Daily reports\n- Data synchronization\n- Cleanup tasks"
},
"typeVersion": 1
},
{
"id": "1d7cb17d-2ef8-4500-8199-e48e3505b831",
"name": "Resumen Final",
"type": "n8n-nodes-base.set",
"position": [
1552,
224
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "final-summary",
"name": "workflow_summary",
"type": "string",
"value": "=Workflow executed successfully!\n\nProcessed items: {{ $items().length }}\nTimestamp: {{ $now.toISO() }}\n\nThis beginner workflow demonstrated:\n- Data creation and manipulation\n- Conditional logic\n- API integrations\n- AI capabilities\n\nNext: Explore n8n documentation and build your own workflows!"
}
]
}
},
"typeVersion": 3.3
}
],
"pinData": {},
"connections": {
"7e354aac-bf00-4137-b6a2-fb96971b27a9": {
"main": [
[
{
"node": "6ed38d45-da78-4c65-80c3-31622b13df7a",
"type": "main",
"index": 0
}
]
]
},
"68818e55-db72-4660-9810-709877f2f90b": {
"ai_tool": [
[
{
"node": "9bfbc587-b48c-445d-afa4-32ed86183ce5",
"type": "ai_tool",
"index": 0
}
]
]
},
"982434c7-64a0-46b3-a3d0-ce388c5a3447": {
"main": [
[
{
"node": "35c673ad-958d-45fd-bf70-a659862ad007",
"type": "main",
"index": 0
}
]
]
},
"d418f9a5-197b-4754-a242-e41130fdfd37": {
"main": [
[
{
"node": "35c673ad-958d-45fd-bf70-a659862ad007",
"type": "main",
"index": 1
}
]
]
},
"29e89cad-0ecb-4bd4-9c70-1b11a78a8dad": {
"ai_languageModel": [
[
{
"node": "9bfbc587-b48c-445d-afa4-32ed86183ce5",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"2a386f39-b829-4fa6-9feb-a3514cdce8e0": {
"main": [
[
{
"node": "ae144427-e63f-47d6-9e3a-a01fff3eba3f",
"type": "main",
"index": 0
}
]
]
},
"c835131a-07ec-4e77-82bc-aaf9644d17b7": {
"ai_tool": [
[
{
"node": "9bfbc587-b48c-445d-afa4-32ed86183ce5",
"type": "ai_tool",
"index": 0
}
]
]
},
"ae144427-e63f-47d6-9e3a-a01fff3eba3f": {
"main": [
[
{
"node": "9a02665d-32f7-41d3-8961-584d39a24fde",
"type": "main",
"index": 0
}
]
]
},
"35c673ad-958d-45fd-bf70-a659862ad007": {
"main": [
[
{
"node": "1d7cb17d-2ef8-4500-8199-e48e3505b831",
"type": "main",
"index": 0
}
]
]
},
"597eee76-e669-439b-a063-d1efc915d67f": {
"ai_memory": [
[
{
"node": "9bfbc587-b48c-445d-afa4-32ed86183ce5",
"type": "ai_memory",
"index": 0
}
]
]
},
"27523b11-3a92-4b5f-b457-811ee30e188f": {
"main": [
[
{
"node": "5d91498e-32e9-4f9e-89aa-3d4a079f1109",
"type": "main",
"index": 0
}
]
]
},
"b1b6de48-2d84-4133-a9ca-c40efd8d40cb": {
"main": [
[
{
"node": "982434c7-64a0-46b3-a3d0-ce388c5a3447",
"type": "main",
"index": 0
}
],
[
{
"node": "d418f9a5-197b-4754-a242-e41130fdfd37",
"type": "main",
"index": 0
}
]
]
},
"e68f97f4-e769-4e19-b005-81afe32e19bd": {
"main": [
[
{
"node": "2a386f39-b829-4fa6-9feb-a3514cdce8e0",
"type": "main",
"index": 0
}
]
]
},
"2bf3244b-8dfd-4cb8-8daa-47e6617d91f0": {
"main": [
[
{
"node": "9bfbc587-b48c-445d-afa4-32ed86183ce5",
"type": "main",
"index": 0
}
]
]
},
"0a919d77-d00e-46a4-9dd4-c89f16cb5467": {
"main": [
[
{
"node": "7e354aac-bf00-4137-b6a2-fb96971b27a9",
"type": "main",
"index": 0
}
]
]
},
"6ed38d45-da78-4c65-80c3-31622b13df7a": {
"main": [
[
{
"node": "b1b6de48-2d84-4133-a9ca-c40efd8d40cb",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Avanzado - Creación de contenido, IA Multimodal
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Compartir este flujo de trabajo