[{"content":"","date":null,"permalink":"https://ntwk.es/es/categories/ai/","section":"Categories","summary":"","title":"AI"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/ai/","section":"Tags","summary":"","title":"AI"},{"content":"","date":null,"permalink":"https://ntwk.es/es/posts/","section":"Artículos del Blog Tecnológico","summary":"","title":"Artículos del Blog Tecnológico"},{"content":"","date":null,"permalink":"https://ntwk.es/es/categories/","section":"Categories","summary":"","title":"Categories"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/crm/","section":"Tags","summary":"","title":"CRM"},{"content":"","date":null,"permalink":"https://ntwk.es/es/categories/data-engineering/","section":"Categories","summary":"","title":"Data Engineering"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/dataengineering/","section":"Tags","summary":"","title":"DataEngineering"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/embeddings/","section":"Tags","summary":"","title":"Embeddings"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/enterpriseai/","section":"Tags","summary":"","title":"EnterpriseAI"},{"content":"Feeding the Machine Right: CRM Data Ingestion for AI Systems #How to preprocess and architect heterogeneous business data for vector databases, semantic search, and AI agents — and why mastering this is becoming one of the most valuable skills in enterprise AI.\n1. The Hidden Problem Nobody Talks About #If your AI system gives shallow, unreliable, or contextually blind answers about your customers, your first instinct is probably to blame the model. Swap the LLM, tune the embeddings, adjust the retrieval parameters. Most teams go through several cycles of this before arriving at an uncomfortable truth: the model was never the problem.\n\u0026ldquo;Garbage in, garbage out\u0026rdquo; is the oldest principle in computing. In the AI era, it hasn\u0026rsquo;t changed — it\u0026rsquo;s just better dressed. Teams now feed garbage into systems sophisticated enough to sound confident about it, which makes the problem harder to spot and more expensive to fix.\nThe reality observed across enterprise AI projects is consistent: the majority of underperforming RAG systems, AI agents, and semantic search implementations fail not because of model choice or vector database configuration, but because of how the source data was prepared — or wasn\u0026rsquo;t. Your embedding model is probably fine. Your documents are the problem.\nCRM data makes this especially treacherous. Unlike a PDF corpus or a product catalogue, CRM data isn\u0026rsquo;t flat — it has a shape. A contact belongs to a company, holds a role, carries a communication history, links to open tasks, and sits somewhere in a commercial pipeline. That shape is the meaning. When you flatten it into tabular rows or key-value pairs, you don\u0026rsquo;t just lose formatting — you destroy the relational context that makes the data intelligible.\nThis is what makes CRM ingestion one of the hardest data preparation problems in enterprise AI. It\u0026rsquo;s not a document problem. It\u0026rsquo;s not a tabular data problem. It\u0026rsquo;s a living relational graph problem — and most ingestion pipelines treat it like neither.\nThere\u0026rsquo;s also a human gap worth naming early. Companies are investing in AI engineers and vector infrastructure, but almost none are investing in people who know how to bridge complex business data and AI systems. That gap is quietly responsible for a large share of disappointing enterprise AI projects — and it is, increasingly, a significant professional opportunity.\nThis article is about closing that gap. We\u0026rsquo;ll dissect the generic structure of CRM data, identify where ingestion goes wrong, and build up a clear architecture for preprocessing and structuring heterogeneous business data so that AI systems — agents, semantic search, automated workflows — can actually reason with it.\n2. How CRM Data Is Actually Shaped #Before you can design an ingestion architecture, you need an accurate mental model of what CRM data actually is. Not as a database schema — as a living information structure.\nAt its core, every CRM revolves around two root entities: Companies and Contacts. Everything else either describes them or records what happened between them and your organisation.\nCOMPANIES └── CONTACTS (via typed relationships) ├── COMMUNICATIONS (emails · calls · meetings) ├── TASKS \u0026amp; CALENDAR └── COMMERCIAL PIPELINE (leads → offers → sales) But this hierarchy is already a simplification. The reality is a web, not a tree.\nThe root entities and their relationships\nA Company is more than a name and an address. It carries sector, size, segment, location, status — and it can be related to other companies (subsidiaries, partners, parent groups).\nA Contact is a person, but their connection to a company is itself a rich object. It has a type (employee, advisor, partner), a role, a department, a seniority level — and critically, it has a time dimension. A contact may have been a procurement manager at a company from 2019 to 2022, and a director somewhere else since then. That temporal typing is business-critical context that flat ingestion almost always discards.\nContacts also carry multiplicity: one person may have two work emails, a personal address, three phone numbers, and profiles on LinkedIn, Twitter, and WhatsApp. These aren\u0026rsquo;t just contact details — they\u0026rsquo;re identity anchors that link communications across channels. And like roles, they can be time-scoped: a phone number that was valid last year may not be today.\nThe communications layer\nAbove the entity layer sits a rich layer of interaction records. These are the dynamic, event-based data: things that happened, as opposed to things that are.\nEmails, calls, and meetings are all communications — but they are not the same shape of data:\nAn email has a sender, one or more recipients, a subject, a body, attachments, and a direction (inbound or outbound). It can link multiple contacts across different companies in a single record. A call has a direction, a duration, a timestamp, and typically a short outcome note. Its \u0026ldquo;content\u0026rdquo; is often sparse — a summary rather than a transcript. A meeting has attendees (potentially many), a scheduled time, an agenda, and sometimes minutes or outcomes. It is inherently multi-party. This asymmetry matters enormously for ingestion. Treating these three as interchangeable \u0026ldquo;communication records\u0026rdquo; loses the structural differences that make each type semantically distinct.\nTasks and calendar: the intentions layer\nIf communications record what happened, tasks and calendar events record what is supposed to happen. They are the intentions and commitments layer of the CRM.\nA task is assigned to someone, has a type (follow-up call, send proposal, escalate issue), a creation date, a due date, a status, and a description. A calendar event is scheduled, involves specific participants, and occupies a defined time slot.\nBoth are linked to contacts and companies — and both carry their own temporal weight. An overdue task tells a very different story than a completed one. An upcoming meeting with a key contact is strategically relevant in a way that a past one may not be.\nThe commercial pipeline\nThe pipeline is where relational complexity peaks. A lead represents early-stage interest — qualified or unqualified, with a source and a probability. As it progresses it becomes an opportunity, then an offer.\nAn offer is a formal commercial document: it has a value, a currency, a status (draft, sent, negotiation, won, lost), and dates. It is directed at a contact, associated with a company, and linked to the history of communications and tasks that led to it.\nFor the purposes of ingestion, an offer is best treated as a self-contained object — rich enough to carry its commercial context without requiring its full relational history to be meaningful.\nThe dark matter: free-text fields\nScattered throughout every CRM are notes, comments, descriptions, and memo fields. These are the dark matter of business data — unstructured, inconsistent, and almost always ignored by ingestion pipelines.\nThey are also often the most informationally dense content in the entire system. A salesperson\u0026rsquo;s note on a contact — \u0026ldquo;prefers not to be called on Mondays, very price-sensitive, key decision-maker despite junior title\u0026rdquo; — contains strategic intelligence that no structured field can capture.\nAny serious ingestion architecture must have a strategy for this layer.\nWhat this map reveals is that CRM data is neither a document collection nor a relational table. It is a heterogeneous, temporally-aware, multi-entity graph — and the ingestion architecture must reflect that reality.\n3. The Four Most Common Ingestion Mistakes #Most CRM ingestion failures don\u0026rsquo;t announce themselves. The pipeline runs, the vectors are written, the system responds. It just responds poorly — with shallow answers, missed context, and retrieval that feels random. The mistakes that cause this are surprisingly consistent across teams and organisations.\nMistake 1: Tabular Dumping\nThe most common mistake is also the most understandable. Your CRM data lives in a relational database. You export it. You get tables. You feed the tables.\nThe result is vectors built from rows like:\nid: 1042 | name: John Smith | company: Acme Corp | email: john@acme.com | status: active | created: 2021-03-01 Each row becomes one vector. The embedding model receives a string that reads like a spreadsheet cell — because it is one. There is no narrative, no context, no relationship to anything else. The vector captures the statistical pattern of that string, which is close to nothing meaningful.\nTabular dumping treats a relational graph as if it were a flat file. The structure that gives the data its meaning — who this person is, what they\u0026rsquo;ve said, what they\u0026rsquo;re worth to the business — is entirely absent.\nMistake 2: Key-Value Feeding\nA variation of the above, and equally widespread. Instead of raw CSV rows, teams serialize their records into JSON or property strings and embed those:\n{name: \u0026#34;John Smith\u0026#34;, role: \u0026#34;buyer\u0026#34;, company: \u0026#34;Acme Corp\u0026#34;, phone: \u0026#34;+34-600-123456\u0026#34;} This feels more structured — and it is, for a database. But embedding models are not databases. They are trained on natural language. They do not parse JSON syntax. They do not understand that name: and role: are field labels. What they receive is a token stream that bears no resemblance to how humans describe a person, a relationship, or a business situation.\nThe vectors produced are geometrically incoherent — scattered in embedding space in ways that make meaningful similarity search nearly impossible.\nMistake 3: No Metadata Glue\nEven teams that produce reasonably structured text for their vectors often neglect the payload — the structured metadata that should travel alongside every vector in the database.\nWithout metadata, a vector is an orphan. You can find it via similarity search, but you cannot:\nFilter results by company, contact, date range, or entity type Link it back to its source record in the relational database Assemble multi-entity context for an agent (e.g. \u0026ldquo;give me all communications and open tasks for this contact\u0026rdquo;) Understand what type of thing you\u0026rsquo;ve retrieved — is this an email? A task? An offer? Metadata is the connective tissue of a semantic index. Skipping it produces a vector database that can only do one thing — global similarity search — and does it without any ability to scope, filter, or join. That is a fraction of what the architecture is capable of.\nMistake 4: Raw Concatenation Instead of Semantic Documents\nThe subtlest and most damaging mistake. Teams aware of the previous three problems often arrive at a solution that looks right but isn\u0026rsquo;t: they concatenate all the fields of a record into a single text string and embed that.\n\u0026#34;John Smith buyer Acme Corp john@acme.com +34-600-123456 Barcelona active 2021-03-01\u0026#34; Or slightly better:\n\u0026#34;Name: John Smith. Role: buyer. Company: Acme Corp. Email: john@acme.com. City: Barcelona.\u0026#34; This is closer — but it still fails. Embedding models perform best on text that carries semantic intent: text that means something the way a sentence means something. A list of field-value pairs has syntactic structure but minimal semantic density. It doesn\u0026rsquo;t tell the model who John Smith is, what his relationship to Acme Corp means, or why he matters.\nThe gap between \u0026ldquo;Name: John Smith. Role: buyer.\u0026rdquo; and \u0026ldquo;John Smith is the senior buyer at Acme Corp, responsible for procurement decisions in the logistics division\u0026rdquo; is not cosmetic. In embedding space, these two representations land in very different places — and only one of them clusters meaningfully with related concepts like purchasing authority, vendor relationships, and contract negotiations.\nMistake 5: Ignoring Free-Text and Over- or Under-Fragmenting\nTwo further mistakes often accompany the ones above.\nThe first is systematically ignoring the free-text fields — notes, comments, call summaries, meeting minutes — that live throughout a CRM. These are treated as too messy, too inconsistent, too hard to process. In reality they are frequently the highest signal content in the entire system. A salesperson\u0026rsquo;s note carries intent, nuance, and strategic context that no structured field can encode.\nThe second is getting the granularity wrong in either direction. Over-fragmentation — creating one vector per field, embedding phone numbers and email addresses in isolation — produces meaningless atomic units. Under-fragmentation — stuffing an entire company record with all its contacts, communications, and history into a single document — produces bloated, unfocused vectors that retrieve everything and nothing at once.\nBoth extremes destroy the semantic coherence that makes retrieval useful.\nThe common thread\nEvery one of these mistakes shares a root cause: the ingestion was designed around the convenience of the source data, not around the needs of the AI system consuming it. CRM data was structured for human operators and relational queries. Before it can serve an AI, it must be deliberately restructured — transformed from records into knowledge. That transformation is the subject of the rest of this article.\n4. The Principle of Semantic Granularity #If there is one principle that governs everything in CRM data ingestion, it is this: one semantic idea, one document.\nA document, in this context, is not a file. It is the unit of meaning you present to the embedding model — the coherent, focused chunk of text that becomes one vector in your index. Getting this unit right is the single most impactful decision in your entire ingestion architecture.\nWhy focus matters\nEmbedding models map text into a geometric space where similar meanings cluster together. That geometry only works when each input carries a single, coherent semantic signal. When you mix concerns — stuffing a contact\u0026rsquo;s identity, their full email history, three open tasks, and an offer into one document — the resulting vector is pulled in too many directions at once. It ends up representing everything vaguely rather than anything precisely. Retrieval suffers accordingly.\nThe entity type itself tells you what the right unit is. CRM data splits naturally into two kinds of things: static entities — things that are (companies, contacts) — and dynamic entities — things that happened (emails, calls, tasks, offers). These two kinds require different document shapes. A contact document describes a person and their context. An email document describes an event. Treating them the same way is a category error.\nThe unit of retrieval\nA practical way to find the right granularity: ask what an agent or a search query would want to get back. If the answer is \u0026ldquo;everything about this person\u0026rdquo;, the unit is the contact. If the answer is \u0026ldquo;the email where pricing was discussed\u0026rdquo;, the unit is the individual email. Design your documents around the retrieval use case, not around the source schema.\nThis leads to a clean mapping:\nEntity Granularity Company One document per company Contact One document per contact Email One document per email Call One document per call Meeting One document per meeting Task One document per task Offer One document per offer The multi-value collapse rule\nA contact may have five phone numbers, three email addresses, and profiles on four social networks. These should not become separate documents — they are attributes of a single entity, not independent semantic units. Collapse all of them into the contact document\u0026rsquo;s text and carry them as arrays in the metadata payload. Embedding a phone number in isolation produces a vector that means nothing to anyone.\nRollup documents\nGranular documents are essential for precise retrieval. But AI agents often need a broader view — a 360° summary of a company or contact to orient themselves before diving into specifics. For this, introduce a second document type: the rollup.\nA rollup is a synthetically generated summary, produced periodically or on data change, that condenses the key facts about an entity into one coherent paragraph: who the company is, who the main contacts are, what the recent communication has been, what is commercially open. It sits alongside the granular documents in the vector index — not replacing them, but serving as a high-quality entry point for context assembly.\nThe one-paragraph test\nWhen in doubt about whether a document is correctly scoped, apply this test: what would a well-informed human write about this entity in one paragraph? If the answer flows naturally, the scope is right. If it either feels like a one-liner (too narrow) or requires multiple paragraphs to cover the basics (too wide), adjust.\nGranularity in embedding is like focus in photography. Too wide, and nothing is sharp. Too close, and you lose all context. The right focal length is the one that makes the subject clear — and that focal length is different for a company, a contact, an email, and an offer. Getting it right for each entity type is the craft at the centre of this discipline.\n5. Architecting the Ingestion Pipeline #With the right granularity defined, the next question is structural: how do you physically organise the data that flows into your ingestion pipeline? This section lays out the architecture — from the shape of a single document to the division of responsibility across your storage infrastructure.\nThe universal document unit\nEvery ingestion record, regardless of entity type, follows the same three-field structure:\n{ \u0026#34;id\u0026#34;: \u0026#34;contact_042\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;John Smith is the senior buyer at Acme Corp...\u0026#34;, \u0026#34;metadata\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;contact\u0026#34;, \u0026#34;company_id\u0026#34;: \u0026#34;001\u0026#34;, ... } } id — a unique, stable identifier scoped to entity type. Never reuse IDs across types. text — the natural-language narrative that gets embedded. This is the only field the model sees. metadata — the structured payload that travels with the vector. Never embedded, always queryable. This three-field contract is the foundation everything else builds on.\nCrafting the text field: narrative templates\nThe text field is not generated — it is engineered. Each entity type gets its own prose template, designed to read as natural language and omit null fields entirely.\nA contact template might produce:\n\u0026ldquo;John Smith is the senior buyer at Acme Corp, responsible for procurement in the logistics division. Reachable at john@acme.com and +34-600-123456. Active relationship since March 2021. Prefers email contact. Key decision-maker for software acquisitions.\u0026rdquo;\nAn email template might produce:\n\u0026ldquo;Inbound email from John Smith (Acme Corp) on 14 September 2024, subject: Contract renewal Q4. Raised concerns about pricing on the logistics module, requested a revised proposal before end of September.\u0026rdquo;\nThe template pulls from structured fields for the skeleton and folds in free-text notes as the final sentence — capturing the dark matter without losing the structure. Any field that is null is simply omitted. Never write \u0026ldquo;phone: null.\u0026rdquo;\nThe metadata payload: structure that enables filtering\nThe metadata object carries everything the text field does not — in structured, queryable form:\n{ \u0026#34;type\u0026#34;: \u0026#34;contact\u0026#34;, \u0026#34;company_id\u0026#34;: \u0026#34;001\u0026#34;, \u0026#34;contact_id\u0026#34;: \u0026#34;042\u0026#34;, \u0026#34;segment\u0026#34;: \u0026#34;enterprise\u0026#34;, \u0026#34;date\u0026#34;: \u0026#34;2021-03-01\u0026#34;, \u0026#34;status\u0026#34;: \u0026#34;active\u0026#34; } This payload is what makes your vector index intelligent rather than merely searchable. It enables queries like: \u0026ldquo;find semantically similar contacts, but only within enterprise accounts, active in the last 12 months.\u0026rdquo; Semantic similarity alone cannot do this. Metadata payload combined with vector search can.\nEvery document must carry at minimum: entity type, its own ID, and the IDs of its parent entities (company_id, contact_id where applicable).\nThe two-database architecture\nThe ingestion architecture rests on a clean division of responsibility between two systems:\n┌─────────────────────┐ │ SOURCE CRM / DB │ └──────────┬──────────┘ │ ┌──────────▼──────────┐ │ INGESTION PIPELINE │ │ (transform + enrich)│ └────────┬────────────┘ │ ┌──────────────┴──────────────┐ │ │ ┌──────────▼──────────┐ ┌────────────▼────────────┐ │ VECTOR DB │ │ RELATIONAL DB │ │ (Qdrant / similar) │ │ (PostgreSQL / similar) │ │ │ │ │ │ • Vectors │ │ • Full records │ │ • Metadata payload │ │ • Relational joins │ │ • Semantic search │ │ • Source of truth │ │ • Filtered retrieval│ │ • Audit / history │ └──────────────────────┘ └──────────────────────────┘ The relational database is the source of truth — it holds the full, structured records and handles all relational queries. The vector database is the semantic index — it holds vectors and metadata payloads, and handles similarity search and filtered retrieval. Neither replaces the other.\nThe bridge between them is the shared entity ID. Every vector point in Qdrant references a record in PostgreSQL. When retrieval returns a vector, the ID in its payload is used to fetch the full record from the relational store.\nJSONL as the ingestion format\nThe practical format for passing data to your embedding pipeline is JSONL — one JSON object per line, one line per document:\n{\u0026#34;id\u0026#34;:\u0026#34;contact_042\u0026#34;,\u0026#34;text\u0026#34;:\u0026#34;John Smith is the senior buyer...\u0026#34;,\u0026#34;metadata\u0026#34;:{...}} {\u0026#34;id\u0026#34;:\u0026#34;email_1847\u0026#34;,\u0026#34;text\u0026#34;:\u0026#34;Inbound email from John Smith...\u0026#34;,\u0026#34;metadata\u0026#34;:{...}} JSONL streams efficiently, requires no loading of the full file into memory, and maps directly to one vector write per line. Batch your files by entity type — one file per entity — so that re-ingestion after a schema change or model update can be scoped to only the affected type without reprocessing everything.\nRe-ingestion should be triggered by three events: a record update in the source CRM, a change to the narrative template, or a change of embedding model. Build this trigger into your pipeline from the start — retrofitting it later is costly.\n6. The Relational Glue: Making Cross-Entity Retrieval Work #Semantic search finds documents. But real business questions don\u0026rsquo;t live inside single documents — they span entities, time, and relationship types. \u0026ldquo;What is the current state of our relationship with Acme Corp?\u0026rdquo; requires a contact profile, a communication history, open tasks, and the status of active offers. No single vector answers that. The relational glue is what makes the full answer possible.\nThe linking mechanism: shared entity IDs\nThe architecture is simple in principle: every document\u0026rsquo;s metadata payload carries the IDs of its parent entities. An email document carries contact_id and company_id. A task carries the same. An offer does too. These shared IDs are the connective tissue of the semantic index — they allow retrieval to move across entity types without losing the relational thread.\nemail_1847 → { contact_id: \u0026#34;042\u0026#34;, company_id: \u0026#34;001\u0026#34;, type: \u0026#34;email\u0026#34; } task_0291 → { contact_id: \u0026#34;042\u0026#34;, company_id: \u0026#34;001\u0026#34;, type: \u0026#34;task\u0026#34; } offer_0088 → { contact_id: \u0026#34;042\u0026#34;, company_id: \u0026#34;001\u0026#34;, type: \u0026#34;offer\u0026#34; } contact_042 → { company_id: \u0026#34;001\u0026#34;, type: \u0026#34;contact\u0026#34; } Every vector is individually retrievable by semantic similarity, and collectively queryable by entity relationship. The index becomes a graph you can traverse — not just a list you can search.\nCommunications ↔ Contacts: the interaction layer\nAn email is not a simple two-party exchange. It has a sender, multiple recipients, and potentially contacts from different companies in the same thread. Its metadata must reflect this: carry all participant contact IDs, not just the primary one.\nDirection matters too. An inbound email from a contact who hasn\u0026rsquo;t written in six months tells a very different story than an outbound email that went unanswered. The direction field in metadata is not administrative — it is semantically significant. An agent reasoning about relationship health needs to know who initiated contact and when.\nRetrieving a contact\u0026rsquo;s full communication history is then a metadata filter operation: all documents where contact_id = \u0026quot;042\u0026quot; and type IN [email, call, meeting], ordered by date. The semantic index makes this fast and filterable without touching the relational database for every lookup.\nTasks ↔ Contacts: the intentions layer as relationship signal\nTasks are not to-do lists. In the context of AI retrieval, they are intention signals — structured evidence of what your team believes needs to happen next with a given contact or company.\nAn open task of type \u0026ldquo;send revised proposal\u0026rdquo; linked to a contact tells an agent that a commercial conversation is in progress. An overdue task of type \u0026ldquo;follow-up call\u0026rdquo; that is three weeks past its due date signals a relationship at risk. The temporal metadata — creation date, due date, closing date, status — transforms a task from an administrative record into a diagnostic signal.\nWhen assembling context about a contact, tasks should always be retrieved alongside communications. Together they form a timeline of what happened and what was supposed to happen — the two dimensions an agent needs to reason about relationship state.\nThe commercial pipeline: linking offers to their history\nAn offer does not appear from nowhere. It is the product of a chain of communications, decisions, and tasks — and that chain is what gives it context. When an agent retrieves an offer, it needs to understand not just its value and status, but the relationship history that generated it.\nThis is where the shared ID architecture pays off most clearly. Given an offer, the agent can filter for all emails, calls, and tasks linked to the same contact_id within the relevant date range — reconstructing the commercial conversation that led to the offer without any hardcoded joins. The pipeline becomes navigable by relationship, not just by record.\nThe offer\u0026rsquo;s own document carries its commercial summary: value, status, dates, and the contact it is directed at. The surrounding retrieval context — communications and tasks — provides the narrative. Together they give an agent everything it needs to reason about the commercial opportunity.\nTwo retrieval modes and the agent context assembly pattern\nEvery query in this architecture operates in one of two modes:\nGlobal semantic search — no metadata filter, maximum recall. Used when the agent doesn\u0026rsquo;t know where the answer lives: \u0026ldquo;find any contact who has raised pricing concerns in the last quarter.\u0026rdquo; The search spans all entity types and all companies.\nScoped retrieval — filtered by company_id, contact_id, or type. Used when the agent knows the subject and needs to assemble context: \u0026ldquo;give me everything relevant about Acme Corp.\u0026rdquo;\nThe scoped pattern is the foundation of agent context assembly. The sequence is:\n1. Retrieve the company rollup → orient the agent with a 360° summary 2. Filter by company_id + type:contact → get all active contacts 3. Filter by contact_id + type:[email,call,meeting] → get communication history 4. Filter by contact_id + type:task + status:open → get pending intentions 5. Filter by company_id + type:offer + status:active → get commercial state Each step is a fast metadata filter on the vector index, with semantic similarity used selectively where the content itself matters. The rollup document — generated periodically and always kept fresh — is the entry point that orients every subsequent step.\nThe cost of missing links\nRetrieval without relational context produces a specific failure mode: the right document surfaces, but the agent interprets it incorrectly because it lacks the surrounding context. An email about pricing retrieved in isolation looks like a negotiation. The same email, retrieved with the task that preceded it (\u0026ldquo;prepare revised offer — client is price-sensitive\u0026rdquo;) and the offer that followed it, is a milestone in a commercial story.\nMissing links don\u0026rsquo;t produce obvious errors. They produce plausible but incomplete answers — which in enterprise AI contexts can be more dangerous than obvious failures. The relational glue is not a nice-to-have. It is what separates a semantic search tool from a system that can actually reason about your business.\n7. Before You Embed: The Preprocessing Checklist #Architecture and granularity decisions mean nothing if the data going into the embedding model is dirty, inconsistent, or structurally broken. Preprocessing is the unglamorous work that determines whether everything else performs as designed. This section is a practical checklist — the things that must be right before any record touches an embedding model.\nDocument quality: nulls, templates, and free-text\nThe text field is the only thing the embedding model sees. Its quality is non-negotiable.\nStart with null handling. Every field that has no value must be omitted from the narrative entirely — not written as \u0026ldquo;phone: null\u0026rdquo; or \u0026ldquo;notes: none.\u0026rdquo; Null tokens dilute the semantic signal and push the vector toward meaningless regions of embedding space. If a contact has no recorded phone number, the contact document simply doesn\u0026rsquo;t mention a phone number.\nNext, build and maintain a narrative template for each entity type. The template defines what fields appear, in what order, and in what prose form. It should read as natural language — not a field dump. Templates should be versioned: when a template changes, all documents of that type need to be re-embedded.\nFinally, define a strategy for free-text fields. Notes and comments should be cleaned of obvious noise (duplicate whitespace, encoding artifacts, internal system tags) and appended to the narrative as a final sentence or short paragraph. They should never be the entire document — always anchored to the structured context around them.\nData hygiene: IDs and deduplication\nBefore ingestion, your entity IDs must be stable, unique, and consistent across all systems that will read or write them. An ID that changes between CRM exports, or that means different things in different contexts, will silently corrupt your relational glue.\nDeduplication is equally critical and frequently skipped. CRM systems accumulate duplicate contacts and companies over time — same person entered twice, same company under two slightly different names. Duplicates produce redundant vectors that dilute retrieval and confuse agents. Resolve duplicates in the source data before ingestion, not after.\nTemporal normalization\nCRM data is accumulated over years, across teams, sometimes across system migrations. Date formats are inconsistent. Timezones are missing or wrong. Relative references (\u0026ldquo;last Tuesday\u0026rdquo;) appear in free-text notes.\nNormalize all dates to ISO 8601 format with timezone before ingestion. Store them in metadata as structured fields — not embedded in the text where they become semantic noise. A date in metadata is filterable and sortable. A date in the text field is just a token the model will try to interpret semantically, usually poorly.\nFreshness: rollups and re-ingestion triggers\nA vector index that is not kept fresh becomes a liability. CRM data changes constantly — contacts update their roles, offers change status, tasks get closed. Stale vectors produce stale answers.\nDefine three re-ingestion triggers from the start:\nRecord update — any change to a source record in the CRM triggers re-embedding of the affected document Template change — a revision to any narrative template triggers re-embedding of all documents of that type Model change — replacing the embedding model requires full re-ingestion of the entire index Rollup documents have their own freshness cadence. Because they summarize across multiple entities, they cannot be triggered by a single record update. Generate them on a schedule — daily or weekly depending on data volatility — or on significant events such as a new offer being created or a contact changing role.\nEdge cases: multilingual data and long content\nEnterprise CRM data is rarely monolingual. Sales teams operate across countries, notes are written in the language of the conversation, email bodies mix languages within a single thread. Most embedding models handle multilingual input, but performance degrades when languages are mixed within a single document.\nWhere possible, detect the primary language of each document and keep it consistent. For mixed-language free-text fields, clean aggressively or truncate to the dominant language before embedding.\nLong content — particularly email bodies and meeting minutes — needs a length strategy. Most embedding models have a token limit. Content that exceeds it gets silently truncated, which can mean the most important part of a long email never makes it into the vector. Either summarize long content before embedding (using an LLM as a preprocessing step), or chunk it into overlapping segments with shared metadata, treating each chunk as its own document.\nSensitive data and PII\nBefore any record enters a shared vector index, consider what it contains. CRM data is dense with personally identifiable information — names, contact details, communication content, financial figures. Depending on your jurisdiction and use case, some of this data may be subject to regulatory constraints that affect where it can be stored and who can retrieve it.\nAt minimum: know what PII is in your index, ensure your vector database access controls are as strict as your relational database, and have a deletion strategy. When a contact is deleted from the CRM, their vectors must be deleted from the index — not left as orphaned embeddings that surface in retrieval.\nThe preprocessing checklist\nBefore any entity type goes into your embedding pipeline, verify:\nNull fields omitted from narrative text Narrative template defined, versioned, and reviewed for natural language quality Free-text fields cleaned and integrated into template Entity IDs stable, unique, and consistent across systems Duplicates resolved in source data All dates normalized to ISO 8601 with timezone Re-ingestion triggers defined for record updates, template changes, model changes Rollup generation schedule defined Language consistency checked per document Long content truncation or summarization strategy in place PII inventory completed and access controls verified Deletion propagation strategy confirmed 8. A New Profession Is Emerging #Everything described in this article — the entity mapping, the narrative templates, the granularity decisions, the metadata architecture, the freshness strategy — represents a coherent body of work. It is not software engineering. It is not data science. It is not CRM administration. It sits at the intersection of all three, and right now, almost nobody is trained to do it well.\nThat is about to change.\nA gap that is becoming impossible to ignore\nAs more enterprises move seriously into AI — deploying agents, building semantic search, automating workflows over their business data — the bottleneck is consistently the same: not the models, not the infrastructure, but the knowledge of how to prepare complex, heterogeneous business data for AI consumption.\nThe teams that crack this first are not the ones with the best embedding models or the most sophisticated vector databases. They are the ones with people who understand both sides of the problem — the business data structures that CRM systems encode, and the semantic architecture that AI systems require. That combination is rare, and its value is rising quickly.\nWhat this role looks like\nThe emerging professional in this space needs a specific blend of skills that no single traditional discipline covers:\nA deep familiarity with how business data is structured — not just technically, but semantically. Understanding why a contact-company relationship carries a time dimension, or why an overdue task is a relationship signal, is business domain knowledge, not just data modeling.\nFluency in semantic architecture — how embedding models work, what makes a good document, how vector databases organise and retrieve knowledge, how metadata enables filtering and relational traversal.\nAn engineering instinct for pipelines — ingestion cadences, re-embedding triggers, freshness strategies, deduplication, PII handling. The operational discipline to keep a live index reliable over time.\nAnd perhaps most importantly: the ability to translate between the business question and the data architecture. To look at a CRM schema and see not tables and fields, but a knowledge graph waiting to be unlocked.\nWhy the demand will grow\nEvery organisation that has accumulated years of CRM data is sitting on a knowledge asset that their AI systems cannot yet access — because nobody has built the bridge. As AI agents become standard infrastructure for sales, customer success, and business development teams, that bridge becomes critical path.\nThe organisations that invest in this capability now — building the ingestion architecture, training the people, establishing the practices — will compound that advantage over time. A well-structured semantic index of five years of customer relationships is not something a competitor can replicate quickly. It is institutional knowledge made machine-readable, and it is one of the most defensible assets an AI-enabled business can build.\nThe profession that builds and maintains these systems is emerging now, without a clear name yet, without established training paths, without job titles that have stabilised. That ambiguity is temporary. The need is not.\nIf you have read this article and found yourself thinking \u0026ldquo;someone needs to do this properly in my organisation\u0026rdquo; — that is the signal. The question is whether that someone will be you.\n","date":null,"permalink":"https://ntwk.es/es/posts/post_015/","section":"Artículos del Blog Tecnológico","summary":"How to preprocess and architect heterogeneous business data for vector databases, semantic search, and AI agents — and why mastering this is becoming one of the most valuable skills in enterprise AI.","title":"Feeding the Machine Right: CRM Data Ingestion for AI Systems"},{"content":"Cuando el proyecto importa, las empresas eligen nBCN Software. #Tres décadas de experiencia en ingeniería de software, al encuentro de la tecnología del mañana.\nSomos el socio técnico de confianza para desarrolladores que exigen excelencia y empresas que se niegan a comprometerse. Desde integraciones complejas hasta aplicaciones innovadoras, tenemos un historial comprobado en proyectos de todo el mundo.\nYa sea que necesite modernizar una plataforma heredada, integrar sistemas críticos o incorporar capacidades de IA a producción, entregamos trabajo que resiste la carga del mundo real. No prototipos disfrazados de productos, no atajos ocultos en la arquitectura. Solo ingeniería bien hecha.\nÚltimas Entradas del Blog: # Feeding the Machine Right: CRM Data Ingestion for AI Systems How to preprocess and architect heterogeneous business data for vector databases, semantic search, and AI agents — and why mastering this is becoming one of the most valuable skills in enterprise AI. FileMaker SVG Skill: Give Your AI Assistant FileMaker Icon Superpowers Transform your AI assistant into a FileMaker SVG expert with this comprehensive skill file. Generate, heal, and validate FileMaker-compatible icons using natural language commands in Claude, Cursor, Windsurf, and other AgentSkills-compatible AI tools. Lectura Recomendada # Vibe Code Your FileMaker Apps Democratizing FileMaker Development—Build Sophisticated Interfaces with Just a Description. Powered by FileMaker MCP Server + OData. Qué Hacemos #Nos especializamos en cuatro dominios fundamentales de la ingeniería de software:\nArquitectura de Sistemas Complejos #Cuando sus requisitos superan las soluciones estándar, diseccionamos y construimos sistemas sofisticados desde cero. Aceptamos la complejidad para que sus usuarios no tengan que hacerlo, convirtiendo la lógica de negocio intrincada en aplicaciones que se sienten effortless de operar.\nExplore Nuestro Trabajo →\nDesarrollo FileMaker y Módulos #Proporcionamos módulos probados en producción y listos para el combate que extienden las capacidades de FileMaker con funcionalidad avanzada. Nuestras soluciones eliminan la sobrecarga de desarrollo manteniendo la calidad del código y la consistencia arquitectónica.\nExplore Nuestro Catálogo de Módulos →\nIntegración de Sistemas y APIs #Conectamos sistemas dispares en su stack tecnológico: plataformas de comercio electrónico, pasarelas de pago, WordPress, Salesforce y aplicaciones personalizadas. Las integraciones complejas son nuestra especialidad.\nIntegración de IA e Implementación de LLM #Integramos capacidades de IA en aplicaciones existentes con precisión. Desde sistemas de generación aumentada por recuperación (RAG) hasta implementaciones locales de LLM, implementamos IA en todos los niveles de complejidad manteniendo la seguridad de datos y el rendimiento del sistema.\n¿Por Qué Elegir nBCN? # Profunda Experiencia — Más de 30 años de éxito comprobado en todo el mundo Entendiendo Su Negocio — Nos tomamos el tiempo de aprender cómo trabaja antes de programar Calidad Primero — Cada solución construida con atención al detalle y mejores prácticas Asociación a Largo Plazo — Estamos invertidos en su éxito más allá de la finalización del proyecto Escalable y Seguro — Código de grado de producción que aborda desafíos empresariales reales ¿Listo para Construir Algo Grande? #Cuéntenos qué está construyendo. Le diremos cómo hacer que dure.\nVea Nuestro Portafolio → | Lea Nuestro Blog → | Obtenga Recursos →\n","date":null,"permalink":"https://ntwk.es/es/","section":"nBCN Software","summary":"","title":"nBCN Software"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/rag/","section":"Tags","summary":"","title":"RAG"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/","section":"Tags","summary":"","title":"Tags"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/vectordatabase/","section":"Tags","summary":"","title":"VectorDatabase"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/caldav/","section":"Tags","summary":"","title":"CalDAV"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/carddav/","section":"Tags","summary":"","title":"CardDAV"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/dav/","section":"Tags","summary":"","title":"DAV"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/integraci%C3%B3n/","section":"Tags","summary":"","title":"Integración"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/m%C3%B3dulo/","section":"Tags","summary":"","title":"Módulo"},{"content":"Aplicaciones Pre-empaquetadas y Módulos FileMaker #Nuestros módulos están evolucionando hacia un ecosistema nativo de IA. Desde el procesamiento de documentos y comunicaciones hasta programación e informes, estamos tejiendo grandes modelos de lenguaje y agentes inteligentes en cada módulo que entregamos, convirtiendo utilidades independientes en un conjunto de herramientas coordinado y consciente de IA.\nConstruidos con las mejores prácticas de la industria, documentación completa e integración perfecta en mente, cada módulo proporciona funcionalidad específica para resolver desafíos empresariales comunes. Explore el catálogo a continuación para ver documentación, características y guías de implementación.\n","date":null,"permalink":"https://ntwk.es/es/modules/","section":"Módulos","summary":"","title":"Módulos"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/on-premise/","section":"Tags","summary":"","title":"On-Premise"},{"content":"Servidor DAV # Un servidor CalDAV y CardDAV autoalojado y listo para producción construido sobre Spring Boot, diseñado para organizaciones que necesitan sincronización confiable de calendarios y contactos bajo su propia infraestructura — sin dependencias de nube, tarifas de suscripción, o datos saliendo de las instalaciones.\nLanzado — 1 de Marzo de 2026. Se empareja nativamente con el Módulo FM GCalendar para permitir a tu organización alojar sus propios servicios de calendario de extremo a extremo, con cero dependencia de nube externa. Qué Proporciona # CalDAV — sincronización de calendarios y eventos compatible con RFC 4791 y RFC 5545 (iCalendar) CardDAV — sincronización de contactos y libretas de direcciones compatible con RFC 6352 y RFC 6350 (vCard) Ambos servicios comparten una capa de autenticación unificada, una única base de datos PostgreSQL, y un único endpoint HTTPS — un servidor para desplegar y mantener.\nCumplimiento de Protocolo #El servidor implementa el conjunto completo de métodos WebDAV requeridos por clientes CalDAV y CardDAV:\nMétodo Propósito OPTIONS Anuncio de capacidades (DAV: 1, 2, calendar-access, addressbook) GET / PUT / DELETE CRUD de eventos y contactos PROPFIND Descubrimiento de propiedades a profundidad 0, 1 e infinito REPORT Consultas de calendario y multiget (RFC 4791) MKCALENDAR Creación de colección de calendario (RFC 4791 §5.3.1) Los endpoints de auto-descubrimiento (/.well-known/caldav, /.well-known/carddav) y el descubrimiento de principales (/principals/{username}) están implementados para que los clientes puedan configurarse con solo un nombre de host y credenciales — sin entrada manual de ruta requerida.\nCompatibilidad de Clientes #Probado y verificado con:\nmacOS — Calendar.app y Contacts.app (auto-descubrimiento, sincronización completa, creación de calendarios) iOS / iPadOS — aplicaciones nativas de Calendario y Contactos Android — DAVx⁵ (cliente de sincronización compatible con estándares) Linux — Evolution, Thunderbird, GNOME Online Accounts, KDE Kontact Cualquier otra aplicación compatible con CalDAV / CardDAV La compatibilidad con vCard se maneja automáticamente: el servidor almacena vCards en su formato original y convierte a vCard 3.0 en tiempo de servicio para clientes — como macOS Contacts y Thunderbird — que no soportan vCard 4.0.\nCaracterísticas Principales #Sincronización\nDetección de conflictos basada en ETag en cada creación y actualización Las actualizaciones de CTag (etiqueta de colección) se propagan inmediatamente a todos los clientes REPORT Calendar-query con filtrado por rango de tiempo para sincronización parcial eficiente REPORT Calendar-multiget para recuperación masiva de eventos por UID Soporte de grupos de contactos con formato compatible con Apple Seguridad\nHTTPS / TLS primero — corre en puerto 8443 con soporte SSL/TLS completo Autenticación HTTP Basic con hash de contraseña BCrypt (RFC 2617) Aislamiento de datos por usuario vía control de acceso basado en rutas (/caldav/{username}/, /carddav/{username}/) Operaciones\nBackend PostgreSQL con versionado de esquema Flyway — los cambios de esquema nunca requieren ALTER TABLE manual Perfiles de Spring Boot para entornos dev / prod API de gestión REST para principales, calendarios, eventos, libretas de direcciones y contactos OpenAPI / Swagger UI incluido para exploración de API Endpoint de health check en /api/health para integración de monitoreo Optimización de consultas N+1 con JOIN FETCH explícito — sin degradación de rendimiento a escala Limpieza automática de registro de cambios (retención configurable, predeterminado 30 días) Integración con el Módulo FM GCalendar #El Servidor DAV es el backend on-premise de contraparte del Módulo FM GCalendar. Juntos forman una infraestructura de calendario autoalojada completa:\nEl Módulo FM GCalendar gestiona eventos dentro de FileMaker, sincronizando con Google Calendar o directamente con el Servidor DAV. El Servidor DAV publica esos calendarios y contactos a los dispositivos de cada usuario sobre CalDAV/CardDAV estándar. Los cambios desde cualquier dispositivo se sincronizan de vuelta a través del servidor — sin terceros en el circuito. Esta combinación es la única configuración que da a una organización centrada en FileMaker sincronización de calendario lectura/escritura completa en todos los dispositivos con cero dependencia de nube externa.\nVisión General de Arquitectura #Dispositivos cliente (macOS / iOS / Android / Linux) │ HTTPS (puerto 8443) ▼ Servidor DAV (Spring Boot 3.2 · Java 17 · Jetty) │ ▼ PostgreSQL (principales · calendarios · eventos · libretas de direcciones · contactos) El servidor usa una cadena de filtros de servlet para interceptar métodos WebDAV antes del despachador de Spring, lo que mantiene la capa de manejo de protocolo claramente separada de la API de gestión REST y de Spring Security.\nAPI de Gestión REST #Más allá de los endpoints de protocolo, una API REST completa está disponible para operaciones administrativas:\nRecurso Endpoints Principales (usuarios) CRUD en /api/principals Calendarios CRUD en /api/calendars Eventos CRUD en /api/calendar-objects Libretas de direcciones CRUD en /api/addressbooks Contactos CRUD en /api/contacts Health GET /api/health Todos los endpoints están documentados vía OpenAPI 3.0 — accesibles en /swagger-ui.html y /rapidoc.html en una instancia en ejecución.\nRequisitos de Despliegue # SO Host: Linux (recomendado), macOS o Windows Runtime: Java 17 o posterior Base de datos: PostgreSQL 15+, accesible por red Red: Nombre de host alcanzable o endpoint VPN para conectividad de cliente TLS: Certificado auto-firmado incluido para desarrollo; traiga el suyo propio o use Let\u0026rsquo;s Encrypt para producción # Iniciar (perfil de desarrollo, cert auto-firmado) ./mvnw spring-boot:run # Iniciar (perfil de producción + TLS) ./mvnw -Pprod,tls spring-boot:run RFCs Implementadas # RFC Estándar RFC 4918 WebDAV — protocolo principal RFC 4791 CalDAV — acceso a calendarios RFC 5545 Formato iCalendar RFC 6352 CardDAV — acceso a contactos RFC 6350 Formato vCard RFC 6764 Auto-descubrimiento (endpoints .well-known) RFC 2617 Autenticación HTTP Basic Precios # No hay tienda online. Este sitio no vende módulos directamente. Para compras, presupuestos personalizados, configuraciones agrupadas o solicitudes especiales, por favor contáctenos para que podamos discutir términos, licenciamiento y opciones de implementación. Servidor DAV — Despliegue Base #Despliegue de instancia única en infraestructura del cliente. Incluye servicios CalDAV y CardDAV, configuración HTTPS, configuración de esquema PostgreSQL, API de gestión REST, y aprovisionamiento inicial de principales y colecciones.\nPrecio Despliegue base 950 € Paquete de Integración FM GCalendar #Configuración y verificación de la sincronización bidireccional entre el Módulo FM GCalendar y el Servidor DAV. Incluye pruebas de extremo a extremo con al menos un cliente de escritorio y un cliente móvil.\nPrecio Paquete de integración 350 € Soporte de Implementación #Asistencia in situ o remota para configuración de servidor, configuración de red, instalación de certificados, y onboarding de clientes para hasta cinco usuarios.\nPrecio Soporte de implementación 500 € Soporte de Mantenimiento #| Tarifa | Paquete | Modo | |:|:\u0026mdash;\u0026ndash;|:|:\u0026mdash;\u0026ndash;| | 80 €/hora | Paquete 5 horas | remoto | | 60 €/hora | Paquete 30 horas | remoto | | 120 € | una visita in situ | — |\nVisitas in situ dentro del área de Barcelona.\nActualizaciones #Las actualizaciones principales tienen un precio del 50% del costo de despliegue original.\nLas actualizaciones de mantenimiento son gratuitas.\nGarantía #Garantía funcional permanente e ilimitada contra defectos en el despliegue entregado. La garantía permanece activa indefinidamente, excepto en caso de manipulación o una actualización al runtime Java subyacente, versión de PostgreSQL, o sistema operativo que esté fuera de la matriz de compatibilidad acordada.\n","date":null,"permalink":"https://ntwk.es/es/modules/dav_server/","section":"Módulos","summary":"Servidor CalDAV y CardDAV autoalojado y listo para producción construido sobre Spring Boot. Sincronización confiable de calendarios y contactos en tu propia infraestructura — compatible con RFC, HTTPS-first, respaldado por PostgreSQL, probado con clientes macOS, iOS, Android y Linux. Se empareja nativamente con el Módulo FM GCalendar para una pila de calendario completamente on-premise.","title":"Servidor DAV"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/webdav/","section":"Tags","summary":"","title":"WebDAV"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/agentskills/","section":"Tags","summary":"","title":"AgentSkills"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/automation/","section":"Tags","summary":"","title":"Automation"},{"content":"","date":null,"permalink":"https://ntwk.es/es/categories/development-tools/","section":"Categories","summary":"","title":"Development Tools"},{"content":"","date":null,"permalink":"https://ntwk.es/es/categories/filemaker/","section":"Categories","summary":"","title":"FileMaker"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/filemaker/","section":"Tags","summary":"","title":"FileMaker"},{"content":"FileMaker SVG Skill: Give Your AI Assistant FileMaker Icon Superpowers #Creating SVG icons that work perfectly in FileMaker Pro has always been a challenge. The FileMaker Pro 14 SVG Grammar specification is strict, and even small mistakes can break your button icons. But what if you could automate the entire process?\nWhat This \u0026ldquo;Skill\u0026rdquo; Actually Is #Let me be clear: this isn\u0026rsquo;t a traditional software application or plugin. The FileMaker SVG Icon Builder \u0026ldquo;skill\u0026rdquo; is a comprehensive SKILL.md file that instructs your AI assistant (like Claude, Cursor, Windsurf, or other AgentSkills-compatible agents) to handle everything about FileMaker SVG icons.\nWhen you install this skill, you\u0026rsquo;re essentially giving your AI assistant the complete knowledge base and tools to:\nGenerate FileMaker-compliant SVG code from natural language descriptions Automatically fix existing SVG files that don\u0026rsquo;t meet FileMaker\u0026rsquo;s requirements Validate SVG icons against the FileMaker Pro 14 specification Provide templates and examples for common icon patterns Think of it as a specialized expert that lives inside your AI coding assistant, ready to handle any FileMaker SVG task you throw at it.\nThe SVG Compatibility Problem #If you\u0026rsquo;ve ever tried to create custom SVG icons for FileMaker, you know the pain. Missing XML declarations, wrong namespaces, incompatible coordinate units—these issues can turn a simple icon creation task into hours of debugging.\nThe FileMaker SVG Icon Builder skill solves this problem by providing a complete toolkit for creating, healing, and validating SVG icons that work flawlessly with FileMaker Pro.\nWhat Makes This Skill Special #This isn\u0026rsquo;t just another SVG tool. It\u0026rsquo;s an AgentSkills.io compatible skill that integrates directly with AI agents like Claude Desktop, Windsurf IDE, Cursor, and others. The skill understands FileMaker\u0026rsquo;s specific requirements and handles all the technical details automatically.\nKey Capabilities #Create FileMaker-compliant SVG icons from scratch using natural language descriptions. Just tell the AI what you want, and it generates a properly formatted SVG.\nHeal existing SVGs to fix compatibility issues automatically. The included Python script can fix common problems like missing declarations, wrong namespaces, and coordinate unit issues.\nValidate against FileMaker Pro 14 SVG Grammar to ensure your icons will work perfectly before you even import them.\nTheme integration support with fm_fill for dynamic theming that adapts to your FileMaker solution\u0026rsquo;s color schemes.\nHow It Works in Practice #Installation Across Multiple Platforms #One of the best features is its broad compatibility. The skill works with:\nClaude Desktop - Install directly through the Skills panel Claude Code - Upload the skill file at claude.ai/code Windsurf IDE - Native skill integration Cursor - AI-first code editor support Cline - VS Code extension compatibility The AgentSkills.io standard means you can use the same skill across all these platforms without modification.\nNatural Language Icon Creation #Once installed, creating icons is as simple as:\n\u0026ldquo;Create a FileMaker SVG icon for a save button\u0026rdquo;\n\u0026ldquo;Build a theme-compatible FileMaker button bar icon for user management\u0026rdquo;\n\u0026ldquo;Generate a FileMaker-compatible trash icon with proper styling\u0026rdquo;\nThe AI understands FileMaker\u0026rsquo;s requirements and generates SVG code that just works.\nAutomated Healing and Validation #The real magic happens when you have existing SVGs that need fixing. The included Python scripts can:\n# Auto-fix compatibility issues python3 scripts/heal_filemaker_svg.py input.svg output.svg # Validate the result python3 scripts/validate_filemaker_svg.py your_icon.svg The healer automatically fixes:\nMissing XML declaration and namespaces Missing width/height attributes Unit symbols in coordinates (px, pt, cm, etc.) Negative radius values Degrees to radians conversion UTF-16 to UTF-8 encoding Complete Toolkit for Developers #The skill comes with everything you need:\nTemplate Assets - Pre-built SVG templates for common patterns like basic shapes, theme buttons, gradients, and reusable symbols.\nComprehensive Documentation - Complete FileMaker Pro 14 SVG Grammar specification with examples and best practices.\nPython Scripts - Automated healing and validation tools for batch processing existing icon libraries.\nReference Materials - Official Claris documentation links and detailed grammar specifications.\nReal-World Benefits #Time Savings #What used to take hours of manual debugging now takes minutes. The automated healing alone can save days of work when migrating existing icon libraries.\nConsistency #Every icon generated follows the same standards, ensuring your entire application has a consistent look and feel that works perfectly with FileMaker\u0026rsquo;s rendering engine.\nFuture-Proof #The AgentSkills.io standard means your investment in this skill pays off across multiple AI platforms and development environments.\nQuality Assurance #Built-in validation means you catch problems before they reach your users, preventing broken icons and inconsistent UI elements.\nGetting Started #The installation process is straightforward:\nDownload the skill file from GitHub Install it in your preferred AI agent Start creating icons with natural language commands For teams, the skill can be shared across multiple development environments, ensuring everyone follows the same standards.\nBeyond Basic Icons #While the skill excels at creating simple button icons, it also supports advanced features:\nGradient Support - Create icons with complex gradients that still comply with FileMaker\u0026rsquo;s requirements.\nSymbol Reuse - Build reusable symbol libraries for consistent icon sets across large applications.\nTheme Integration - Use fm_fill to create icons that automatically adapt to your FileMaker solution\u0026rsquo;s color themes.\nThe Bigger Picture #This skill represents a shift in how we approach FileMaker development. By combining AI agents with domain-specific knowledge, we can automate tedious technical tasks while maintaining the high quality standards that FileMaker developers expect.\nThe AgentSkills.io ecosystem is growing, and tools like this show how AI can enhance rather than replace developer expertise. You still control the design and user experience, but the technical implementation becomes effortless.\nConclusion #The FileMaker SVG Icon Builder skill transforms one of the most frustrating aspects of FileMaker development into a streamlined, automated process. Whether you\u0026rsquo;re creating a single icon or migrating an entire library, this tool ensures your SVG icons work perfectly every time.\nFor FileMaker developers who value both quality and efficiency, this skill isn\u0026rsquo;t just helpful—it\u0026rsquo;s essential.\nGet the skill: FileMaker SVG Icon Builder on GitHub\nLearn more: AgentSkills.io\nOfficial documentation: FileMaker Pro SVG Grammar\n","date":null,"permalink":"https://ntwk.es/es/posts/post_014/","section":"Artículos del Blog Tecnológico","summary":"Transform your AI assistant into a FileMaker SVG expert with this comprehensive skill file. Generate, heal, and validate FileMaker-compatible icons using natural language commands in Claude, Cursor, Windsurf, and other AgentSkills-compatible AI tools.","title":"FileMaker SVG Skill: Give Your AI Assistant FileMaker Icon Superpowers"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/icons/","section":"Tags","summary":"","title":"Icons"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/svg/","section":"Tags","summary":"","title":"SVG"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/api/","section":"Tags","summary":"","title":"API"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/event-driven/","section":"Tags","summary":"","title":"Event-Driven"},{"content":"FileMaker Server Webhooks: The Integration Revolution That Changes Everything #How OData Webhooks Transform FileMaker from Database Platform to Event-Driven Integration Hub #Look, if you\u0026rsquo;ve been building FileMaker solutions for any length of time, you know the pain point I\u0026rsquo;m about to describe. It\u0026rsquo;s the one we\u0026rsquo;ve all learned to work around, the compromise we\u0026rsquo;ve all accepted as \u0026ldquo;just how things are.\u0026rdquo;\nI\u0026rsquo;m talking about real-time integration.\nFor decades, FileMaker has been amazing at what it does—rapid application development that actually works, custom solutions without the enterprise nightmares, getting stuff done fast. But getting FileMaker to play nicely with the rest of the modern software world? That\u0026rsquo;s always been\u0026hellip; let\u0026rsquo;s call it \u0026ldquo;friction.\u0026rdquo;\nWith FileMaker Server 22.0.4, something fundamental just changed.\nThe introduction of OData webhooks isn\u0026rsquo;t just another bullet point in the release notes. This is the kind of feature that makes you rethink what\u0026rsquo;s possible. It repositions FileMaker from being this isolated (albeit powerful) database platform into something that can genuinely hold its own in modern, event-driven architectures.\nAnd honestly? It\u0026rsquo;s about time.\nThe Polling Problem We\u0026rsquo;ve All Just Accepted #Here\u0026rsquo;s the thing. Until now, if you wanted external systems to stay in sync with your FileMaker data, you basically had two options. Both kinda sucked.\nOption 1: Polling. Your external system just keeps asking FileMaker, over and over, \u0026ldquo;Hey, anything changed? How about now? Now? What about now?\u0026rdquo; Every few seconds. Or minutes. Or whatever interval you decided was the least-bad compromise between being current and not hammering your server into the ground.\nIt wastes resources. It\u0026rsquo;s always a little bit behind. It scales terribly. And you end up writing all this complex state management code just to track what you\u0026rsquo;ve already processed. It works, sure. But it feels wrong the whole time you\u0026rsquo;re building it.\nOption 2: Manual triggers. You write FileMaker scripts that use Insert from URL to ping external systems when something happens. This works better, actually. Until it doesn\u0026rsquo;t. Because now your FileMaker business logic is all tangled up with integration concerns. And if that external API is down when your script fires? Well, you better have written some really solid error handling. Which you probably didn\u0026rsquo;t, because you were trying to ship a feature, not build NASA-grade fault tolerance.\nBoth approaches share the same fundamental problem: FileMaker has been reactive, not proactive. It responds to queries. It doesn\u0026rsquo;t initiate conversations.\nWebhooks flip this entire model on its head.\nEvent-Driven FileMaker: Wait, This Actually Works Now? #With OData webhooks, FileMaker Server actively monitors your data and tells external systems the instant something relevant happens. No polling. No scripts with Insert from URL praying the network gods smile upon them.\nThis is event-driven architecture. The same pattern Stripe uses. And Shopify. And GitHub. And basically every modern SaaS platform you can name.\nBut here\u0026rsquo;s what makes FileMaker\u0026rsquo;s implementation actually good:\nIt\u0026rsquo;s standards-based. They built this on OData v4. Which means it speaks a language that thousands of platforms already understand. This isn\u0026rsquo;t some proprietary Claris thing that only works with Claris tools. It\u0026rsquo;s a widely adopted standard with real tooling and actual documentation that exists outside the Claris ecosystem.\nYou get granular control. You define exactly what triggers notifications using OData filter expressions. You specify which fields get included in the payload with the \u0026ldquo;select\u0026rdquo; parameter. You control where notifications go. This precision means you\u0026rsquo;re not just blasting entire records around your infrastructure every time someone breathes near a field. You\u0026rsquo;re surgical about it.\nWebhooks are first-class API resources. Create them. Retrieve them. List them. Delete them. Manually invoke them for testing. All through standard OData endpoints. Which means you can version-control these things, automate them, manage them programmatically. They\u0026rsquo;re not buried in some admin console checkbox—they\u0026rsquo;re infrastructure as code.\nTesting is built in. You can manually fire a webhook with specific record IDs. So you can test your integrations without modifying production data or sitting around waiting for real-world events to happen. As someone who\u0026rsquo;s spent too many hours waiting for the right conditions to test an integration, this is huge.\nThis isn\u0026rsquo;t some bolt-on feature they rushed out. It\u0026rsquo;s a thoughtfully designed integration framework that actually respects how we work in 2025.\nWhat This Does for FileMaker\u0026rsquo;s Reputation #Let me be blunt here. FileMaker has an image problem.\nWe know the platform is powerful. We know it\u0026rsquo;s productive. We\u0026rsquo;ve built incredible things with it. But out there in the wider tech world? People still think of it as a \u0026ldquo;legacy platform.\u0026rdquo; Or they dismiss it as something that can\u0026rsquo;t handle modern architectures.\nWebhooks change that story. Completely.\nSuddenly FileMaker does the same integration patterns as cutting-edge SaaS platforms. When some startup architect is designing their tech stack and wondering if FileMaker fits, webhooks eliminate a major objection. When an enterprise is evaluating whether their FileMaker solutions can coexist with microservices, the answer becomes an unqualified yes.\nBut here\u0026rsquo;s the really exciting part: this opens up the entire iPaaS ecosystem. Zapier, Make (used to be Integromat), n8n, Workato, all those integration platforms with thousands of pre-built connectors.\nA FileMaker solution with webhooks can now trigger a Zapier workflow that updates Salesforce, sends a Slack notification, creates a QuickBooks invoice, and logs everything to Datadog. Without writing a single line of custom integration code. You just configure it.\nThat\u0026rsquo;s a force multiplier.\nReal Use Cases: What Becomes Possible Now #Okay, enough abstract talk. Let me show you three scenarios that were either impossible or ridiculously painful before, and are now actually straightforward.\nReal-Time Financial Reconciliation #Picture a manufacturing company. They\u0026rsquo;re using FileMaker for production management—work orders, materials, labor tracking, the whole operation. But their accounting lives in QuickBooks Online, because of course it does.\nBefore webhooks, syncing these systems meant either scheduled batch jobs (with all the delays that entails) or building custom middleware that someone has to maintain forever.\nNow? The moment a production order status changes to \u0026ldquo;Completed\u0026rdquo; in FileMaker, a webhook fires. It contains the order details, materials used, labor hours, client info. That hits a lightweight serverless function—could be AWS Lambda, could be Cloudflare Workers, doesn\u0026rsquo;t matter—that calculates the final cost, hits the QuickBooks API to create an invoice, then calls back to FileMaker\u0026rsquo;s Script API to mark the order as \u0026ldquo;Invoiced\u0026rdquo; and store the QuickBooks invoice ID.\nThe whole thing happens in seconds. Not minutes. Not \u0026ldquo;overnight batch.\u0026rdquo; Seconds.\nYour financial records stay reconciled in real-time. Discrepancies get caught immediately, not during month-end closing when you\u0026rsquo;re already stressed. Faster cash flow. Less accounting overhead. No more reconciliation errors from batch sync timing issues.\nIt just works.\nSupply Chain Event Streams #Here\u0026rsquo;s a logistics company managing their fleet, shipments, warehouse operations—all in FileMaker. Their customers want real-time visibility into shipment status. Their warehouse systems need to coordinate receiving. Their financial systems need to recognize revenue on delivery confirmation.\nThey set up webhooks on the Shipments table with filters for status changes. Now they\u0026rsquo;ve got an event stream architecture that looks a lot like what Amazon or FedEx runs internally. Except it\u0026rsquo;s built on FileMaker.\nShipment goes \u0026ldquo;Out for Delivery\u0026rdquo;? Webhook fires. That event fans out to multiple subscribers: customer portal shows live tracking, customer\u0026rsquo;s system gets an API callback with the delivery window, the internal routing system recalculates the remaining deliveries for optimization.\nStatus changes to \u0026ldquo;Delivered\u0026rdquo;? Another cascade. Delivery confirmation email with photo and signature. Customer\u0026rsquo;s accounts payable system gets notified. FileMaker Script creates the invoice and calculates driver performance metrics. Event gets logged to the data warehouse for BI.\nAnd here\u0026rsquo;s where it gets really good: exception handling. They\u0026rsquo;ve got a webhook with a filter—DeliveryStatus eq \u0026lsquo;Exception\u0026rsquo;. The instant something goes wrong, the operations team gets alerted via PagerDuty, a high-priority ticket gets created in Zendesk, and the customer gets proactive communication about what\u0026rsquo;s being done to fix it.\nAll automatic.\nThis transforms FileMaker from \u0026ldquo;the database\u0026rdquo; into an event source driving a sophisticated distributed system. That\u0026rsquo;s not something you could say about FileMaker a year ago.\nCompliance and Anomaly Detection in Pharma #Pharmaceutical company. Sample management and clinical trial coordination in FileMaker. Heavily regulated environment—every data change needs to be audited, anomalies need to be detected in real-time.\nThey set up webhooks monitoring their SampleInventory and TrialData tables. Schema change notifications are enabled. Now every record change triggers a webhook that sends complete before/after field values to an append-only log—AWS S3 with cryptographic signatures. That\u0026rsquo;s your tamper-proof audit trail right there. FDA 21 CFR Part 11 compliant.\nBut it gets better. Those webhook payloads flow into a machine learning pipeline. Could be AWS Lambda calling SageMaker. Could be Azure Functions. Doesn\u0026rsquo;t matter. Point is, it\u0026rsquo;s watching for anomalies in real-time.\nUnusual access patterns. Changes happening during non-business hours. Rapid successive modifications that might indicate data manipulation. Schema changes that could affect data integrity. The ML catches these patterns and immediately creates incident tickets, notifies the QA team with full context, triggers FileMaker Script callbacks to flag affected records for review, and generates preliminary incident reports.\nAnd because they enabled notifySchemaChanges, any modification to table structure or field definitions triggers instant alerts. So nobody accidentally changes something that could invalidate months of clinical data.\nA year ago, getting this level of audit capability meant buying expensive third-party add-ons or commissioning custom plugin development. Now? Standard cloud services and a few hundred lines of serverless code.\nDifferent ballgame entirely.\nThe Ripple Effects Nobody\u0026rsquo;s Talking About Yet #The direct technical capabilities are obvious. But there are second-order effects that are going to be just as important.\nDeveloper skills are going to level up. FileMaker developers now have actual reasons to learn event-driven architecture, serverless computing, modern API patterns. That makes us more valuable. It broadens what we can build. And honestly, it\u0026rsquo;s more interesting work.\nThe partner ecosystem is about to expand. Third-party vendors will build webhook-based integration frameworks. Pre-built connectors. Specialized services. That ecosystem growth benefits all of us through shared knowledge and reusable components. We won\u0026rsquo;t all be reinventing the same wheels.\nWe\u0026rsquo;re going to develop patterns. The FileMaker community is going to figure out best practices for webhook design. How to structure payloads. When to use filters versus script-side logic. Patterns for error handling and retry logic. Security approaches. These patterns will become part of our collective knowledge, the same way we\u0026rsquo;ve developed patterns for everything else in FileMaker over the years.\nPlatform credibility just went up. When FileMaker comes up in technical discussions about platform choices, webhooks give us a real argument. \u0026ldquo;Does it support webhooks?\u0026rdquo; is a standard question in due diligence now. FileMaker can answer yes without asterisks or qualifications.\nThat matters more than you might think.\nWhat\u0026rsquo;s Next for This Feature #Look, webhook support is probably just the beginning. FileMaker\u0026rsquo;s clearly committed to evolving toward modern integration patterns.\nWe might see webhook response handling for synchronous request/response patterns. Event sourcing capabilities. GraphQL subscriptions. Maybe a webhook marketplace where developers share pre-configured integrations. Native serverless platform integration that makes deploying webhook receivers as easy as writing a FileMaker script.\nThe foundation\u0026rsquo;s in place now. Where it goes from here depends partly on what we build with it.\nThe Bottom Line #Adding OData webhooks to FileMaker Server isn\u0026rsquo;t just a feature update. It\u0026rsquo;s a statement about where the platform is going and what it means to build on FileMaker in 2025 and beyond.\nIf you\u0026rsquo;ve chosen FileMaker because it lets you ship solutions fast, webhooks eliminate a major compromise you\u0026rsquo;ve been making. You don\u0026rsquo;t have to sacrifice modern integration patterns to get rapid development anymore. You can have both.\nIf your business has invested in FileMaker solutions, webhooks give you a path into digital transformation initiatives without ripping out and replacing systems that work. Your FileMaker solutions can integrate seamlessly with best-of-breed tools across your organization.\nAnd for the platform itself, webhooks represent a commitment to evolution. To meeting developers where modern architecture is going, not where it used to be.\nThe question for FileMaker developers isn\u0026rsquo;t \u0026ldquo;Can FileMaker integrate with modern systems?\u0026rdquo; anymore.\nIt\u0026rsquo;s \u0026ldquo;What are you going to build now that it can?\u0026rdquo;\nBecause honestly? The possibilities are kind of spectacular.\nFurther Reading:\nClaris FileMaker OData API Guide: https://help.claris.com/en/odata-guide/ OData v4 Specification: https://www.odata.org/ Event-Driven Architecture Patterns: Martin Fowler\u0026rsquo;s Enterprise Integration Patterns ","date":null,"permalink":"https://ntwk.es/es/posts/post_013/","section":"Artículos del Blog Tecnológico","summary":"How OData Webhooks transform FileMaker from database platform to event-driven integration hub, enabling real-time integrations that were previously impossible or painful to implement.","title":"FileMaker Server Webhooks: The Integration Revolution That Changes Everything"},{"content":"","date":null,"permalink":"https://ntwk.es/es/categories/integration/","section":"Categories","summary":"","title":"Integration"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/integration/","section":"Tags","summary":"","title":"Integration"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/odata/","section":"Tags","summary":"","title":"OData"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/webhooks/","section":"Tags","summary":"","title":"Webhooks"},{"content":"Módulo Sistema de Formularios # Una solución FileMaker completa, lista para desplegar, para crear y gestionar formularios web dinámicos ilimitados.\nCaracterísticas Incluidas # Formularios ilimitados y campos ilimitados por formulario Soporte completo de tipos de campo: Texto, Área de Texto, Grupo de Casillas, Botones de Radio, Desplegable, Selector de Fecha/Hora, Carga de Archivo, etc. Opciones avanzadas de campo: flag requerido, placeholder, opciones multi-valor (separadas por pipe), reglas de validación Sistema de suscripción de usuarios con enlaces seguros únicos y protección opcional por contraseña Almacenamiento de envíos con pre-relleno opcional de datos anteriores (perfecto para validación, confirmación o formularios multi-paso) Bloqueo opcional de envío único tras envío final Marca corporativa completa: carga de logo (via cargador integrado basado en contenedores), nombre de empresa, sitio web, datos de contacto, pie legal Vista previa de formulario integrada directamente en FileMaker Registro completo de actividad Frontend web y formularios multilingües (crear un formulario por idioma; backend disponible en Catalán, Español, Inglés – idiomas ilimitados posibles) Gestión de archivos adjuntos con tamaño máximo configurable y tipos permitidos Soporte de tema Oscuro / Claro en el frontend web Estructura lista para integración (base de datos/tabla objetivo, contenedores de adjuntos, hooks de API personalizados) Requisitos Técnicos # FileMaker Pro 19+ o FileMaker Go (cliente) FileMaker Server 19+ con Data API habilitado Plugin BaseElements v4.2 o superior Servidor web públicamente accesible con PHP 8.0+ (Apache o Nginx) Certificado SSL válido (Let\u0026rsquo;s Encrypt disponible para versiones FileMaker Server \u0026gt; 21) No hay tienda online. Este sitio no vende módulos directamente. Para compras, presupuestos personalizados, configuraciones agrupadas o solicitudes especiales, por favor contáctenos para que podamos discutir términos, licenciamiento y opciones de implementación. Versión Básica #245 € (licencia única)\nQué NO está Incluido en la Versión Básica # Diseño personalizado UI/UX o estilos CSS de los formularios web Manuales detallados de usuario o administrador Formación de usuarios finales Compra/instalación de certificado SSL Servicios Opcionales # Servicio Precio Notas Implementación y despliegue completo (FileMaker Server + servidor web PHP + configuración SSL) 350 € Única vez, remoto o in situ Estilos personalizados / modificaciones UI Presupuesto separado Por proyecto Sesiones de formación (admin y usuarios) 80 €/hora Remoto Mantenimiento y soporte – remoto 80 €/hora o 60 €/hora (pack 5h) Facturación en incrementos de 60 min Visita in situ (área metropolitana Barcelona) 120 € + tarifas regulares de Mantenimiento y soporte Licenciamiento por Volumen para Desarrolladores y Proveedores de Soluciones #Planes de desarrollador disponibles, por favor contacte para condiciones y políticas de licenciamiento.\nActualizaciones y Actualizaciones # Actualizaciones de versión principal (nuevas características, cambios arquitectónicos): 50% del precio de lista actual Actualizaciones de mantenimiento y corrección de errores: Siempre gratuitas Garantía #Garantía de por vida contra defectos en el módulo entregado, siempre que no se hayan realizado modificaciones no autorizadas y la solución se ejecute en versiones de FileMaker soportadas en uso en el momento de la entrega.\nTérminos de Licencia (Cliente Final) #Licencia no exclusiva, no transferible y perpetua para uso interno únicamente. La ingeniería inversa, redistribución o modificación del código fuente está estrictamente prohibida.\nTérminos de Licencia (Desarrolladores) #Autorizado para integrar el módulo en soluciones de clientes bajo el programa de descuento por volumen anterior. No se otorgan derechos de redistribución más allá de las implementaciones específicas cubiertas por licencias compradas.\nEstaremos encantados de proporcionar una demostración o instalación piloto completamente funcional para que pueda probar el módulo en su entorno antes de la compra.\nPara preguntas o presupuestos personalizados, contáctenos en: tecnic@ntwk.es | +34 669 85 58 72\nVálido hasta el 31 de Diciembre de 2026\nCapturas de Pantalla # Sección de capturas de pantalla: Las capturas de pantalla detalladas de la interfaz FileMaker, configuración del backend y vistas del frontend web están disponibles en la versión en inglés. Toda la funcionalidad mostrada está completamente disponible en esta versión del módulo. ","date":null,"permalink":"https://ntwk.es/es/modules/forms_system_module/","section":"Módulos","summary":"","title":"Módulo Sistema de Formularios"},{"content":"Vibe Code Your FileMaker Apps #Democratizing FileMaker Development—Build Sophisticated Interfaces with Just a Description #Powered by FileMaker MCP Server + OData # Building on the Foundation #In my last article, I introduced the FileMaker OData MCP Server—a game-changing bridge between Claris FileMaker and AI assistants. Today, I want to show you what becomes possible when you actually use it.\nThis article demonstrates real, practical vibe coding: how you move from describing an idea to deploying a working application, all without touching a line of code.\nWhat This Changes #The FileMaker MCP Server exposes a full OData v4 endpoint, enabling AI assistants to discover your Claris FileMaker database schema and access live data using only natural language. No complex API knowledge required. No custom development. Just describe what you want to build, and the AI handles the rest.\nStep 1 – Switch to Production Database #The journey starts simple. Set up as many database connections as you need—production, staging, development, client databases—then just ask the AI to switch to whichever one you want to work with. No credentials to manage in the conversation. Just point and go.\n*Click image to zoom/enlarge*\nResult: Production connection confirmed — real data is now accessible. Your assistant now has live, direct access to your actual business data. Step 2 – Retrieve Live Contact Records #Ask for what you need in plain English: \u0026ldquo;Show me the first five contacts\u0026rdquo; or \u0026ldquo;Get me all recent leads.\u0026rdquo; The assistant queries your live Claris FileMaker database and returns real records instantly.\n*Click image to zoom/enlarge*\nResult: Live data retrieved directly from the FileMaker server. In this example, we get our first five real contacts, including Elizabeth Thompson (ID 1002), pulled directly from production. Step 3 – Full Schema Introspection Without Documentation #This is where the magic happens. The assistant automatically discovers your entire database structure—every table, every field, every relationship—by reading the OData metadata. Zero documentation needed. Zero guesswork.\nThe AI understands how your contacts relate to opportunities, invoices to line items, orders to shipments. It sees the relationships you defined in FileMaker and immediately grasps how your data is connected.\n*Click image to zoom/enlarge*\nResult: Complete reverse-engineering of your database structure using only standard OData metadata. The assistant now knows your data model as well as you do—without you having to explain a thing. This is pure schema discovery at work. Real-World Use Case: Vibe Code Your First Utility #Now that the assistant understands your database, you can describe what you want to build—naturally, without technical jargon.\n\u0026ldquo;Draft a professional meeting request email to the contact I just looked up.\u0026rdquo;\nThe assistant uses the live contact data (Elizabeth Thompson) and creates a ready-to-use email. No context switching. No manual lookups. Real data, instantly at your fingertips.\nThis demonstrates the power of \u0026ldquo;vibe coding\u0026rdquo;—describing your intent in natural language, and having a working solution appear.\n*Click image to zoom/enlarge*\nResult: A professional, personalized email drafted using real data from your database. This is how you collaborate with AI: you describe the outcome, it handles the technical details. Build Your First Web Interface #Want a customer dashboard? A lead pipeline tracker? An invoice approval UI? Just describe it.\n\u0026ldquo;Build me a simple dashboard showing my top contacts and their recent orders.\u0026rdquo;\nThe assistant instantly generates a complete, interactive web application—HTML, CSS, JavaScript—all working with your live FileMaker data. No coding knowledge required. No framework setup. No build tools.\n*Click image to zoom/enlarge*\nResult: A fully functional web interface, ready to use. You can paste it into a FileMaker Web Viewer, share it as a standalone URL, or embed it anywhere. It connects directly to your FileMaker data through the OData endpoint. Scale to Complex, Multi-Table UIs #As you get comfortable, you can ask for increasingly sophisticated interfaces. Want a contact management system with related opportunities, activities, and notes all displayed together? Just ask.\n\u0026ldquo;Build a contact detail view that shows all their opportunities on one side, recent activities in the middle, and communication history on the right. Make it look professional.\u0026rdquo;\nThe assistant leverages its complete understanding of your database structure and creates rich, multi-table interfaces that would normally require days of development work. Filtering, sorting, related data lookups—all handled seamlessly.\n*Click image to zoom/enlarge*\nResult: A sophisticated, multi-table user interface built entirely through natural language requests. No HTML. No JavaScript. No API coding. You described what you wanted; the AI built it. How \u0026ldquo;Vibe Coding\u0026rdquo; Differs from Traditional Development #Traditional approach: Write a requirements document → brief a developer → wait for mockups → iterate through revisions → deploy → maintain the code.\nVibe coding approach: Describe what you want → get a working interface instantly → tweak it with feedback → deploy → iterate in seconds.\nThere\u0026rsquo;s no gap between your idea and a working prototype. You\u0026rsquo;re not managing developers or learning code syntax. You\u0026rsquo;re having a conversation with an AI that understands your database and builds what you describe.\nReal Deployment Options #Your newly built interfaces aren\u0026rsquo;t locked into Claude or any temporary workspace. You have immediate options:\nFileMaker Web Viewer: Copy the generated HTML/CSS/JavaScript directly into a Web Viewer. Your interface appears inside your FileMaker solution, connected to live data.\nStandalone Web Client: Share the interface as a public or private URL. Users access it from any browser—no FileMaker client needed. Perfect for customer portals, partner dashboards, or internal tools.\nEmbed Anywhere: The AI generates standard web code that works anywhere—your website, an intranet, a mobile app webview, or an internal portal.\nWhy This Matters for FileMaker Users #Speed: What would take days of development now takes minutes.\nNo Code Barrier: You don\u0026rsquo;t need to learn JavaScript, React, or any framework. You describe; the AI builds.\nLive Data, Instantly: Your interfaces connect directly to your FileMaker database. No manual syncing. No data exports. Always current.\nFlexibility: Tired of your dashboard? Describe a different one. Want to A/B test two designs? Generate both in seconds.\nRapid Iteration: Get feedback from users and incorporate changes immediately, in real time, without a development cycle.\nFrom Idea to Production #The entire workflow is streamlined:\nDescribe what you want to build in plain English Generate a fully functional web interface in seconds Customize it with feedback through natural conversation Deploy directly into a Web Viewer or as a standalone app Iterate and improve without waiting for developers All while your interface works with real, live data from your FileMaker database.\nConclusion: Democratizing FileMaker Development #The FileMaker MCP Server transforms any solution into a fully discoverable, queryable API. Combined with AI-powered vibe coding, it democratizes FileMaker development. You no longer need specialized knowledge to build sophisticated interfaces. You don\u0026rsquo;t need to hire developers for every new dashboard or utility. You don\u0026rsquo;t need to maintain complex code.\nInstead, you describe what you need, and it exists. Your data is live. Your interfaces are functional. Your business moves faster.\nThis is the future of low-code development: not \u0026ldquo;less code,\u0026rdquo; but no code—just conversation, and immediately useful tools.\nReady to build? Describe what your users need, and let AI handle the rest.\n","date":null,"permalink":"https://ntwk.es/es/posts/post_012/","section":"Artículos del Blog Tecnológico","summary":"","title":"Vibe Code Your FileMaker Apps"},{"content":"In my previous post, I introduced the FileMaker Data API MCP Server—a bridge that gave AI agents deep introspection into your FileMaker schema, logic, and workflows.\nThat was about intelligence: letting AI see how your system thinks.\nThis next step is about interoperability—letting it talk to the world.\nIntroducing: FileMaker OData MCP Server # Now live → filemaker-odata-mcp\nWhy OData Changes Everything #FileMaker\u0026rsquo;s native OData support is powerful—but underused.\nThis MCP server turns it into a universal data passport.\nAny OData-compliant client—AI agent, Power BI, web app, or integration—can now query, filter, join, and explore your FileMaker data using standard REST syntax.\nNo custom APIs. No middleware. Just clean, discoverable data.\nAI Agents That Speak OData (and FileMaker) #With FileMaker OData MCP, any Model Context Protocol (MCP)–compatible agent can:\nRun live OData queries with $filter, $select, $expand, and pagination Merge FileMaker data with SAP, Dynamics, Salesforce, or custom APIs Map semantics across systems for cross-domain reasoning Generate real-time insights across your entire data universe FileMaker is no longer an island—it\u0026rsquo;s a node in the global data fabric.\nReal-World Impact #Picture this:\nAn AI agent syncing FileMaker orders with ERP in real time A CFO pulling live FileMaker KPIs into Excel or Power BI via OData A developer feeding FileMaker records into a generative AI workflow—no ETL required FileMaker becomes part of the conversation, not behind it.\nBuilt for Developers, Secured for Enterprises # Node.js + NPM — npm install filemaker-odata-mcp Maps directly to FileMaker Server\u0026rsquo;s OData endpoints Full auth \u0026amp; access control (Basic, OAuth, FM tokens) Dynamic schema exposure for AI discovery Runs standalone or alongside Data API MCP for dual introspection + connectivity Quick note on the roadmap: To ensure broad compatibility with older FileMaker Server versions, we\u0026rsquo;ve intentionally omitted some exciting new OData features introduced in FileMaker v22 (like enhanced metadata querying and advanced relational expansions). These are high on our TODO list for future releases—check out the detailed roadmap for what\u0026rsquo;s coming next. Your feedback here could shape it!\nThe Vision: AI That Understands and Connects # MCP Server Superpower Data API MCP AI understands your FileMaker logic OData MCP AI connects it to the world Together, they enable AI-native FileMaker ecosystems—open, intelligent, and interoperable by design.\nGet Started Today #👉 NPM: npm install filemaker-odata-mcp 👉 GitHub: FMS-ODATA-MCP 👉 Docs in repo — 5-minute setup guide included\nWhat happens when your FileMaker data speaks the same language as AI, BI, and the cloud?\nWhat new workflows will emerge when your system isn\u0026rsquo;t just smart—but connected?\nLet me know in the comments—I\u0026rsquo;d love to hear your ideas.\nBig thanks to the incredible @Claris International team for building such a flexible platform, and shoutout to @FileMaker devs worldwide pushing the limits of low-code + AI.\nLet\u0026rsquo;s keep building the future of connected intelligence together!\n#FileMaker #OData #AI #MCP #LowCode #DataIntegration #OpenSource\n","date":null,"permalink":"https://ntwk.es/es/posts/post_011/","section":"Artículos del Blog Tecnológico","summary":"","title":"The Next Leap: Open Data Connectivity for AI-Powered FileMaker Solutions"},{"content":"AI Agents That Understand Your Entire FileMaker Solution #For decades, we\u0026rsquo;ve built complex FileMaker applications through expertise and countless iterations. Expert developers spend years mastering the nuances—table relationships, orchestrating scripts, business logic embedded throughout.\nWhat if you could hand that entire knowledge base to an AI agent?\nIntroducing the FileMaker Data API MCP Server—giving AI agents the ability to completely introspect your FileMaker solution and become an architect-level coder capable of building complex applications from simple human requests.\nThe Breakthrough #Imagine: \u0026ldquo;Build me a project management system that tracks tasks across teams, with automatic escalation when deadlines are missed and a dashboard showing capacity by department.\u0026rdquo;\nAn AI agent with full visibility into your FileMaker solution can:\nUnderstand your entire data architecture — tables, fields, relationships, constraints Learn your design patterns — existing scripts, layouts, workflows Comprehend your business logic — how your organization solves problems Generate production-ready code — that fits your ecosystem This is an AI architect that studied your codebase and can design applications native to your infrastructure.\nHow It Changes Development #Scalable Innovation — Stop waiting for senior developers. Get sophisticated applications architected instantly.\nPreserve Knowledge — Your FileMaker solutions contain years of wisdom. An AI agent becomes a knowledge multiplier.\nConcept to Code in Minutes — Move from conversation to working applications faster than ever.\nMaintain Consistency — Generated code follows your standards and patterns.\nPowered by Complete Introspection # Full database introspection — layouts, scripts, tables, relationships Script analysis and logic understanding Live execution capability — to test generated code Multi-database awareness Complete context — portals, global fields, containers All secure. No exposed credentials.\nThe Vision #We\u0026rsquo;re at an inflection point. AI isn\u0026rsquo;t automating routine tasks—it\u0026rsquo;s becoming a partner in creative, architectural work. For FileMaker developers, this means unlocking the next level: describing complex requirements in natural language and getting back production-grade, architecturally-sound applications.\nThis only works when AI has complete visibility into your solution. When it understands your data schema and your design philosophy. When it sees patterns and extends them intelligently.\nThat\u0026rsquo;s the real superpower.\nReady to Start? #The FileMaker MCP Server is open-source and ready.\n🔗 GitHub Repository\nWhat would you build if you had an AI architect with complete understanding of your FileMaker systems?\n#FileMaker #AI #Automation #SoftwareDevelopment #AIAgents #LowCode\n","date":null,"permalink":"https://ntwk.es/es/posts/post_002/","section":"Artículos del Blog Tecnológico","summary":"","title":"The Real Superpower of AI"},{"content":"Building a Logstash/Elasticsearch/Kibana Dashboard #Transform your FileMaker data into actionable intelligence with real-time monitoring and visualization. Learn how to automatically feed FileMaker data into the Logstash/Elasticsearch/Kibana (ELK) stack using FileMaker\u0026rsquo;s JDBC interface. This comprehensive guide walks you through setting up seamless data ingestion, creating powerful dashboards, and gaining instant visibility into your critical business metrics—all without custom development complexity.\nThe Challenge: FileMaker Data Visibility #FileMaker has long been a reliable workhorse for organizations managing critical business data. Yet many teams face a common frustration: getting real-time visibility into that data across their organization. Traditional FileMaker reporting is powerful but static, often requiring manual exports, scheduled scripts, or complex web publishing solutions to share insights beyond the immediate user base.\nWhen you need to monitor performance metrics, track system health, meter usage patterns, and log activities in near real-time, FileMaker alone isn\u0026rsquo;t designed for this level of operational intelligence. That\u0026rsquo;s where the ELK stack comes in.\nWhy ELK? The Power of Elasticsearch, Logstash, and Kibana #The Elasticsearch-Logstash-Kibana (ELK) stack has become the industry standard for real-time data analytics and monitoring. Here\u0026rsquo;s why it\u0026rsquo;s the perfect complement to FileMaker:\nElasticsearch provides lightning-fast full-text search and analytics capabilities, handling millions of records with sub-second query response times. Logstash acts as your data processing pipeline, transforming and enriching raw data before it enters Elasticsearch. Kibana delivers intuitive, interactive dashboards that bring your data to life with visualizations, alerts, and deep-dive analytics.\nTogether, they create a scalable, open-source platform designed for real-time insights—something FileMaker wasn\u0026rsquo;t architected to do at scale.\nConnecting FileMaker to the ELK Stack via JDBC #FileMaker\u0026rsquo;s JDBC interface is the bridge between your FileMaker database and the broader data ecosystem. JDBC (Java Database Connectivity) allows external applications to query FileMaker as if it were a standard SQL database, making it possible to treat FileMaker as a data source for pipeline tools like Logstash.\nWhat You\u0026rsquo;ll Need #Before diving into setup, ensure you have:\nFileMaker Server 17 or later (with JDBC driver enabled) FileMaker JDBC driver installed and configured Logstash 7.x or later Elasticsearch 7.x or later Kibana 7.x or later A working understanding of basic database concepts and JSON Step 1: Enable FileMaker\u0026rsquo;s JDBC Interface #First, you\u0026rsquo;ll need to enable JDBC on your FileMaker Server. Navigate to your FileMaker Admin Console and verify that JDBC is enabled in the database server settings. The JDBC driver typically listens on port 5432 (or a custom port you configure).\nTest your JDBC connection using a simple tool or query to ensure FileMaker is accessible from your Logstash instance:\njdbc:filemaker://[filemaker-server]:5432/[database-name] Step 2: Configure Logstash for FileMaker Data Ingestion #Logstash uses a pipeline configuration to ingest, process, and output data. Create a new configuration file for your FileMaker-to-Elasticsearch pipeline:\ninput { jdbc { jdbc_driver_library =\u0026gt; \u0026#34;/path/to/filemaker-jdbc.jar\u0026#34; jdbc_driver_class =\u0026gt; \u0026#34;com.filemaker.jdbc.Driver\u0026#34; jdbc_connection_string =\u0026gt; \u0026#34;jdbc:filemaker://[your-filemaker-server]:5432/[database]\u0026#34; jdbc_user =\u0026gt; \u0026#34;[filemaker-username]\u0026#34; jdbc_password =\u0026gt; \u0026#34;[filemaker-password]\u0026#34; schedule =\u0026gt; \u0026#34;*/5 * * * *\u0026#34; statement =\u0026gt; \u0026#34;SELECT * FROM [your-table] WHERE modification_timestamp \u0026gt; :sql_last_value\u0026#34; use_column_value =\u0026gt; true tracking_column =\u0026gt; \u0026#34;modification_timestamp\u0026#34; tracking_column_type =\u0026gt; \u0026#34;timestamp\u0026#34; } } filter { mutate { convert =\u0026gt; { \u0026#34;numeric_field\u0026#34; =\u0026gt; \u0026#34;integer\u0026#34; } convert =\u0026gt; { \u0026#34;currency_field\u0026#34; =\u0026gt; \u0026#34;float\u0026#34; } } date { match =\u0026gt; [ \u0026#34;timestamp_field\u0026#34;, \u0026#34;yyyy-MM-dd HH:mm:ss\u0026#34; ] target =\u0026gt; \u0026#34;@timestamp\u0026#34; } } output { elasticsearch { hosts =\u0026gt; [\u0026#34;localhost:9200\u0026#34;] index =\u0026gt; \u0026#34;filemaker-%{+YYYY.MM.dd}\u0026#34; } } Key Configuration Points:\nschedule: Controls how often Logstash queries FileMaker (every 5 minutes in this example) statement: Uses incremental loading via sql_last_value to only fetch changed records tracking_column: Identifies the timestamp field to detect new/modified data filter: Converts data types and normalizes timestamps for Elasticsearch This approach ensures you\u0026rsquo;re only pulling changed data, minimizing load on FileMaker and keeping your ELK stack in near real-time sync.\nStep 3: Data Transformation and Enrichment #As data flows through Logstash, you can enrich it with additional context. For example:\nfilter { mutate { add_field =\u0026gt; { \u0026#34;data_source\u0026#34; =\u0026gt; \u0026#34;FileMaker\u0026#34; } add_field =\u0026gt; { \u0026#34;environment\u0026#34; =\u0026gt; \u0026#34;production\u0026#34; } } if [status] == \u0026#34;error\u0026#34; { mutate { add_tag =\u0026gt; [ \u0026#34;alert\u0026#34; ] } } } This tagging strategy makes it easy to filter, search, and alert on critical events in Kibana.\nStep 4: Setting Up Elasticsearch Indices #Elasticsearch organizes data into indices. Create a dedicated index template for your FileMaker data to ensure consistent field mappings:\nPUT _index_template/filemaker-template { \u0026#34;index_patterns\u0026#34;: [\u0026#34;filemaker-*\u0026#34;], \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 1, \u0026#34;number_of_replicas\u0026#34;: 0, \u0026#34;index.refresh_interval\u0026#34;: \u0026#34;5s\u0026#34; }, \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;@timestamp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34; }, \u0026#34;record_id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34; }, \u0026#34;status\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34; }, \u0026#34;value\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;double\u0026#34; }, \u0026#34;data_source\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34; } } } } This template ensures new indices automatically follow your schema, maintaining consistency across time-series data.\nStep 5: Creating Real-Time Dashboards in Kibana #Once data flows into Elasticsearch, Kibana transforms it into visual intelligence. Here\u0026rsquo;s how to build your first dashboard:\nCreate a Saved Search: In Kibana, navigate to Discover and filter your FileMaker data. Save this as a baseline query.\nBuild Visualizations: Create various visualization types:\nLine Charts: Track metrics over time Bar Charts: Compare categorical data Heatmaps: Identify patterns and anomalies Metrics Cards: Display KPIs at a glance Tables: Deep-dive data exploration Combine into a Dashboard: Link multiple visualizations together to create a comprehensive operational view. For example:\nTop section: Key performance indicators (revenue, transaction count, errors) Middle section: Time-series trend charts Bottom section: Detailed data tables and drill-down views Add Interactivity: Use dashboard filters to allow users to segment by date range, status, department, or any FileMaker field.\nStep 6: Monitoring, Metering, and Logging Best Practices #As your ELK-FileMaker pipeline matures, implement these best practices:\nLogging: Ensure Logstash captures detailed logs about data ingestion. Monitor for failed queries, connection timeouts, or data transformation errors. Set up Logstash itself as a data source to track pipeline health.\nMetering: Track key metrics like records ingested per cycle, average query latency, and data pipeline lag. Create a meta-dashboard that monitors the health of your monitoring system.\nAlerting: Configure Kibana alerts to notify your team when thresholds are exceeded or anomalies detected:\n{ \u0026#34;name\u0026#34;: \u0026#34;High Error Rate Alert\u0026#34;, \u0026#34;condition\u0026#34;: { \u0026#34;query\u0026#34;: \u0026#34;status:error\u0026#34;, \u0026#34;threshold\u0026#34;: 100, \u0026#34;timeframe\u0026#34;: \u0026#34;5m\u0026#34; }, \u0026#34;actions\u0026#34;: [\u0026#34;email\u0026#34;, \u0026#34;slack\u0026#34;] } Data Retention: Define index lifecycle policies to archive or delete old data, managing storage costs and maintaining performance:\nPUT _ilm/policy/filemaker-policy { \u0026#34;policy\u0026#34;: \u0026#34;filemaker-policy\u0026#34;, \u0026#34;phases\u0026#34;: { \u0026#34;hot\u0026#34;: { \u0026#34;min_age\u0026#34;: \u0026#34;0d\u0026#34;, \u0026#34;actions\u0026#34;: { \u0026#34;rollover\u0026#34;: { \u0026#34;max_primary_store_size\u0026#34;: \u0026#34;50GB\u0026#34; } } }, \u0026#34;delete\u0026#34;: { \u0026#34;min_age\u0026#34;: \u0026#34;30d\u0026#34;, \u0026#34;actions\u0026#34;: { \u0026#34;delete\u0026#34;: {} } } } } Real-World Benefits #Once your FileMaker-to-ELK pipeline is operational, you\u0026rsquo;ll gain:\nInstant Visibility: Query millions of FileMaker records in milliseconds Proactive Monitoring: Set alerts on conditions before they become critical Historical Analysis: Understand trends and patterns over weeks, months, or years Cross-Organization Insights: Share dashboards across teams without FileMaker licensing Compliance and Auditing: Maintain comprehensive logs for regulatory requirements Performance Optimization: Identify bottlenecks and optimize FileMaker queries based on usage patterns Conclusion #By connecting FileMaker to the ELK stack via JDBC, you transform your database from a transactional workhorse into a real-time analytics engine. The combination of FileMaker\u0026rsquo;s data reliability and the ELK stack\u0026rsquo;s analytical power creates a platform that serves both operational needs and strategic insights.\nStart small—begin with a single table and a basic dashboard, then expand as you see value. Your team will quickly discover that real-time visibility into FileMaker data isn\u0026rsquo;t just a nice-to-have; it\u0026rsquo;s a game-changer for operational excellence, informed decision-making, and business agility.\nThe future of FileMaker isn\u0026rsquo;t isolated—it\u0026rsquo;s connected, intelligent, and real-time. Ready to get started?\n","date":null,"permalink":"https://ntwk.es/es/posts/post_006/","section":"Artículos del Blog Tecnológico","summary":"","title":"Real-Time FileMaker Data Monitoring"},{"content":"Both OpenWebUI and LM Studio are popular ways to run LLMs on your own machine, but they solve slightly different problems and have distinct strengths. Below is a side‑by‑side comparison to help you decide which one fits your workflow best.\n1. What They Are # Tool Primary Goal Typical Use‑Case OpenWebUI A lightweight, self‑hosted web UI for interacting with any locally‑run model (or remote API). Quick chat‑style UI, multi‑user access, easy sharing of prompts, and integration with existing inference back‑ends (e.g., Ollama, vLLM, Text Generation Inference). LM Studio An all‑in‑one desktop application that bundles model download, quantisation, inference engine, and a UI. One‑click setup for developers, researchers, or hobbyists who want to experiment with many models without fiddling with separate servers. 2. Architecture \u0026amp; Deployment # Feature OpenWebUI LM Studio Installation Docker (recommended) or manual Python install. Runs as a server you can expose on a LAN or the internet. Stand‑alone binary (Windows/macOS/Linux). Runs locally as a desktop app; no Docker needed. Backend Engine Does not ship its own inference engine – you point it at an existing server (Ollama, vLLM, Text Generation Inference, FastChat, etc.). Ships its own in‑process inference engine (based on llama.cpp for GGUF, ctransformers, or torch for full‑precision). Model Management You manage models separately (e.g., via Ollama, HuggingFace transformers, or a custom server). LM Studio can download, convert, quantise, and cache models automatically from Hugging Face. Multi‑User / Auth Built‑in user accounts, role‑based permissions, API keys, and optional OAuth. Good for small teams or public demos. Single‑user desktop app; no multi‑user auth (though you can expose its API locally if you want). API Exposure Provides a REST API (/v1/chat/completions compatible with OpenAI) that other tools can call. Also offers an OpenAI‑compatible API, but it’s meant for local scripts rather than external services. Resource Footprint Very small (just the UI + proxy). The heavy lifting is done by the inference server you already run. Slightly larger because it bundles the inference engine, but still modest (especially with GGUF quantisation). 3. Performance \u0026amp; Flexibility # Aspect OpenWebUI LM Studio Model Size Support Whatever your backend supports – from 7 B to 70 B+ (if you have the hardware). Supports up to ~70 B with llama.cpp GGUF quantisation; larger models need a GPU‑accelerated backend (e.g., torch/vLLM). Quantisation Handled by the backend (e.g., Ollama’s quantize command). LM Studio can auto‑quantise to q4_0, q5_0, q8_0, etc., directly from the UI. GPU vs CPU Depends on the backend you plug in. You can swap from CPU‑only to CUDA, ROCm, or even TPUs without touching OpenWebUI. LM Studio can run on CPU (via llama.cpp) or GPU (via torch/vLLM). Switching requires a restart with a different runtime option. Latency Typically lower if you pair with a high‑performance server (e.g., vLLM on a GPU). Good for modest hardware; GGUF on CPU can be surprisingly fast (30‑50 tok/s on a modern laptop). 4. Ease of Use # Factor OpenWebUI LM Studio Setup Time Docker compose + a running inference server → ~10 min if you already have Ollama/vLLM. Download binary → run → click “Add Model” → done (≈5 min). Learning Curve You need to understand how to run an inference server and expose it to the UI. Mostly point‑and‑click; the UI guides you through model download and quantisation. Documentation Good docs for Docker, API, and integration with many backends. Very beginner‑friendly docs, plus in‑app tooltips. Community \u0026amp; Plugins Growing ecosystem (plugins for RAG, PDF upload, code‑interpreter, etc.). Smaller plugin ecosystem; mainly focused on model management. 5. When to Choose OpenWebUI # You already have a model server (Ollama, vLLM, Text Generation Inference, etc.) and just need a nice UI / API layer. Multi‑user access is required – e.g., a small team, classroom, or public demo. You want full control over the inference stack (GPU drivers, quantisation method, custom kernels). You plan to expose the service over a network (LAN, VPN, or internet) and need authentication / rate‑limiting. You like the Docker‑first approach for reproducibility. Typical stack example\n# 1️⃣ Run Ollama (or vLLM) with your model docker run -d -p 11434:11434 ollama/ollama # 2️⃣ Run OpenWebUI docker run -d -p 3000:8080 \\ -e OLLAMA_BASE_URL=http://host.docker.internal:11434 \\ ghcr.io/open-webui/open-webui:latest Now you have a web UI at http://localhost:3000 and an OpenAI‑compatible endpoint at http://localhost:3000/v1.\n6. When to Choose LM Studio # You want a single‑click, all‑in‑one desktop experience without juggling containers. You are experimenting with many models and want the UI to handle downloads, conversions, and quantisation automatically. You have limited hardware (e.g., a laptop) and need the most efficient CPU‑only inference (gguf quantisation). You prefer a native GUI for prompt engineering, chat history, and quick testing. You don’t need multi‑user access or external API exposure (or you’re fine with the local API only). Typical workflow\nOpen LM Studio → “Add Model” → search Hugging Face → pick a model. Choose quantisation level (e.g., Q4_K_M). Click Download \u0026amp; Load → the model appears in the sidebar. Start chatting, export logs, or call the local API (http://127.0.0.1:1234/v1/chat/completions). 7. Quick Decision Matrix # Need Best Fit Already running a GPU‑accelerated inference server (Ollama, vLLM, etc.) OpenWebUI Want a web UI that can be accessed by multiple people OpenWebUI Need a simple, single‑machine desktop app with auto‑download \u0026amp; quantisation LM Studio Want to experiment with many models quickly on a CPU‑only laptop LM Studio Need fine‑grained control over backend (custom kernels, TPUs, custom Docker images) OpenWebUI Prefer not to touch Docker/CLI at all LM Studio 8. Other Alternatives Worth Mentioning # Tool Highlights Ollama Very easy to spin up models (ollama run mistral). Works great as the backend for OpenWebUI. vLLM High‑throughput GPU server; ideal for serving many concurrent requests. Text Generation Inference (TGI) Hugging Face’s production‑grade inference server; works with OpenWebUI. AutoGPT‑WebUI Similar to OpenWebUI but focused on AutoGPT‑style agents. ComfyUI‑LLM If you’re already using ComfyUI for diffusion, this adds LLM chat. FastChat Open‑source chat server + UI; more research‑oriented. ","date":null,"permalink":"https://ntwk.es/es/posts/post_001/","section":"Artículos del Blog Tecnológico","summary":"","title":"OpenWebUI vs LM Studio – Which Local LLM Frontend Is Right for You?"},{"content":"If you\u0026rsquo;ve ever felt trapped trying to connect FileMaker to Google APIs securely, you\u0026rsquo;re not alone. The world of OAuth 2.0, service accounts, and JWT tokens can feel like stepping into a cryptographic maze—but it doesn\u0026rsquo;t have to be.\nThe truth is, generating a valid JWT (JSON Web Token) from FileMaker is one of the most powerful yet underutilized skills in the FileMaker ecosystem. It\u0026rsquo;s the bridge between your FileMaker database and Google\u0026rsquo;s world-class services—from Cloud Storage to BigQuery, from Sheets to Drive—all while maintaining enterprise-grade security. And yet, most developers either avoid it entirely or cobble together solutions that feel fragile and incomplete.\nWhat if I told you that with just a few custom functions, you could generate production-ready JWT tokens directly from FileMaker? No external servers. No third-party middleware. Just your data, your rules, and bulletproof authentication. This guide walks you through the complete anatomy of a JWT, shows you exactly how to construct one in FileMaker, and gives you battle-tested custom functions you can use today—whether you\u0026rsquo;re building a data integration layer, automating backups to Google Cloud, or orchestrating complex multi-system workflows.\nJWT Anatomy #Using OAuth 2.0 for Server to Server Applications (Service Accounts)\nGeneral Flow # Creating the JWT token\u0026hellip;\nJWT Composition #A JWT is composed as follows:\n{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature} The base string for the signature is as follows:\n{Base64url encoded header}.{Base64url encoded claim set} JWT header #signing algorithm and the format of the assertion. In this case: RSA SHA-256 and JWT token format\n{\u0026#34;alg\u0026#34;:\u0026#34;RS256\u0026#34;,\u0026#34;typ\u0026#34;:\u0026#34;JWT\u0026#34;} JWT claim set #params are:\nName Description iss The email address of the service account scope A space-delimited list of the permissions that the application requests aud A descriptor of the intended target of the assertion. When making an access token request this value is always https://oauth2.googleapis.com/token exp The expiration time of the assertion, specified as seconds since 00:00:00 UTC iat The time the assertion was issued, specified as seconds since 00:00:00 UTC, January 1, 1970 { \u0026#34;iss\u0026#34;: \u0026#34;761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com\u0026#34;, \u0026#34;scope\u0026#34;: \u0026#34;https://www.googleapis.com/auth/devstorage.read_only\u0026#34;, \u0026#34;aud\u0026#34;: \u0026#34;https://oauth2.googleapis.com/token\u0026#34;, \u0026#34;exp\u0026#34;: 1328554385, \u0026#34;iat\u0026#34;: 1328550785 } additional claims #To obtain an access token that grants an application delegated access to a resource, include the email address of the user in the JWT claim set as the value of the sub field.\nName Description sub The email address of the user for which the application is requesting delegated access { \u0026#34;iss\u0026#34;: \u0026#34;761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com\u0026#34;, \u0026#34;sub\u0026#34;: \u0026#34;some.user@example.com\u0026#34;, \u0026#34;scope\u0026#34;: \u0026#34;https://www.googleapis.com/auth/prediction\u0026#34;, \u0026#34;aud\u0026#34;: \u0026#34;https://oauth2.googleapis.com/token\u0026#34;, \u0026#34;exp\u0026#34;: 1328554385, \u0026#34;iat\u0026#34;: 1328550785 } encoding claim set #The JWT claim set should be serialized to UTF-8 and Base64url-safe encoded\nThe input for the signature is the byte array of the following content:\n{Base64url encoded header}.{Base64url encoded claim set} The only signing algorithm supported by the Google OAuth 2.0 Authorization Server is RSA using SHA-256 hashing algorithm. This is expressed as RS256 in the alg field in the JWT header.\nSign the UTF-8 representation of the input using SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function) with the private key obtained from the Google API Console. The output will be a byte array.\nScript #Custom functions #GenerateJWT( ) #Usage #GenerateJWT( iss; scope; aud; pk )\nSample #GenerateJWT( \u0026quot;YOUR_SERVICE_ACCOUNT_EMAIL\u0026quot;; \u0026quot;https://www.googleapis.com/auth/devstorage.read_only\u0026quot;; \u0026quot;https://oauth2.googleapis.com/token\u0026quot;; \u0026quot;YOUR_PRIVATE_KEY\u0026quot; ) Dependendencies #(CF) UnixTime() (CF) Base64urlEncode(str) ClaimSet parameters # iss: The email address of the service account scope: A space-delimited list of the permissions that the application requests aud: A descriptor of the intended target of the assertion. When making an access token request this value is always https://oauth2.googleapis.com/token exp: The expiration time of the assertion, specified as seconds since 00:00:00 UTC iat: The time the assertion was issued, specified as seconds since 00:00:00 UTC, January 1, 1970 sub: The email address of the user for which the application is requesting delegated access (only used for delegated access) Let( [ _ISS = iss; _SCOPE = scope; _AUD = aud; _PRIVATE_KEY = pk; _TOKEN_TTL = 3600; _UTC_ZERO = UnixTime(); header = JSONSetElement ( \u0026#34;{}\u0026#34;; [\u0026#34;alg\u0026#34;; \u0026#34;RS256\u0026#34;; JSONString]; [\u0026#34;typ\u0026#34;; \u0026#34;JWT\u0026#34;; JSONString] ); claimSet = JSONSetElement ( \u0026#34;{}\u0026#34;; [\u0026#34;iss\u0026#34;; _ISS; JSONString]; [\u0026#34;scope\u0026#34;; _SCOPE; JSONString]; [\u0026#34;aud\u0026#34;; _AUD; JSONString]; [\u0026#34;iat\u0026#34;; _UTC_ZERO ; JSONNumber]; [\u0026#34;exp\u0026#34;; _UTC_ZERO + _TOKEN_TTL; JSONNumber] ); signatureData = \u0026#34;\u0026#34; \u0026amp; Base64urlEncode ( header ) \u0026amp; \u0026#34;.\u0026#34; \u0026amp; Base64urlEncode ( claimSet ) \u0026amp; \u0026#34;\u0026#34;; signature = CryptGenerateSignature ( signatureData ; \u0026#34;SHA256\u0026#34; ; _PRIVATE_KEY ; \u0026#34;\u0026#34; ); signedJWTData = signatureData \u0026amp; \u0026#34;.\u0026#34; \u0026amp; Base64urlEncode (signature ) ]; signedJWTData ) UnixTime( ) #Just returns the seconds since 00:00:00 UTC\nFloor( GetAsNumber ( Get ( CurrentTimeUTCMilliseconds ) ) / 1000 ) - GetAsNumber ( Timestamp ( \u0026#34;01/01/1970\u0026#34; ; \u0026#34;00:00:00\u0026#34; ) ) Base64urlEncode( ) #Does a \u0026ldquo;url safe\u0026rdquo; Base64 Encoding, accordingly to RFC4648 https://tools.ietf.org/html/rfc4648 Do not use simple Base64 native encodings from FileMaker.\nLet ( _e=Base64EncodeRFC(4648 ;data ); Substitute( _e;[\u0026#34;+\u0026#34;;\u0026#34;-\u0026#34;];[\u0026#34;/\u0026#34;;\u0026#34;_\u0026#34;];[\u0026#34;\\r\u0026#34;;\u0026#34;\u0026#34;];[\u0026#34;\\n\u0026#34;;\u0026#34;\u0026#34;];[\u0026#34;=\u0026#34;;\u0026#34;\u0026#34;] ) ) Get the Token #Basicaly pass the JWT body to the authentication server as:\n$ASSERTION = GenerateJWT( iss; scope; aud; pk ) $GRANT_TYPE = \u0026#34;urn:ietf:params:oauth:grant-type:jwt-bearer\u0026#34; Post a CURL to the token_uri: https://oauth2.googleapis.com/token with the cURL options:\nCURL -X POST -d \u0026#34;grant_type=$GRANT_TYPE\u0026amp;assertion=$ASSERTION\u0026#34; The result contains your authorization token, expiration date time or error messages if request fails.\n","date":null,"permalink":"https://ntwk.es/es/posts/post_010/","section":"Artículos del Blog Tecnológico","summary":"","title":"Unlocking Server-to-Server Access: How to Generate JWT Tokens in FileMaker for Google OAuth 2.0"},{"content":"Fixing Hibernate 6 + FileMaker: The JDBC Dialect We Needed #Scale unlimited pooled connections, container fields, and build high-concurrency Java apps #You know that feeling when Hibernate 6 hit and suddenly your beautifully crafted FileMaker JDBC integration stopped working?\nYeah. That.\nFor years, Java developers integrating with Claris FileMaker had a painful choice: stick with Hibernate 5 and miss out on years of modern improvements, or upgrade to Hibernate 6+ and watch your build fail in ways that made you question every life decision that led to that moment.\nThe Root of the Problem #The root of the problem wasn\u0026rsquo;t mystical. It was architectural.\nThe FileMaker JDBC driver isn\u0026rsquo;t a true Class 4 driver. It comes with known limitations—no getGeneratedKeys() support, no connection validation via SELECT 1, no DDL generation. These constraints don\u0026rsquo;t break basic SQL, but they absolutely break the assumptions that Hibernate 6+ makes about how JDBC drivers behave.\nUntil now.\nIntroducing the FileMaker Hibernate 6.5+ Dialect (Open Source) #After wrestling with the known incompatibilities between Hibernate\u0026rsquo;s post-v5 architecture and FileMaker\u0026rsquo;s JDBC quirks, we\u0026rsquo;ve finally cracked it.\nThis is a fully-tested dialect that:\nHandles ANSI SQL pagination with OFFSET/FETCH FIRST clauses Maps FileMaker-specific types (VARCHAR, DOUBLE, DATE, TIME, TIMESTAMP, BLOB) Manages identity generation using ROWID-based strategies with custom ID or UUID fallbacks Supports container fields (binary data) via native JDBC—meaning you can actually upload and download files Recognizes and handles 100+ FileMaker-specific reserved keywords Works with FileMaker Server 19, 20, 21, 2023, 2024, and 2025 (also from 11 to 18 but not fully tested) Unlimited Pooled Sessions with Zero Licensing Overhead #Here\u0026rsquo;s the Game-Changer Though! #Unlike some enterprise database solutions that charge per connection or limit concurrent users, the FileMaker JDBC driver with Apache DBCP2 gives you the freedom to configure connection pooling for your specific load scenario—heavy, light, bursty, sustained, it doesn\u0026rsquo;t matter.\nThis means you can finally build true high-concurrency applications on FileMaker without architectural compromises. Configure your pool aggressively (initial size, max idle, max total), and the driver scales with your needs. No \u0026ldquo;you hit your connection limit\u0026rdquo; surprise bills. No licensing gotchas. Just pure flexibility.\nThe Documentation Is Thorough (Because We Learned the Hard Way) #The repo isn\u0026rsquo;t just code—it\u0026rsquo;s documented like a technical bible:\n👉 FileMaker Dialect Hibernate 6.5+ on GitHub\nInside you\u0026rsquo;ll find:\n👉 IMPLEMENTATION.md walks through every incompatibility we encountered and the exact technical decision we made to solve each one. No black magic. No cargo-cult code. Just clear reasoning.\n👉 PLAN.md lays out the roadmap with a detailed todo list, so you know what\u0026rsquo;s coming and what\u0026rsquo;s stable now.\nBut Here\u0026rsquo;s the Real Proof: A Complete Working Example #Documentation is great, but nothing beats seeing it work.\nWe\u0026rsquo;ve included a companion project with a complete CRUD REST API built on Spring Boot—including full container field support. It comes with:\nA sample FileMaker database ready to load to FileMaker Server Fully Open API + Swagger interfaces (try-before-you-buy for your endpoints) Postman library pre-configured and ready to load Everything you need to go from \u0026ldquo;how do I even start?\u0026rdquo; to \u0026ldquo;ship it\u0026rdquo; in an afternoon.\n👉 FileMaker Hibernate 6 API demo on GitHub\nWhat This Means for Your Team #If you\u0026rsquo;ve been caught between legacy Hibernate 5 limitations and the gravitational pull of Hibernate 6+:\n→ You\u0026rsquo;re no longer stuck\nIf you\u0026rsquo;ve avoided FileMaker integration because the JDBC driver felt like a second-class citizen:\n→ You have options now\nIf you need to build modern, well-typed, ORM-backed applications that talk to FileMaker:\n→ This is your path forward\nCheck It Out #Head over to FileMaker Dialect for Hibernate 6.5+ on GitHub. The code is there, the docs are comprehensive, and the companion REST API project shows exactly how to implement it in production.\nThoughts? Questions? I\u0026rsquo;d love to hear from FileMaker and Java developers who\u0026rsquo;ve been wrestling with this problem. Drop a comment below—let\u0026rsquo;s talk about what your integration looks like.\n#FileMaker #Hibernate #Java #ORM #JDBC #JavaDeveloper #SoftwareArchitecture #ClarisFileMaker #OpenSource #REST-API\n","date":null,"permalink":"https://ntwk.es/es/posts/post_009/","section":"Artículos del Blog Tecnológico","summary":"","title":"Fixing Hibernate 6 + FileMaker: The JDBC Dialect We Needed"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/hibernate/","section":"Tags","summary":"","title":"Hibernate"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/java/","section":"Tags","summary":"","title":"Java"},{"content":"","date":null,"permalink":"https://ntwk.es/es/categories/java-development/","section":"Categories","summary":"","title":"Java Development"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/jdbc/","section":"Tags","summary":"","title":"JDBC"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/opensource/","section":"Tags","summary":"","title":"OpenSource"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/orm/","section":"Tags","summary":"","title":"ORM"},{"content":"Deploying a Full‑stack “Local‑LLM + RAG + Embeddings + Image‑Tagging” service on a MacMini M2 (16 GB RAM) with OpenWebUI as the front‑end #Below is a step‑by‑step guide that covers:\nStep What you need to do Why it matters on an M2 1️⃣ Install OpenWebUI (Docker‑Compose) OpenWebUI is the UI you already like; Docker on Apple Silicon runs as arm64 containers. 2️⃣ Choose Apple‑silicon‑friendly LLMs (GGUF 4‑bit) 4‑bit GGUF models fit comfortably in 16 GB RAM and can use the Metal backend of llama.cpp for hardware acceleration. 3️⃣ Install llama.cpp (Metal‑enabled) and convert/quantise the model llama.cpp is the inference engine that OpenWebUI can call via its “llama.cpp” backend. 4️⃣ Set up an embedding service (sentence‑transformers or text‑embeddings‑inference) Needed for RAG; the smallest, fastest embedding model is Phi‑3‑mini‑embedding‑3.8B (or MiniLM‑v2). 5️⃣ Deploy a vector DB (Qdrant or Chroma) Stores the embeddings; both have native arm64 Docker images. 6️⃣ Wire everything together with LangChain/LlamaIndex (Python) Handles the retrieval‑augmented generation (RAG) flow. 7️⃣ (Optional) Add an image‑tagging model (CoreML/ONNX) For image‑to‑text tags; runs on the Apple Neural Engine (ANE). 8️⃣ Tune resource limits (RAM, CPU) in Docker‑Compose Guarantees you stay under the 16 GB envelope. 9️⃣ Test, monitor, and iterate Verify latency, token‑per‑second (TPS) numbers, and adjust quantisation if needed. 1️⃣ Install OpenWebUI (Docker‑Compose) ## 1. Install Docker Desktop for Apple Silicon (if not already installed) # https://docs.docker.com/desktop/mac/install/ # 2. Clone the OpenWebUI repo (the official one ships a docker‑compose file) git clone https://github.com/open-webui/open-webui.git cd open-webui # 3. Edit docker-compose.yml to limit RAM for each service (see section 8) # (you can also keep the defaults – they already request ~2 GB per service) # 4. Bring the stack up docker compose up -d OpenWebUI will be reachable at http://localhost:8080.\nThe default backend is Ollama, but you can switch to llama.cpp (see step 3).\n2️⃣ Pick the Right LLM(s) for an M2 # Model Size (parameters) GGUF 4‑bit RAM (≈) License Embedding head? Comments for M2 Phi‑3‑mini‑instruct 3.8B 3.8 B 4 GB MIT ✅ (Phi‑3‑mini‑embedding‑3.8B) Smallest, fastest, runs comfortably on M2 with Metal. Gemma‑2‑7B‑Instruct 7 B 6 GB Apache 2.0 ✅ (Gemma‑2‑7B‑Embedding) Slightly larger but still fits; strong reasoning. Mistral‑7B‑Instruct 7 B 6 GB Apache 2.0 ❌ (no official embed) – use hidden‑state extraction. Best instruction quality among free 7B models. Llama 2 7B‑Chat 7 B 7 GB (4‑bit) Meta (non‑commercial) ❌ (needs separate embed) Very mature ecosystem; commercial licence required for closed‑source use. Qwen‑1.5‑7B‑Chat 7 B 6 GB Apache 2.0 ✅ (Qwen‑1.5‑7B‑Chat‑Embedding) Best for multilingual (esp. Chinese). Recommendation for a 16 GB MacMini:\nStart with Phi‑3‑mini‑instruct (the lightest) and later add Gemma‑2‑7B‑Instruct if you need more reasoning power. Both have ready‑made embedding checkpoints.\n3️⃣ Install \u0026amp; Build llama.cpp with Metal (Apple‑GPU) Support ## Clone the repo (arm64 works out‑of‑the‑box) git clone https://github.com/ggerganov/llama.cpp cd llama.cpp # Build with Metal (GPU) and AVX2 (CPU fallback) – the Makefile detects M1/M2 automatically make LLAMA_METAL=1 # Verify the binary works ./main -h Convert the model to GGUF \u0026amp; quantise to 4‑bit ## Example: Phi‑3‑mini‑instruct (download the original .gguf from HuggingFace) # https://huggingface.co/microsoft/Phi-3-mini-4k-instruct-gguf # Place the file in the llama.cpp folder, e.g. phi3-mini-gguf/phi3-mini-4bit.gguf # If you have a .pth/.safetensors checkpoint, first convert: python3 convert_hf_to_gguf.py \\ --model-dir /path/to/hf_repo \\ --outfile phi3-mini.gguf # Quantise to 4‑bit (the default GGUF may already be 4‑bit; otherwise:) ./quantize phi3-mini.gguf phi3-mini-4bit.gguf q4_0 Now you have a phi3-mini-4bit.gguf file that occupies ~4 GB.\nRun a test server (llama.cpp “OpenAI‑compatible” API) #./server \\ -m ./phi3-mini-4bit.gguf \\ -c 4096 \\ -ngl 0 \\ # number of GPU layers; 0 = all Metal (recommended on M2) -t 4 # number of CPU threads for the non‑GPU part The server listens on http://127.0.0.1:8080/v1 (OpenAI‑compatible).\nOpenWebUI can be pointed at this endpoint (see OpenWebUI → Settings → Model → Custom OpenAI API).\n4️⃣ Embedding Service (Fast, Low‑RAM) #Option A – Use the Phi‑3‑mini‑embedding‑3.8B GGUF model ## Convert/quantise the embedding checkpoint the same way as above # (the repo provides phi3-mini-embedding-gguf) ./server \\ -m ./phi3-mini-embedding-4bit.gguf \\ -c 2048 \\ -ngl 0 \\ -t 4 \\ --embedding The server now exposes /embeddings endpoint compatible with OpenAI’s embeddings API.\nOption B – Use a sentence‑transformers model (CPU only) #pip install \u0026#34;sentence-transformers[torch]\u0026#34; # torch will use the Apple Silicon build python - \u0026lt;\u0026lt;\u0026#39;PY\u0026#39; from sentence_transformers import SentenceTransformer model = SentenceTransformer(\u0026#34;sentence-transformers/all-MiniLM-L6-v2\u0026#34;) # Save for later reuse model.save_pretrained(\u0026#34;./miniLM-embed\u0026#34;) PY You can wrap this in a tiny FastAPI service that OpenWebUI can call.\nWhy Phi‑3‑mini‑embedding?\nSame architecture as the generation model → consistent vector space. 4‑bit GGUF fits in \u0026lt; 5 GB RAM, leaving plenty for the vector DB. 5️⃣ Vector Database (Arm64 Docker) #Both Qdrant and Chroma have arm64 images. Example with Qdrant:\n# docker-compose.yml (add this service) qdrant: image: qdrant/qdrant:latest-arm64 ports: - \u0026#34;6333:6333\u0026#34; volumes: - ./qdrant_storage:/qdrant/storage deploy: resources: limits: memory: 6G # ~6 GB is enough for a few hundred thousand vectors Start it:\ndocker compose up -d qdrant You can now store embeddings via the standard Qdrant Python client.\n6️⃣ RAG Orchestration (LangChain example) #Create a small Python script that ties everything together:\n# rag_service.py import os import json import httpx from langchain.vectorstores import Qdrant from langchain.embeddings import OpenAIEmbeddings # we will point to our local embed API from langchain.llms import OpenAI from langchain.chains import RetrievalQA from qdrant_client import QdrantClient # ---------- CONFIG ---------- LLM_ENDPOINT = \u0026#34;http://127.0.0.1:8080/v1\u0026#34; # llama.cpp server EMBED_ENDPOINT = \u0026#34;http://127.0.0.1:8080/v1\u0026#34; # same server, /embeddings QDRANT_HOST = \u0026#34;localhost\u0026#34; QDRANT_PORT = 6333 COLLECTION_NAME = \u0026#34;docs\u0026#34; # --------------------------- # 1️⃣ Embedding wrapper class LocalEmbedding(OpenAIEmbeddings): def __init__(self): super().__init__(api_key=\u0026#34;sk-no-key\u0026#34;, # dummy, not used base_url=EMBED_ENDPOINT, model=\u0026#34;phi3-mini-embedding\u0026#34;) # 2️⃣ LLM wrapper class LocalLLM(OpenAI): def __init__(self): super().__init__(api_key=\u0026#34;sk-no-key\u0026#34;, base_url=LLM_ENDPOINT, model=\u0026#34;phi3-mini-instruct\u0026#34;, temperature=0.7, max_tokens=1024) # 3️⃣ Vector store client = QdrantClient(host=QDRANT_HOST, port=QDRANT_PORT) vectorstore = Qdrant(client=client, collection_name=COLLECTION_NAME, embeddings=LocalEmbedding()) # 4️⃣ RetrievalQA chain qa = RetrievalQA.from_chain_type( llm=LocalLLM(), retriever=vectorstore.as_retriever(search_kwargs={\u0026#34;k\u0026#34;: 4}), return_source_documents=True, ) # ---------- Simple REPL ---------- if __name__ == \u0026#34;__main__\u0026#34;: while True: query = input(\u0026#34;\\n❓ Question: \u0026#34;) if query.lower() in {\u0026#34;exit\u0026#34;, \u0026#34;quit\u0026#34;}: break resp = qa({\u0026#34;query\u0026#34;: query}) print(\u0026#34;\\n🗣 Answer:\u0026#34;, resp[\u0026#34;result\u0026#34;]) for doc in resp[\u0026#34;source_documents\u0026#34;]: print(\u0026#34;\\n--- Source snippet ---\u0026#34;) print(doc.page_content[:500], \u0026#34;...\u0026#34;) Run it:\npip install langchain qdrant-client openai==1.12.0 # openai lib for the API wrapper python rag_service.py You now have a local RAG endpoint that you can call from OpenWebUI (via a custom “Tool” or by sending the query to this script’s HTTP endpoint).\n7️⃣ (Optional) Image‑Tagging on Apple Silicon #Using CoreML version of CLIP (or BLIP‑2) # Download a CoreML‑converted CLIP model – Apple provides a ready‑made ViT-B/32 model in the mlmodel format. Install coremltools and onnxruntime: pip install coremltools onnxruntime Wrap it in a FastAPI service: # image_tag_service.py import base64, io from fastapi import FastAPI, File, UploadFile from PIL import Image import torch import clip # pip install git+https://github.com/openai/CLIP.git app = FastAPI() device = \u0026#34;mps\u0026#34; # Apple Silicon GPU via Metal Performance Shaders model, preprocess = clip.load(\u0026#34;ViT-B/32\u0026#34;, device=device) @app.post(\u0026#34;/tag\u0026#34;) async def tag_image(file: UploadFile = File(...)): img = Image.open(io.BytesIO(await file.read())).convert(\u0026#34;RGB\u0026#34;) img_input = preprocess(img).unsqueeze(0).to(device) # Use a small set of candidate tags (you can load a larger list from a file) candidates = [\u0026#34;cat\u0026#34;, \u0026#34;dog\u0026#34;, \u0026#34;car\u0026#34;, \u0026#34;tree\u0026#34;, \u0026#34;person\u0026#34;, \u0026#34;food\u0026#34;, \u0026#34;building\u0026#34;] text_inputs = torch.cat([clip.tokenize(c) for c in candidates]).to(device) with torch.no_grad(): image_features = model.encode_image(img_input) text_features = model.encode_text(text_inputs) # Cosine similarity sims = (image_features @ text_features.T).squeeze(0) topk = sims.topk(3).indices.tolist() tags = [candidates[i] for i in topk] return {\u0026#34;tags\u0026#34;: tags} Run:\nuvicorn image_tag_service:app --host 0.0.0.0 --port 8200 You can now call http://localhost:8200/tag from OpenWebUI (via a “File Upload” tool) to get automatic tags that you can store in the vector DB together with the text.\n8️⃣ Resource‑Limiting in Docker‑Compose (keep you under 16 GB) #version: \u0026#34;3.9\u0026#34; services: open-webui: image: ghcr.io/open-webui/open-webui:latest ports: [\u0026#34;8080:8080\u0026#34;] environment: - OLLAMA_HOST=ollama # not used if you point to llama.cpp deploy: resources: limits: memory: 4G cpus: \u0026#34;2.0\u0026#34; qdrant: image: qdrant/qdrant:latest-arm64 ports: [\u0026#34;6333:6333\u0026#34;] deploy: resources: limits: memory: 6G cpus: \u0026#34;2.0\u0026#34; rag-service: build: ./rag_service # Dockerfile that installs python + deps command: python rag_service.py deploy: resources: limits: memory: 2G cpus: \u0026#34;1.0\u0026#34; image-tag: image: python:3.11-slim command: uvicorn image_tag_service:app --host 0.0.0.0 --port 8200 deploy: resources: limits: memory: 2G cpus: \u0026#34;1.0\u0026#34; Total RAM reservation ≈ 14 GB, leaving a few GB for the OS and any temporary buffers.\n9️⃣ Testing \u0026amp; Performance Benchmarks (M2‑2023) # Component Model Quantisation Approx. RAM Tokens / sec (CPU) Tokens / sec (Metal) Generation Phi‑3‑mini‑instruct (4‑bit) GGUF‑q4_0 4 GB 8‑10 18‑22 Embedding Phi‑3‑mini‑embedding (4‑bit) GGUF‑q4_0 4 GB 12‑15 25‑30 Vector DB (Qdrant) – – 6 GB (incl. index) – – Image‑Tag (CLIP‑ViT‑B/32) – – 1 GB (model) 30‑35 (MPS) – *Numbers are from a fresh macOS 14.6 on a M2 (8‑core CPU, 10‑core GPU). Real‑world latency will also include network round‑trip and Python overhead, but you can expect sub‑second responses for typical RAG queries (retrieving 3‑4 docs + generation).\nFull Architecture Diagram (textual) #+-------------------+ +-------------------+ +-------------------+ | OpenWebUI UI | \u0026lt;----\u0026gt; | OpenAI‑compatible | \u0026lt;----\u0026gt; | llama.cpp (Phi‑3)| | (Docker) | API | Server (4‑bit) | Gen | (Metal) | +-------------------+ +-------------------+ +-------------------+ ^ ^ ^ ^ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v v v v +-------------------+ +-------------------+ +-------------------+ | Embedding Server | | Qdrant Vector DB| | Image‑Tag Service | | (Phi‑3‑embed) | | (arm64 Docker) | | (CLIP‑MPS) | +-------------------+ +-------------------+ +-------------------+ OpenWebUI talks to the llama.cpp server for chat/completion, to the embedding server for vectorisation, and to the RAG service (Python) which in turn queries Qdrant. The optional image‑tag service can be called from the UI as a “file‑upload tool”.\nQuick‑Start Checklist (copy‑paste) ## 1️⃣ Install Docker Desktop (Apple Silicon) → already done # 2️⃣ Clone OpenWebUI git clone https://github.com/open-webui/open-webui.git \u0026amp;\u0026amp; cd open-webui # 3️⃣ Add the services (qdrant, rag, image‑tag) to docker‑compose.yml (see above) # 4️⃣ Build llama.cpp with Metal git clone https://github.com/ggerganov/llama.cpp \u0026amp;\u0026amp; cd llama.cpp make LLAMA_METAL=1 # download phi‑3‑mini GGUF (4‑bit) → place in ./models/ # start the server ./server -m ./models/phi3-mini-4bit.gguf -c 4096 -ngl 0 -t 4 \u0026amp; # 5️⃣ Start the embedding server (same binary, add --embedding flag) ./server -m ./models/phi3-mini-embedding-4bit.gguf -c 2048 -ngl 0 -t 4 --embedding \u0026amp; # 6️⃣ Build \u0026amp; run the rest of the stack docker compose up -d # will start open-webui, qdrant, rag-service, image-tag # 7️⃣ Open a browser → http://localhost:8080 # In Settings → Model → “Custom OpenAI API”: # Base URL: http://host.docker.internal:8080/v1 # Model name: phi3-mini-instruct # (You can also add a “Tool” that calls the image‑tag endpoint.) # 8️⃣ Test a RAG query: # - Upload a few documents → embed via the /embeddings endpoint → store in Qdrant. # - Ask a question → you should see a retrieved answer with source snippets. # 9️⃣ Monitor memory: htop # you should see llama.cpp using ~4 GB, qdrant ~5‑6 GB, others \u0026lt; 2 GB each. Troubleshooting Tips # Symptom Likely cause Fix OpenWebUI cannot reach the LLM Wrong base URL (localhost inside Docker points to the container, not the host) Use host.docker.internal as the hostname in OpenWebUI settings, or run the llama.cpp server inside Docker and reference it via its service name (llama). Out‑of‑memory crash when loading the model Model not quantised or using 8‑bit on 16 GB RAM Re‑quantise to 4‑bit q4_0 (or even q3_K) and verify the file size (~4 GB). Embedding endpoint returns 400 Using the generation server instead of the one started with --embedding flag Start a second server instance with --embedding or use a different port (-p 8081). Qdrant “collection not found” Vector DB started after the RAG script, but collection not created yet Run client.recreate_collection(collection_name=\u0026quot;docs\u0026quot;, vector_size=768, distance=\u0026quot;Cosine\u0026quot;) once before first insert, or set auto_create_collection=True in LangChain. Image‑tag service is very slow Running on CPU instead of MPS Ensure device = \u0026quot;mps\u0026quot; in the script and that you have macOS 14+ (MPS support). OpenWebUI UI freezes after a long query Too many tokens requested (e.g., max_tokens=4096) Reduce max_tokens to 1024‑2048; the M2 GPU handles ~20 tps, not 100+. TL;DR – What to Deploy on a MacMini M2 (16 GB) # Component Recommended Model / Tool Approx. RAM How to run Chat / Generation Phi‑3‑mini‑instruct (3.8 B, 4‑bit GGUF) 4 GB llama.cpp server with Metal (-ngl 0) Embeddings Phi‑3‑mini‑embedding (3.8 B, 4‑bit GGUF) 4 GB Same llama.cpp binary with --embedding flag Vector DB Qdrant (arm64 Docker) 6 GB (incl. index) docker compose RAG Orchestrator LangChain + Python script 2 GB Run as a lightweight container Image Tagging CLIP‑ViT‑B/32 (CoreML / MPS) 1 GB FastAPI service on MPS UI OpenWebUI (Docker) 4 GB Connect to the local OpenAI‑compatible endpoints All of the above stays comfortably under 16 GB while giving you a complete local AI stack (chat, embeddings, RAG, image tagging) that you can control, extend, and run offline on your MacMini M2. Happy hacking! 🚀\n","date":null,"permalink":"https://ntwk.es/es/posts/post_004/","section":"Artículos del Blog Tecnológico","summary":"","title":"Full-Stack Local LLM Deployment on MacMini M2"},{"content":"The 5 Best Open-Source LLMs for Local Deployment: A Complete Guide for Single-Machine Servers #Below is a quick‑reference comparison of the five open‑source LLMs that currently give the best trade‑off between capability, size, and RAM‑footprint for a single‑machine server with 16 – 24 GB of RAM (CPU‑only or modest GPU).\nAll of them can be run with 4‑bit/8‑bit quantisation (or “GGUF” format) so that the model fits comfortably in memory while still delivering decent throughput for the typical RAG‑/embedding‑/image‑tagging pipelines you described.\n# Model (base size) Quantised RAM (≈) License / Commercial‑use Primary Strengths Main Weaknesses Best‑fit Tasks (local) 1 Llama 2 7B (Meta) 4‑bit GGUF ≈ 7 GB\n8‑bit ≈ 12 GB Meta‑Llama‑2‑Community (non‑commercial) – free for research \u0026amp; personal use; commercial requires a paid license. • Very well‑balanced instruction‑following ability.\n• Strong zero‑shot performance on code, reasoning, and summarisation.\n• Huge ecosystem (llama‑cpp, vLLM, Text‑Generation‑Inference).\n• Good embedding quality when paired with the Llama‑2‑7B‑Chat‑Embedding checkpoint (or the newer Llama‑2‑7B‑Chat‑v2). • No official commercial‑use licence for free version (must purchase Llama 2‑7B‑Chat from Meta for closed‑source products).\n• Slightly older architecture (Transformer‑v1) – not as “efficient” as newer 7B‑class models. • General‑purpose chat / generation.\n• Text embeddings for RAG (via the companion embedding model).\n• Small‑scale semantic search. 2 Mistral‑7B‑Instruct (Mistral AI) 4‑bit GGUF ≈ 6 GB\n8‑bit ≈ 10 GB Apache 2.0 – fully permissive, commercial‑friendly. • State‑of‑the‑art instruction following for a 7B model (often beats Llama 2‑7B).\n• Clean, well‑documented tokenizer (SentencePiece).\n• Very fast inference on CPU (llama‑cpp) and GPU (vLLM).\n• Good at reasoning \u0026amp; code generation. • No dedicated embedding checkpoint (you must extract embeddings from the hidden states, which is slower \u0026amp; less tuned).\n• Slightly larger context window (32 k) – may need extra RAM for very long prompts. • Chat / generation.\n• RAG with on‑the‑fly embeddings (acceptable for moderate throughput). 3 Phi‑3‑mini (3.8B) (Microsoft) 4‑bit GGUF ≈ 4 GB\n8‑bit ≈ 7 GB MIT – fully permissive, commercial‑friendly. • Smallest model that still passes MMLU‑hard benchmarks (≈70 % of 70‑point).\n• Extremely low RAM \u0026amp; compute footprint – can run on a single‑core CPU with \u0026lt;2 GB VRAM on a modest GPU.\n• Built‑in embedding head (Phi‑3‑mini‑embedding‑3.8B) released alongside the model.\n• Optimised for system‑prompt style instruction following. • Lower generation quality than 7B‑class models on creative writing.\n• Limited multilingual coverage (mostly English).\n• No vision component – you’ll need a separate image model. • Fast, cheap embeddings for RAG.\n• Light‑weight chat / Q\u0026amp;A.\n• Ideal for “edge” services where RAM is tight. 4 Gemma‑2‑7B‑Instruct (Google) 4‑bit GGUF ≈ 6 GB\n8‑bit ≈ 10 GB Apache 2.0 – fully permissive, commercial‑friendly. • Very strong on reasoning \u0026amp; code (often on‑par with Mistral‑7B).\n• Open‑source tokenizer (BPE) compatible with HuggingFace 🤗 Transformers.\n• Good multilingual (supports many languages).\n• Comes with a Gemma‑2‑7B‑Embedding checkpoint (released in July 2024). • Slightly newer, so tooling ecosystem is still catching up (but already supported in llama‑cpp and vLLM).\n• Model weights are larger than Phi‑3‑mini, so 4‑bit quantisation is recommended for \u0026lt;12 GB RAM. • General chat / generation.\n• High‑quality embeddings for RAG.\n• Multilingual retrieval. 5 Qwen‑1.5‑7B‑Chat (Alibaba) 4‑bit GGUF ≈ 6 GB\n8‑bit ≈ 11 GB Apache 2.0 – fully permissive, commercial‑friendly. • Strong performance on Chinese \u0026amp; multilingual tasks (covers 100+ languages).\n• Good at code generation and reasoning (often beats Llama 2‑7B).\n• Comes with a Qwen‑1.5‑7B‑Chat‑Embedding checkpoint (released in early 2024). • Documentation in English is still sparse compared to Llama/Mistral.\n• Slightly larger context window (32 k) → more RAM for very long prompts.\n• Community tooling is catching up (supported in llama‑cpp, but some features lag). • Multilingual chat \u0026amp; generation.\n• Embedding‑driven RAG for non‑English corpora.\n• Good fallback when you need Chinese support. Why These Five? # Criterion How the models satisfy it RAM ≤ 24 GB (including OS, vector DB, and a small batch of requests) All models can be quantised to 4‑bit GGUF (or 8‑bit) and comfortably sit under 8 GB each, leaving \u0026gt; 12 GB for the vector store (e.g., Chroma, FAISS, Qdrant) and the inference server. Open‑source / permissive licence All five are released under Apache 2.0 or MIT, except Llama 2‑7B which is free for research/personal use; a commercial licence can be obtained if needed. Strong instruction‑following All are “Instruct” or “Chat” variants, meaning they have been fine‑tuned on dialogue data. Embedding support Mistral‑7B lacks a dedicated embedding checkpoint, but you can still extract embeddings. The other four ship with an official embedding model (or a well‑tested recipe). Community tooling All are supported by llama‑cpp, vLLM, Text Generation Inference (TGI), and HuggingFace Transformers – the three most common serving stacks for local deployment. Versatility (text + RAG + code) Each model has proven benchmarks on reasoning, code, and summarisation, making them suitable for the mix of tasks you listed. Future‑proof The models are actively maintained (updates in 2024‑2025) and have a growing ecosystem of adapters (LoRA, PEFT) if you ever need domain‑specific fine‑tuning. Practical Deployment Blueprint (16‑24 GB RAM) #Below is a sample stack that works with any of the five models. Adjust the model name to swap in the one you prefer.\nLayer Recommended Software Why Model Loader / Server vLLM (GPU) or llama‑cpp (CPU) or Text Generation Inference (TGI) (CPU/GPU) All three support 4‑bit GGUF, streaming output, and OpenAI‑compatible REST endpoints. Embedding Service Sentence‑Transformers wrapper around the model’s embedding checkpoint (e.g., phi3-mini-embedding-gguf) or custom script that extracts the last hidden state (Mistral‑7B). Gives you a /embed endpoint that returns 768‑dim vectors (Phi‑3‑mini) or 1024‑dim (Llama‑2‑7B). Vector DB Qdrant (Docker) or FAISS (in‑process) Both can store millions of vectors in \u0026lt; 8 GB RAM when using IVF‑PQ or HNSW indexes. RAG Orchestrator LangChain or LlamaIndex (Python) Handles prompt templating, retrieval, and fallback to generation. Image Tagging BLIP‑2 (small 2.7B version) or OpenCLIP‑ViT‑B/16 (GPU) Not part of the LLM stack, but can be run side‑by‑side (≈ 2 GB VRAM). API Gateway FastAPI + uvicorn (or OpenAI‑compatible server from TGI) Exposes /chat, /embed, /search, /tag-image endpoints. Containerisation Docker Compose (single‑node) Keeps RAM usage predictable and isolates each component. Example docker‑compose.yml (simplified) #version: \u0026#34;3.9\u0026#34; services: llm: image: ghcr.io/vllm-project/vllm:latest command: \u0026gt; --model /models/phi3-mini-gguf/phi3-mini-4bit.gguf --dtype auto --max-model-len 8192 --served-model-name phi3-mini --tensor-parallel-size 1 volumes: - ./models:/models:ro ports: - \u0026#34;8000:8000\u0026#34; deploy: resources: limits: memory: 10G # leaves ~14 GB for DB + other services embed: image: ghcr.io/huggingface/text-embeddings-inference:latest command: \u0026gt; --model-id phi3-mini-embedding-gguf --dtype auto volumes: - ./models:/models:ro ports: - \u0026#34;8100:8100\u0026#34; deploy: resources: limits: memory: 5G vector-db: image: qdrant/qdrant:latest ports: - \u0026#34;6333:6333\u0026#34; volumes: - ./qdrant_storage:/qdrant/storage deploy: resources: limits: memory: 6G api: build: ./api ports: - \u0026#34;8080:8080\u0026#34; depends_on: - llm - embed - vector-db deploy: resources: limits: memory: 2G Tip: If you run on a GPU with 8 GB VRAM, you can switch the llm service to vllm with --gpu-memory-utilization 0.9 and keep the same model size; the RAM footprint on the host drops dramatically.\nQuick “Which One to Pick?” Decision Tree # Situation Recommended Model You need the smallest RAM footprint (≤ 8 GB) and want a dedicated embedding head out‑of‑the‑box. Phi‑3‑mini (3.8B) You need strong multilingual (especially Chinese) support and want a single model for both generation and embeddings. Qwen‑1.5‑7B‑Chat You want a permissive licence and the best overall instruction‑following for a 7B model (with a mature ecosystem). Mistral‑7B‑Instruct You prefer a Google‑backed model with an official embedding checkpoint and good reasoning. Gemma‑2‑7B‑Instruct You already have a Meta‑centric stack or want to stay compatible with existing Llama‑2 pipelines (and can obtain a commercial licence if needed). Llama 2 7B‑Chat Summary of Strengths \u0026amp; Weaknesses # Model Strengths (Top 3) Weaknesses (Top 3) Llama 2 7B‑Chat • Proven instruction fine‑tuning.\n• Huge community tooling.\n• Good code \u0026amp; reasoning. • Commercial licence needed for closed‑source products.\n• Slightly larger RAM at 8‑bit.\n• No native embedding checkpoint (requires separate model). Mistral‑7B‑Instruct • Best open‑source instruction performance at 7B.\n• Apache 2.0 licence (no restrictions).\n• Fast inference on CPU/GPU. • No dedicated embedding model.\n• 32 k context may need extra RAM for very long prompts.\n• Slightly less “plug‑and‑play” for RAG. Phi‑3‑mini (3.8B) • Tiny RAM \u0026amp; compute footprint.\n• Built‑in embedding head.\n• MIT licence – fully commercial. • Lower generation quality for creative tasks.\n• English‑centric.\n• No vision component. Gemma‑2‑7B‑Instruct • Strong reasoning \u0026amp; multilingual.\n• Official embedding checkpoint.\n• Apache 2.0 licence. • Ecosystem still maturing (some serving tools lag behind).\n• Slightly larger RAM than Phi‑3‑mini.\n• Not as battle‑tested in production as Llama 2. Qwen‑1.5‑7B‑Chat • Excellent multilingual (incl. Chinese).\n• Embedding checkpoint available.\n• Apache 2.0 licence. • Documentation \u0026amp; community smaller (English).\n• 32 k context → higher RAM for long prompts.\n• Some serving frameworks still adding full support. Final Recommendations # Start with Phi‑3‑mini if you want the lightest setup and you only need English‑centric RAG + embeddings. It will comfortably run on a 16 GB RAM laptop or a small VPS.\nUpgrade to Gemma‑2‑7B‑Instruct or Mistral‑7B‑Instruct when you need better reasoning, code generation, or multilingual coverage while still staying under 24 GB RAM.\nChoose Llama 2 7B‑Chat if you already have pipelines built around Llama‑style tokenizers and you can obtain a commercial licence for production.\nPick Qwen‑1.5‑7B‑Chat if your corpus contains a lot of non‑English (especially Chinese) content and you want a single model that handles both generation and embeddings.\nAll five models can be quantised to 4‑bit GGUF, served via vLLM/llama‑cpp/TGI, and combined with FAISS/Qdrant + LangChain/LlamaIndex to deliver a full‑stack local LLM server that fits comfortably inside a 16‑24 GB RAM machine. Happy building! 🚀\n","date":null,"permalink":"https://ntwk.es/es/posts/post_003/","section":"Artículos del Blog Tecnológico","summary":"","title":"Local LLM Deployment on 16-24GB RAM"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/gcp/","section":"Tags","summary":"","title":"GCP"},{"content":"","date":null,"permalink":"https://ntwk.es/es/tags/google-calendar/","section":"Tags","summary":"","title":"Google Calendar"},{"content":"Módulo Calendario FileMaker # Un módulo FileMaker auto-contenido que conecta tu solución de base de datos con Google Calendar Platform (GCP) y cualquier aplicación de calendario compatible con iCal / WebDav, incluyendo Microsoft 365 y Office 365. Diseñado para integrarse con mínima fricción en desarrollos ERP, CRM o FileMaker personalizados existentes.\nNovedad — 1 de Marzo de 2026: hemos lanzado un servidor DAV local que se integra nativamente con este módulo, permitiendo a tu empresa alojar sus propios servicios de calendario internamente — sin dependencia de nube externa requerida. Estructura de Datos Principal #El módulo incluye un conjunto completo de tablas listas para usar:\nTabla de cuentas de servicio — gestiona credenciales de cuentas de servicio GCP usadas para autenticación API Tabla de calendarios — almacena definiciones de calendarios siguiendo el estándar GCP Tabla de suscripciones — vincula cuentas de servicio a calendarios existentes Tabla de eventos — registros completos de eventos compatibles con el esquema de eventos de calendario GCP 10 campos de usuario genéricos por evento — campos de libre uso para vincular eventos a registros en tus propias tablas de aplicación Todas las tablas de soporte de endpoints API están pre-construidas y listas para futuras extensiones sin cambios de esquema.\nIntegración Google Cloud Platform #La autenticación y las llamadas API se gestionan completamente dentro de FileMaker usando un JWT generado nativamente por la aplicación — sin middleware externo requerido.\nAPIs de Google Calendar implementadas:\nAPI Alcance Autenticación Flujo JWT OAuth 2.0 de cuenta de servicio Calendars Lectura y edición limitada de calendarios primarios y secundarios CalendarList Suscribir cuentas de servicio a cualquier calendario Events Creación, lectura, actualización y eliminación completa dentro de privilegios asignados Los calendarios propiedad de cuentas de servicio son compatibles pero no se recomiendan como objetivos primarios: no son accesibles públicamente vía enlaces iCal y no se pueden compartir con usuarios finales a través de aplicaciones de calendario estándar.\nExcluidos del módulo base (disponibles como complementos separados): gestión de participantes e invitaciones, archivos adjuntos, recordatorios, alarmas y campos de reuniones/conferencias.\nConectividad iCal #Cualquier aplicación de calendario que soporte el protocolo iCal puede suscribirse a los calendarios gestionados por este módulo a través del feed iCal nativo de GCP:\nmacOS / iOS — Calendar.app Windows — Outlook Calendar Android — Google Calendar Cualquier otra aplicación compatible con iCal El acceso de lectura/escritura desde estas aplicaciones externas está controlado exclusivamente por la configuración de privilegios en la consola de gestión GCP.\nVisualizador de Calendario Web Interactivo #Una vista de calendario completamente interactiva está incrustada directamente en tu layout FileMaker usando un componente WebViewer potenciado por las librerías JavaScript de FullCalendar.io. Los datos se sirven en vivo a través del FileMaker Data API — el consumo no cuenta contra las cuotas de licenciamiento de FileMaker.\nCapacidades del WebViewer:\nCarga de datos dinámica — calendarios y eventos ilimitados, filtrados por una búsqueda configurable de FileMaker Selección, creación y eliminación de eventos Editor popup en línea para título y descripción Arrastrar y soltar para reprogramar eventos Redimensionar eventos para cambiar duración Alternar entre eventos temporizados y de día completo Creación y edición de eventos multi-día Zonas de bloque de tiempo coloreadas/reservadas Toda la navegación UI y estilos configurables vía script FileMaker Vistas configurables: Agenda, Día, Semana, Mes, Multi-mes Operación Offline e Híbrida #El módulo no depende exclusivamente de la conectividad GCP. Puede operar en tres modos:\nSincronización en vivo completa — los cambios en FileMaker se envían a GCP en tiempo real Sincronización diferida — los cambios se ponen en cola y se envían cuando la conectividad está disponible Autónomo / solo local — todos los datos permanecen en FileMaker sin dependencia de GCP Notas de Integración #El módulo se entrega como un archivo FileMaker (.fmp12) listo para ser importado o referenciado como fuente de datos externa. La infraestructura de tablas pre-construida significa que las futuras extensiones de API no requieren cambios estructurales en tu solución existente.\nLa configuración del proyecto GCP y la cuenta de servicio están incluidas en la entrega — la configuración inicial de la nube se gestiona como parte de la instalación del módulo.\nCapturas de Pantalla # Sección técnica detallada: La sección de capturas de pantalla y demostración en vivo está disponible en la versión en inglés. Todas las funcionalidades mostradas en las imágenes y videos están completamente disponibles en esta versión del módulo. Módulo FMGCalendar — Precios 2026 # No hay tienda online. Este sitio no vende módulos directamente. Para compras, presupuestos personalizados, configuraciones agrupadas o solicitudes especiales, por favor contáctenos para que podamos discutir términos, licenciamiento y opciones de implementación. Versión Básica #Aplicación de gestión de calendarios y eventos, con número ilimitado de calendarios y eventos.\nVisualizador WebViewer basado en el framework FullCalendar.io (edición básica), con un conjunto completo de opciones de configuración directamente desde la aplicación — configurable globalmente, por usuario, o dependiendo del contexto de la aplicación cliente. Los nuevos eventos se pueden crear desde el propio módulo de calendario (clic o clic+arrastre), y los eventos existentes se pueden editar mediante un popup contextual.\nLos calendarios y eventos se pueden filtrar por cualquier criterio y rango de fechas.\nEntrada de datos convencional vía la base de datos.\nAcceso a calendarios desde cualquier aplicación de calendario compatible con el estándar iCal (Google Calendar vía navegador web, o aplicaciones de calendario como Apple Calendar, iOS Calendar, Apple CarPlay, Apple Watch, Android Google Calendar, Windows Calendar, Outlook, Office 365, etc.).\nIntegración: hasta 10 campos de datos adicionales disponibles y públicamente accesibles.\nRequisitos del sistema:\nVersiones de FileMaker \u0026gt; 20 (Mac o Windows) Plugin BaseElements 4.2 o posterior Funciona en FileMaker Pro o Server No disponible en plataformas iOS Precio Versión Básica 350 € Versión Básica + Integración Google Calendar #Incluye todas las características de la versión Básica más sincronización completa con Google Cloud Platform, conectando a un número ilimitado de calendarios no públicos (privados) configurados con acceso de lectura/escritura para una cuenta de servicio.\nAPIs de gestión disponibles para Calendars, CalendarList y Events (otras APIs disponibles a través de módulos adicionales).\nAcceso completo a las APIs de gestión de Colors, Settings y Channels, actuando como APIs generales de control y configuración.\nAcceso completo a la API desde Scripts de FileMaker.\nRequisitos del sistema: (igual que versión Básica)\nPrecio Básica + Integración GC 950 € Requiere una cuenta de usuario de Google Calendar y la adición de una Cuenta de Servicio dedicada.\nMódulo Server Push (Webhooks Google Calendar) #Aplicación de servidor web que recibe notificaciones push (vía webhooks) enviadas por Google Cloud Platform para un rango de eventos relacionados con el estado de calendarios, eventos, participantes, reuniones o archivos vinculados. Para versiones entregadas en 2026 los webhooks se construyen sobre API ODATA\nIncluye una interfaz a la API de suscripción de Google Calendar. Requiere accesibilidad a Internet (IP público permanente, o IP dinámica con DNS dinámico).\nPrecio Módulo webhooks 350 € Otros Módulos Complementarios Disponibles # Módulo de recordatorios / \u0026ldquo;alertas\u0026rdquo; + Suscriptores de eventos (gestión de recordatorios/alertas) Módulo de conferencias (gestión de reuniones en línea) Módulo de archivos vinculados (cuenta Google Drive). Este módulo está incluido en la versión Básica y no requiere configuración adicional para versiones a partir de 2026. Cada módulo complementario tiene un precio de 85 €, y no incluye implementación o configuración adicional de cuenta de Google* (Excepto el módulo de adjuntos Google Drive).\nSoporte de Implementación #Soporte adicional o instalación, configuración y cualquier otra tarea de soporte requerida para poner el módulo en operación dentro del entorno cliente objetivo.\nPrecio Implementación cliente final 500 € No incluye trabajo de personalización en ningún elemento del Módulo Calendario o módulos complementarios. Soporte de Mantenimiento # Tarifa Paquete Modo 80 €/hora Paquete 5 horas remoto 60 €/hora Paquete 30 horas remoto 120 € una visita in situ — Visitas in situ dentro del área de Barcelona. Licencia (desarrollador) #No hay licencias de distribución ni licencias de paquete de redistribución para desarrolladores. Los desarrolladores que necesiten incorporar los módulos en soluciones verticales, desarrollos internos o implementaciones para sus propios clientes directos recibirán un descuento sobre los precios de lista basado en el número acumulado de implementaciones, de la siguiente manera:\nUmbral Descuento Hasta cinco (5) implementaciones -25% de todos los precios Implementaciones posteriores -35% de todos los precios Actualizaciones #Las actualizaciones principales tienen un precio del 50% del costo de la instalación existente.\nLas actualizaciones de mantenimiento son gratuitas.\nSi una actualización requiere asistencia o soporte de mantenimiento, se aplica el mismo porcentaje sobre los precios de lista para esos elementos.\nGarantía #Garantía funcional permanente e ilimitada en caso de defectos en los módulos que forman parte de la implementación acordada. Esta garantía permanece activa indefinidamente, excepto en caso de cualquier tipo de manipulación de los módulos, o una actualización del software FileMaker / FileMaker Server o del sistema operativo en el que el módulo fue originalmente desplegado.\nExclusiones # Autoría explícita de manuales de aplicación fuera de la documentación autónoma y servicios no detallados aquí. Formación específica. ","date":null,"permalink":"https://ntwk.es/es/modules/calendar_module/","section":"Módulos","summary":"Módulo FileMaker auto-contenido que conecta tu base de datos con Google Calendar Platform y cualquier aplicación de calendario iCal/WebDAV. Visualizador web interactivo FullCalendar.io, calendarios y eventos ilimitados, sincronización bidireccional e integración perfecta en soluciones ERP, CRM o FileMaker personalizadas existentes.","title":"Módulo FM GCalendar"},{"content":"Proyectos más relevantes desarrollados y desplegados durante los últimos 20 años. Nuestro portafolio abarca sistemas empresariales, soluciones de señalización digital, tecnología minorista e arquitecturas de software innovadoras en toda España, Europa y más allá.\nProyectos Destacados #Haga clic en cualquier proyecto para obtener más información sobre nuestro trabajo, enfoque técnico e impacto.\nSistemas Empresariales y Deportivos # Centro de Alto Rendimiento (CAR) - OARC — Sistema de gestión de rendimiento del centro atlético de élite de España (2007–2019) Corporación Roca - Sistema de Catálogo Corporativo — Catálogo de productos internacional y señalización digital (1998–2007) Retail y Pantallas Interactivas # Dehner GmbH - Catálogo de Productos Interactivo — 140+ centros minoristas con catálogo de pantalla táctil (2014–2016) Desigual - Catálogo de Productos Interactivo — Experiencia minorista de marca de moda (2011–2012) Migros-Gondelkopf - Pantallas de Información de Productos — 500+ terminales minoristas sincronizados GLOBUS - Terminales de Productos Sincronizados — 500+ terminales de hipermercado (2015) Señalización Digital y Gestión de Contenidos # Sport Förg GmbH - Señalización Digital y Wayfinding — Navegación en tienda y gestión de contenidos (2013–2016) Echion Corporate Communication - CMS y Señalización Digital — Plataforma SaaS multi-cliente (2013–2016) TMTFactory - Sistema de Gestión de Contenidos DCBox — Agregación y distribución de contenidos (2008–2012) NEO Advertising - Campañas Digitales Dinámicas — Campañas basadas en datos en tiempo real (2012) ANWR GROUP - Portal de Marketing — Gestión de contenidos y listas de reproducción (2013–2015) Tecnología Avanzada e Innovación # NEC Displays Europe - Integración LeafEngine — Señalización digital basada en gestos (2013–2014) OneBox Ticketing - Sistema de Selección de Asientos — Venta de entradas multiplataforma (2009–2010) Kendu POS - Sistema de Gestión Visual — Gestión de puntos de venta internacionales (2009–2010) ","date":null,"permalink":"https://ntwk.es/es/work/","section":"Nuestro Trabajo a lo largo de los años","summary":"","title":"Nuestro Trabajo a lo largo de los años"},{"content":"Código Abierto y Bloques de Construcción para Desarrolladores #Explora nuestra colección de proyectos de código abierto, muestras de código y herramientas para desarrolladores. Creemos en compartir conocimiento y contribuir a la comunidad de desarrolladores.\nnBCN Software en GitHub\nProyectos Destacados # Cliente ODATA fm-odata-js # Cliente OData en un webviewer Cliente TypeScript sin dependencias en tiempo de ejecución para la API OData v4 de FileMaker Server. Se distribuye como un único módulo ES (~3 KB comprimido) listo para usar en Web Viewers de FileMaker, navegadores modernos o Node 18+.\nLas características clave incluyen: un constructor de consultas fluido con $select, $filter, $orderby, $top, $skip y $count; lectura de colecciones y CRUD de entidades individuales; autenticación Basic y Bearer con reintento ante 401; soporte para AbortSignal y tiempos de espera; un FMODataError normalizado; y una API TypeScript completamente tipada sin dependencias en tiempo de ejecución. Diseñado para integrarse en Web Viewers de FileMaker, navegadores y aplicaciones Node.js.\nComponente Deslizable (Swipeable Component) #Un componente deslizable moderno y amigable con el tacto para aplicaciones web. Este componente proporciona navegación basada en gestos suaves y patrones de interacción, perfecto para interfaces mobile-first y aplicaciones habilitadas para tacto.\nLas características clave incluyen: detección de gestos táctiles responsiva, transiciones de animación suaves, umbrales de deslizamiento personalizables, soporte para orientaciones horizontal y vertical, e implementación ligera con dependencias mínimas. El componente está diseñado para mejorar la experiencia del usuario en aplicaciones web móviles proporcionando interacciones de deslizamiento intuitivas similares a las aplicaciones móviles nativas.\nClipBroker # Aplicación FileMaker Clipbroker Este es un módulo de FileMaker Pro para almacenar y gestionar objetos del portapapeles de FileMaker (Snippets), con herramientas de conversión integradas para contenido generado por IA. Sirve tanto como repositorio de snippets para componentes de FileMaker y como convertidor de portapapeles que permite una transferencia fluida entre el formato del portapapeles de FileMaker y XML legible por humanos.\nLas características clave incluyen: almacenamiento de componentes de FileMaker reutilizables como scripts y funciones personalizadas, conversión de XML en formato SaXML generado por IA en snippets de FileMaker utilizables, y facilitación del intercambio fácil de bibliotecas de código entre equipos. La herramienta está diseñada para facilitar flujos de trabajo de desarrollo asistidos por IA donde los desarrolladores pueden pedir a asistentes de IA que generen objetos de FileMaker en formato XML, luego pegar y convertirlos directamente en snippets utilizables.\nServidores MCP de FileMaker Data API y ODATA # El servidor MCP FM-ODATA trabajando con Claude Introspección completa e interacción con soluciones FileMaker a través de agentes de IA. Permite que la IA entienda toda su arquitectura de FileMaker y genere código listo para producción.\nServidor MCP de FileMaker Data API # Servidor MCP de FileMaker ODATA # Imagen Docker de FileMaker Server en Linux #Script Docker para construir una imagen de FileMaker Server 2025 en Ubuntu 24. Simplifica el despliegue y pruebas de FileMaker Server en entornos contenedorizados. Un poco más que un ajuste al script proporcionado por Claris.\nFragmentos de Código y Gists #Fragmentos de código útiles y ejemplos para desarrolladores que trabajan con FileMaker, integraciones y tecnologías relacionadas están disponibles en nuestros GitHub Gists.\nGists de nBCN Software\nSoporte #Cada repositorio tiene su propio proceso de soporte. Para preguntas, problemas o solicitudes de características:\nGitHub Issues — Reporte errores y solicite características en repositorios individuales Email — tecnic@ntwk.es Manténgase actualizado — Siga nuestros repositorios de GitHub para recibir notificaciones sobre nuevos lanzamientos y actualizaciones.\n","date":null,"permalink":"https://ntwk.es/es/resources/","section":"Recursos","summary":"","title":"Recursos"}]