<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SotaTek | AI &amp; Blockchain Innovation Partner</title>
    <description>The latest articles on DEV Community by SotaTek | AI &amp; Blockchain Innovation Partner (@devsotatek).</description>
    <link>https://dev.to/devsotatek</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4117244%2F6229ec86-28dd-4441-b858-39daab536542.jpg</url>
      <title>DEV Community: SotaTek | AI &amp; Blockchain Innovation Partner</title>
      <link>https://dev.to/devsotatek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devsotatek"/>
    <language>en</language>
    <item>
      <title>RAG vs Fine-Tuning: Debug the Failure Before Changing the Model</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Mon, 12 Oct 2026 08:51:28 +0000</pubDate>
      <link>https://dev.to/devsotatek/rag-vs-fine-tuning-debug-the-failure-before-changing-the-model-1jbl</link>
      <guid>https://dev.to/devsotatek/rag-vs-fine-tuning-debug-the-failure-before-changing-the-model-1jbl</guid>
      <description>&lt;p&gt;RAG vs Fine-Tuning: Debug the Failure Before Changing the Model&lt;/p&gt;

&lt;p&gt;When an LLM application produces bad answers, the first instinct is often to change the model.&lt;/p&gt;

&lt;p&gt;Try a larger model. Add more examples to the prompt. Fine-tune it on domain-specific data. Maybe introduce a vector database.&lt;/p&gt;

&lt;p&gt;But these interventions solve different problems. Applying the wrong one can increase cost and complexity without improving the result.&lt;/p&gt;

&lt;p&gt;Consider two failure cases:&lt;/p&gt;

&lt;p&gt;An enterprise assistant gives an outdated answer because the latest policy never reached the model.&lt;/p&gt;

&lt;p&gt;A classification system has all the information it needs but repeatedly produces inconsistent output formats.&lt;/p&gt;

&lt;p&gt;The first is a knowledge-access problem. The second is a behavior problem.&lt;/p&gt;

&lt;p&gt;RAG changes what information the model can access at inference time. Fine-tuning changes the behavior learned by the model.&lt;/p&gt;

&lt;p&gt;At SotaTek, we approach this decision as an engineering problem: identify the failing layer, measure it, and introduce the smallest change that addresses the actual failure.&lt;/p&gt;

&lt;p&gt;Let's break down how to do that.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand What Each Technique Actually Changes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Retrieval-Augmented Generation (RAG)&lt;/p&gt;

&lt;p&gt;RAG retrieves external information at runtime and provides it as context to the LLM.&lt;/p&gt;

&lt;p&gt;User Query&lt;br&gt;
    |&lt;br&gt;
    v&lt;br&gt;
Query Processing&lt;br&gt;
    |&lt;br&gt;
    v&lt;br&gt;
Search / Retrieval&lt;br&gt;
    |&lt;br&gt;
    v&lt;br&gt;
Reranking and Context Selection&lt;br&gt;
    |&lt;br&gt;
    v&lt;br&gt;
LLM + Retrieved Evidence&lt;br&gt;
    |&lt;br&gt;
    v&lt;br&gt;
Answer + Source References&lt;/p&gt;

&lt;p&gt;The model's weights remain unchanged. The application changes the information available to the model for a particular request.&lt;/p&gt;

&lt;p&gt;This is useful when answers depend on private, changing, or traceable information, such as internal policies, product catalogs, technical documentation, or customer records.&lt;/p&gt;

&lt;p&gt;When a policy changes, the knowledge source can be updated and re-indexed without retraining the model.&lt;/p&gt;

&lt;p&gt;Fine-Tuning&lt;/p&gt;

&lt;p&gt;Fine-tuning adjusts a pretrained model using additional training examples to reinforce desired behavior.&lt;/p&gt;

&lt;p&gt;Suppose a model must transform incident reports into a fixed internal classification schema.&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "input": "Surface blistering detected near connector.",&lt;br&gt;
  "output": {&lt;br&gt;
    "category": "MATERIAL_DELAMINATION",&lt;br&gt;
    "severity": "S2",&lt;br&gt;
    "inspection_route": "MICROSCOPY"&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;A fine-tuning dataset can contain many representative input-output examples that demonstrate the required behavior.&lt;/p&gt;

&lt;p&gt;The objective is not primarily to teach the model which incident happened yesterday. It is to make the model more consistent at performing a particular task.&lt;/p&gt;

&lt;p&gt;This can be useful for specialized classification, structured extraction, domain-specific transformations, and high-volume tasks where prompt overhead or inference efficiency matters.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Diagnose the Failure Before Choosing a Solution&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A useful starting point is to separate the problem into three layers.&lt;/p&gt;

&lt;p&gt;Layer&lt;/p&gt;

&lt;p&gt;Diagnostic question&lt;/p&gt;

&lt;p&gt;Potential intervention&lt;/p&gt;

&lt;p&gt;Retrieval&lt;/p&gt;

&lt;p&gt;Did the system find the correct evidence?&lt;/p&gt;

&lt;p&gt;Improve search, metadata, chunking, or reranking&lt;/p&gt;

&lt;p&gt;Context&lt;/p&gt;

&lt;p&gt;Did the relevant evidence reach the model?&lt;/p&gt;

&lt;p&gt;Improve context selection and prompt construction&lt;/p&gt;

&lt;p&gt;Generation&lt;/p&gt;

&lt;p&gt;Did the model use the evidence correctly?&lt;/p&gt;

&lt;p&gt;Improve prompting, validation, or evaluate fine-tuning&lt;/p&gt;

&lt;p&gt;This distinction prevents a common mistake: trying to fix a retrieval failure by changing the model.&lt;/p&gt;

&lt;p&gt;Imagine an enterprise assistant that must answer questions about internal security policies.&lt;/p&gt;

&lt;p&gt;The correct policy exists in the knowledge base, but retrieval consistently ranks it outside the top five results.&lt;/p&gt;

&lt;p&gt;A larger LLM may generate a more convincing response, but it cannot reliably use evidence that never reaches its context window.&lt;/p&gt;

&lt;p&gt;The right intervention is probably in the retrieval pipeline, not model training.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Evaluate the Baseline Before Changing Anything&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before introducing RAG or fine-tuning, establish a baseline using representative test cases.&lt;/p&gt;

&lt;p&gt;For an enterprise assistant, you might track:&lt;/p&gt;

&lt;p&gt;Metric&lt;/p&gt;

&lt;p&gt;Baseline&lt;/p&gt;

&lt;p&gt;Answer accuracy&lt;/p&gt;

&lt;p&gt;71%&lt;/p&gt;

&lt;p&gt;Groundedness&lt;/p&gt;

&lt;p&gt;68%&lt;/p&gt;

&lt;p&gt;Format compliance&lt;/p&gt;

&lt;p&gt;91%&lt;/p&gt;

&lt;p&gt;Retrieval Recall@5&lt;/p&gt;

&lt;p&gt;62%&lt;/p&gt;

&lt;p&gt;These figures are illustrative, not benchmark results.&lt;/p&gt;

&lt;p&gt;Even this small dataset suggests a direction: retrieval recall is relatively weak, while format compliance is already stronger.&lt;/p&gt;

&lt;p&gt;Fine-tuning should not be the first intervention without further evidence. The system may be failing because it cannot retrieve the information required to answer correctly.&lt;/p&gt;

&lt;p&gt;For a RAG application, evaluate retrieval and generation separately.&lt;/p&gt;

&lt;p&gt;def evaluate_rag(query, expected_doc_ids, retriever, generator):&lt;br&gt;
    retrieved = retriever.search(&lt;br&gt;
        query=query,&lt;br&gt;
        top_k=5,&lt;br&gt;
    )&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;retrieved_ids = {
    document.id for document in retrieved
}

relevant_ids = set(expected_doc_ids)

recall_at_5 = (
    len(retrieved_ids &amp;amp; relevant_ids)
    / len(relevant_ids)
    if relevant_ids else 0.0
)

answer = generator.generate(
    query=query,
    context=retrieved,
)

return {
    "recall_at_5": recall_at_5,
    "answer": answer,
    "retrieved_count": len(retrieved),
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is a simplified evaluation example. A production implementation also needs to handle multiple relevant documents, retrieval ranking, empty results, access permissions, and answer-quality grading.&lt;/p&gt;

&lt;p&gt;The important principle is to measure the retrieval layer independently from the generation layer.&lt;/p&gt;

&lt;p&gt;Otherwise, a single answer-quality score tells you that something failed without telling you where to investigate.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Production RAG Pipeline Is More Than a Vector Database&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A basic RAG implementation often looks like this:&lt;/p&gt;

&lt;p&gt;Documents -&amp;gt; Embeddings -&amp;gt; Vector DB -&amp;gt; LLM&lt;/p&gt;

&lt;p&gt;That can demonstrate the concept, but production retrieval typically requires additional components:&lt;/p&gt;

&lt;p&gt;Document parsing and structure extraction&lt;/p&gt;

&lt;p&gt;Chunking and metadata enrichment&lt;/p&gt;

&lt;p&gt;Vector, lexical, or hybrid search&lt;/p&gt;

&lt;p&gt;Query rewriting&lt;/p&gt;

&lt;p&gt;Permission-aware filtering&lt;/p&gt;

&lt;p&gt;Reranking&lt;/p&gt;

&lt;p&gt;Context selection&lt;/p&gt;

&lt;p&gt;Citation mapping&lt;/p&gt;

&lt;p&gt;Retrieval and groundedness evaluation&lt;/p&gt;

&lt;p&gt;Consider a multi-tenant enterprise application.&lt;/p&gt;

&lt;p&gt;Retrieval must enforce the user's permissions before documents are passed into the model. Filtering the final answer afterward is not a substitute for preventing unauthorized context from entering the generation pipeline.&lt;/p&gt;

&lt;p&gt;A simplified retrieval flow might look like this:&lt;/p&gt;

&lt;p&gt;def answer_question(query, user):&lt;br&gt;
    candidates = search(&lt;br&gt;
        query=query,&lt;br&gt;
        workspace_id=user.workspace_id,&lt;br&gt;
        permissions=user.permissions,&lt;br&gt;
        top_k=30,&lt;br&gt;
    )&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ranked = rerank(
    query=query,
    documents=candidates,
)

context = select_context(
    documents=ranked,
    max_documents=5,
)

return llm.generate(
    question=query,
    context=context,
    instructions=(
        "Answer using the provided evidence. "
        "Cite sources for factual claims. "
        "If evidence is insufficient, say so."
    ),
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The functions are illustrative rather than tied to a specific framework. Authorization must also be enforced by a trusted application layer, not delegated to the model or a prompt instruction.&lt;/p&gt;

&lt;p&gt;If the correct information is already available but retrieval is poor, improve the retrieval system before assuming that the model needs fine-tuning.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When Fine-Tuning Becomes Worth Evaluating&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fine-tuning is more relevant when the model receives adequate information but repeatedly fails to perform the task in the required way.&lt;/p&gt;

&lt;p&gt;Typical signals include:&lt;/p&gt;

&lt;p&gt;Output schemas are inconsistent despite clear instructions.&lt;/p&gt;

&lt;p&gt;The same specialized classification task produces unstable results.&lt;/p&gt;

&lt;p&gt;Domain terminology is repeatedly misunderstood.&lt;/p&gt;

&lt;p&gt;Few-shot examples make the prompt excessively large.&lt;/p&gt;

&lt;p&gt;A smaller model needs to reproduce behavior previously achieved with a larger one.&lt;/p&gt;

&lt;p&gt;However, fine-tuning is not automatically the next step.&lt;/p&gt;

&lt;p&gt;Before training, check whether the failure can be solved with clearer instructions, structured output constraints, better examples, or simpler application logic.&lt;/p&gt;

&lt;p&gt;If fine-tuning is justified, keep training, validation, and final evaluation data separate.&lt;/p&gt;

&lt;p&gt;from sklearn.model_selection import train_test_split&lt;/p&gt;

&lt;p&gt;train_data, holdout_data = train_test_split(&lt;br&gt;
    examples,&lt;br&gt;
    test_size=0.20,&lt;br&gt;
    random_state=42,&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;train_data, validation_data = train_test_split(&lt;br&gt;
    train_data,&lt;br&gt;
    test_size=0.125,&lt;br&gt;
    random_state=42,&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;print("Training:", len(train_data))&lt;br&gt;
print("Validation:", len(validation_data))&lt;br&gt;
print("Holdout:", len(holdout_data))&lt;/p&gt;

&lt;p&gt;This produces an approximate 70/10/20 split.&lt;/p&gt;

&lt;p&gt;For production datasets, split by the appropriate unit, such as customer, document, time period, or source record, when random splitting could leak near-duplicate examples across datasets.&lt;/p&gt;

&lt;p&gt;After training, evaluate both the target behavior and potential regressions on previously supported tasks.&lt;/p&gt;

&lt;p&gt;A model that improves formatting but loses general capability may not be a worthwhile trade-off.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Compare Total System Cost, Not Just Model Cost&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;RAG and fine-tuning move engineering and operating costs to different places.&lt;/p&gt;

&lt;p&gt;Factor&lt;/p&gt;

&lt;p&gt;RAG&lt;/p&gt;

&lt;p&gt;Fine-tuning&lt;/p&gt;

&lt;p&gt;Initial engineering&lt;/p&gt;

&lt;p&gt;Data ingestion and retrieval&lt;/p&gt;

&lt;p&gt;Dataset preparation and training&lt;/p&gt;

&lt;p&gt;Knowledge updates&lt;/p&gt;

&lt;p&gt;Synchronize or re-index sources&lt;/p&gt;

&lt;p&gt;May require another tuning cycle&lt;/p&gt;

&lt;p&gt;Inference latency&lt;/p&gt;

&lt;p&gt;Retrieval and reranking add steps&lt;/p&gt;

&lt;p&gt;May use a simpler inference path&lt;/p&gt;

&lt;p&gt;Prompt size&lt;/p&gt;

&lt;p&gt;Retrieved context can be large&lt;/p&gt;

&lt;p&gt;Learned behavior may reduce prompt examples&lt;/p&gt;

&lt;p&gt;Main evaluation focus&lt;/p&gt;

&lt;p&gt;Retrieval and groundedness&lt;/p&gt;

&lt;p&gt;Task behavior and regression&lt;/p&gt;

&lt;p&gt;Maintenance&lt;/p&gt;

&lt;p&gt;Data freshness and retrieval quality&lt;/p&gt;

&lt;p&gt;Training data and model versions&lt;/p&gt;

&lt;p&gt;Source traceability&lt;/p&gt;

&lt;p&gt;Supported through retrieved metadata&lt;/p&gt;

&lt;p&gt;Not inherently provided by model weights&lt;/p&gt;

&lt;p&gt;Neither approach is universally cheaper or faster.&lt;/p&gt;

&lt;p&gt;RAG adds retrieval infrastructure and runtime work. Fine-tuning adds training, validation, artifact management, and model-version maintenance.&lt;/p&gt;

&lt;p&gt;The right comparison is the total cost per successful business task, including retries, human review, infrastructure, and operational maintenance.&lt;/p&gt;

&lt;p&gt;A lower inference cost per request does not necessarily translate into a lower cost per successful outcome.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When Both Techniques Make Sense&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Some applications genuinely have both problems.&lt;/p&gt;

&lt;p&gt;Consider an enterprise compliance assistant that must:&lt;/p&gt;

&lt;p&gt;Retrieve the latest regulations and internal policies.&lt;/p&gt;

&lt;p&gt;Compare relevant clauses.&lt;/p&gt;

&lt;p&gt;Apply an organization-specific classification scheme.&lt;/p&gt;

&lt;p&gt;Produce a structured review.&lt;/p&gt;

&lt;p&gt;Cite supporting evidence.&lt;/p&gt;

&lt;p&gt;RAG provides the current, traceable knowledge. Fine-tuning may help with the specialized output behavior if evaluation shows that prompting alone is insufficient.&lt;/p&gt;

&lt;p&gt;The architecture could look like this:&lt;/p&gt;

&lt;p&gt;User Request&lt;br&gt;
     |&lt;br&gt;
     v&lt;br&gt;
Permission-Aware Retrieval&lt;br&gt;
     |&lt;br&gt;
     v&lt;br&gt;
Current Evidence + Source Metadata&lt;br&gt;
     |&lt;br&gt;
     v&lt;br&gt;
Fine-Tuned Model&lt;br&gt;
     |&lt;br&gt;
     v&lt;br&gt;
Structured Output&lt;br&gt;
     |&lt;br&gt;
     v&lt;br&gt;
Validation + Citation Checks&lt;br&gt;
     |&lt;br&gt;
     v&lt;br&gt;
Human Review, If Required&lt;/p&gt;

&lt;p&gt;The two techniques operate at different layers.&lt;/p&gt;

&lt;p&gt;But combining them should be an evidence-based decision. Irrelevant retrieved context can introduce noise, even when the model has been fine-tuned successfully.&lt;/p&gt;

&lt;p&gt;Test the baseline, RAG-only, fine-tuning-only where appropriate, and hybrid configuration against the same held-out evaluation set.&lt;/p&gt;

&lt;p&gt;Keep the hybrid architecture only if the improvement justifies its additional complexity.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Practical Decision Framework&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use this sequence when deciding what to build:&lt;/p&gt;

&lt;p&gt;Start with the base model&lt;br&gt;
          |&lt;br&gt;
          v&lt;br&gt;
Can prompting and output constraints&lt;br&gt;
meet the evaluation target?&lt;br&gt;
          |&lt;br&gt;
     Yes  |  No&lt;br&gt;
      |   |&lt;br&gt;
      v   v&lt;br&gt;
   Ship   Diagnose the failure&lt;br&gt;
                |&lt;br&gt;
         +------+------+&lt;br&gt;
         |             |&lt;br&gt;
         v             v&lt;br&gt;
   Missing or      Inconsistent&lt;br&gt;
   stale knowledge behavior&lt;br&gt;
         |             |&lt;br&gt;
         v             v&lt;br&gt;
        RAG       Evaluate fine-tuning&lt;br&gt;
         |             |&lt;br&gt;
         +------+------+&lt;br&gt;
                |&lt;br&gt;
                v&lt;br&gt;
     Do both problems remain?&lt;br&gt;
                |&lt;br&gt;
          Yes   |   No&lt;br&gt;
           |    |&lt;br&gt;
           v    v&lt;br&gt;
        Evaluate  Keep the simplest&lt;br&gt;
         hybrid   working approach&lt;/p&gt;

&lt;p&gt;A few practical rules follow:&lt;/p&gt;

&lt;p&gt;If the model needs current, private, or source-backed information, start by evaluating RAG.&lt;/p&gt;

&lt;p&gt;If the information is already available but the model consistently performs the task incorrectly, investigate behavior and prompting before considering fine-tuning.&lt;/p&gt;

&lt;p&gt;If both knowledge access and specialized behavior are failing, evaluate the two interventions independently before combining them.&lt;/p&gt;

&lt;p&gt;If the base model already meets the acceptance criteria, avoid adding infrastructure without a measurable reason.&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;RAG and fine-tuning are not competing ways to make an LLM smarter. They address different failure modes.&lt;/p&gt;

&lt;p&gt;RAG changes the evidence available to the model. Fine-tuning changes the behavior learned by the model.&lt;/p&gt;

&lt;p&gt;The engineering challenge is to identify which layer is failing and prove that the proposed intervention improves the result.&lt;/p&gt;

&lt;p&gt;That requires more than selecting a model or a vector database. It requires representative evaluation data, clear metrics, reliable retrieval, controlled access, regression testing, and production monitoring.&lt;/p&gt;

&lt;p&gt;At SotaTek, we treat these choices as part of a broader AI engineering process: start with the use case, establish a baseline, validate the architecture, and introduce model customization only when the evidence supports it.&lt;/p&gt;

&lt;p&gt;For a broader view of how these decisions fit into enterprise AI delivery, see our &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/ai-and-machine-learning/ai-development-process/" rel="noopener noreferrer"&gt;AI Development Process guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>rag</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>The AI Development Lifecycle: From PoC to Production Without Guesswork</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Mon, 12 Oct 2026 08:06:14 +0000</pubDate>
      <link>https://dev.to/devsotatek/the-ai-development-lifecycle-from-poc-to-production-without-guesswork-2jlj</link>
      <guid>https://dev.to/devsotatek/the-ai-development-lifecycle-from-poc-to-production-without-guesswork-2jlj</guid>
      <description>&lt;p&gt;Getting an AI model to work in a demo is relatively easy.&lt;/p&gt;

&lt;p&gt;Getting it to work reliably with real data, existing business systems, production traffic, security constraints, and a measurable budget is a different engineering problem.&lt;/p&gt;

&lt;p&gt;A prototype can look impressive while hiding problems that only appear later: poor data coverage, unstable outputs, slow integrations, unpredictable inference costs, or evaluation metrics that don't reflect actual business value.&lt;/p&gt;

&lt;p&gt;The solution isn't necessarily a better model. It's a development process that forces these issues to surface before they become expensive production failures.&lt;/p&gt;

&lt;p&gt;At SotaTek, we approach AI development as a systems engineering problem, where model selection is only one decision in a much larger lifecycle.&lt;/p&gt;

&lt;p&gt;Here's how I'd structure that lifecycle.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start With a Measurable Problem, Not a Model&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before choosing an LLM, training a classifier, or building an agent, define the problem the system needs to solve.&lt;/p&gt;

&lt;p&gt;Three things should be explicit:&lt;/p&gt;

&lt;p&gt;KPI: What outcome should improve?&lt;/p&gt;

&lt;p&gt;Baseline: How does the current process perform?&lt;/p&gt;

&lt;p&gt;Acceptance threshold: What result justifies moving forward?&lt;/p&gt;

&lt;p&gt;For example, an internal document assistant might have these initial targets:&lt;/p&gt;

&lt;p&gt;Metric&lt;/p&gt;

&lt;p&gt;Example target&lt;/p&gt;

&lt;p&gt;Answer quality&lt;/p&gt;

&lt;p&gt;At least 85% on a defined evaluation set&lt;/p&gt;

&lt;p&gt;P95 response latency&lt;/p&gt;

&lt;p&gt;Under 3 seconds&lt;/p&gt;

&lt;p&gt;Cost per request&lt;/p&gt;

&lt;p&gt;Within the approved budget&lt;/p&gt;

&lt;p&gt;Unsupported claims&lt;/p&gt;

&lt;p&gt;Below an agreed threshold&lt;/p&gt;

&lt;p&gt;These numbers are illustrative, not universal benchmarks. The correct thresholds depend on the use case and the consequences of failure.&lt;/p&gt;

&lt;p&gt;Define a kill criterion, too.&lt;/p&gt;

&lt;p&gt;If the prototype cannot outperform the existing workflow within the agreed cost and quality constraints, the team should be able to stop or change direction.&lt;/p&gt;

&lt;p&gt;This prevents a technically interesting experiment from becoming an indefinitely funded product.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Audit the Data Before Selecting the Architecture&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Data readiness can change the entire technical approach.&lt;/p&gt;

&lt;p&gt;A dataset may exist but still be unsuitable because it is incomplete, inconsistent, inaccessible, poorly labeled, or restricted by privacy requirements.&lt;/p&gt;

&lt;p&gt;Before implementation, answer:&lt;/p&gt;

&lt;p&gt;Where does the data come from?&lt;/p&gt;

&lt;p&gt;Who owns it, and who can access it?&lt;/p&gt;

&lt;p&gt;How frequently does it change?&lt;/p&gt;

&lt;p&gt;Does it require labeling, cleaning, or deduplication?&lt;/p&gt;

&lt;p&gt;Can it legally and securely be used for this purpose?&lt;/p&gt;

&lt;p&gt;How will its quality be measured?&lt;/p&gt;

&lt;p&gt;The last question matters because data quality is not just a preparation concern. It affects evaluation, production reliability, and ongoing maintenance.&lt;/p&gt;

&lt;p&gt;For example, a computer vision system with inconsistent annotations may learn the wrong visual patterns. A retrieval-augmented generation (RAG) system with stale documents may return technically relevant but outdated answers.&lt;/p&gt;

&lt;p&gt;Engineering decision: Don't commit to a model or architecture until you understand the data constraints well enough to estimate their impact.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose the Simplest Architecture That Meets the Requirements&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Not every AI use case needs an agent, fine-tuning, or a complex orchestration layer.&lt;/p&gt;

&lt;p&gt;Start by matching the problem to the simplest viable approach.&lt;/p&gt;

&lt;p&gt;Requirement&lt;/p&gt;

&lt;p&gt;Potential approach&lt;/p&gt;

&lt;p&gt;Classification or forecasting&lt;/p&gt;

&lt;p&gt;Traditional machine learning&lt;/p&gt;

&lt;p&gt;Text generation or summarization&lt;/p&gt;

&lt;p&gt;Foundation model API&lt;/p&gt;

&lt;p&gt;Answers grounded in private or changing documents&lt;/p&gt;

&lt;p&gt;RAG&lt;/p&gt;

&lt;p&gt;Specialized behavior not adequately achieved through prompting&lt;/p&gt;

&lt;p&gt;Fine-tuning, if justified&lt;/p&gt;

&lt;p&gt;Image or video inspection&lt;/p&gt;

&lt;p&gt;Computer vision&lt;/p&gt;

&lt;p&gt;Multi-step workflows requiring tools&lt;/p&gt;

&lt;p&gt;Agentic architecture, when necessary&lt;/p&gt;

&lt;p&gt;Then evaluate the candidates against the same constraints:&lt;/p&gt;

&lt;p&gt;Accuracy and failure tolerance&lt;/p&gt;

&lt;p&gt;Latency and throughput&lt;/p&gt;

&lt;p&gt;Cost per task&lt;/p&gt;

&lt;p&gt;Data privacy and deployment requirements&lt;/p&gt;

&lt;p&gt;Integration complexity&lt;/p&gt;

&lt;p&gt;Operational overhead&lt;/p&gt;

&lt;p&gt;Vendor dependency&lt;/p&gt;

&lt;p&gt;A more sophisticated architecture isn't automatically a better one.&lt;/p&gt;

&lt;p&gt;An agent that makes several model calls and invokes multiple tools may solve a task, but a deterministic workflow could achieve the same result with lower latency, lower cost, and more predictable behavior.&lt;/p&gt;

&lt;p&gt;The decision should be based on measured requirements, not architectural novelty.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make the PoC an Experiment, Not a Demo&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A proof of concept should answer a specific question:&lt;/p&gt;

&lt;p&gt;Does this approach work on representative data under realistic conditions?&lt;/p&gt;

&lt;p&gt;Build the smallest useful prototype, but define the evaluation process before tuning the system.&lt;/p&gt;

&lt;p&gt;For an LLM application, an evaluation dataset might contain:&lt;/p&gt;

&lt;p&gt;Representative user inputs&lt;/p&gt;

&lt;p&gt;Expected answers or grading criteria&lt;/p&gt;

&lt;p&gt;Relevant source documents&lt;/p&gt;

&lt;p&gt;Known failure cases&lt;/p&gt;

&lt;p&gt;Cases where the system should refuse or request clarification&lt;/p&gt;

&lt;p&gt;A simple evaluation harness could look like this:&lt;/p&gt;

&lt;p&gt;def evaluate_system(cases, system, grader):&lt;br&gt;
    results = []&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for case in cases:
    prediction = system.run(case["input"])

    score = grader(
        prediction=prediction,
        expected=case.get("expected"),
        context=case.get("context"),
    )

    results.append({
        "case_id": case["id"],
        "score": score,
        "latency_ms": prediction.latency_ms,
        "cost": prediction.cost,
    })

return results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is a simplified example; the grading logic and result schema depend on the application.&lt;/p&gt;

&lt;p&gt;The important part is consistency. You need to compare different prompts, models, retrieval strategies, or architectures against the same evaluation criteria.&lt;/p&gt;

&lt;p&gt;Track more than answer quality:&lt;/p&gt;

&lt;p&gt;Task success rate&lt;/p&gt;

&lt;p&gt;Retrieval quality, when applicable&lt;/p&gt;

&lt;p&gt;Hallucination or unsupported-claim rate&lt;/p&gt;

&lt;p&gt;Latency, including P95&lt;/p&gt;

&lt;p&gt;Cost per successful task&lt;/p&gt;

&lt;p&gt;Failure rate on edge cases&lt;/p&gt;

&lt;p&gt;Keep evaluation data separate from data used to tune prompts or train the model. Otherwise, the results may overstate how well the system generalizes.&lt;/p&gt;

&lt;p&gt;A successful PoC earns the right to move into production engineering. It does not prove that the system is production-ready.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Treat Production Engineering as a Separate Stage&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A working prototype usually proves that the core capability is possible. It rarely proves that the complete application is reliable.&lt;/p&gt;

&lt;p&gt;Production engineering adds the surrounding system:&lt;/p&gt;

&lt;p&gt;Client&lt;br&gt;
  |&lt;br&gt;
API Gateway&lt;br&gt;
  |&lt;br&gt;
Authentication / Authorization&lt;br&gt;
  |&lt;br&gt;
Application Logic&lt;br&gt;
  |&lt;br&gt;
AI Orchestration&lt;br&gt;
  |------------------|&lt;br&gt;
  |                  |&lt;br&gt;
Model Inference    Retrieval / Tools&lt;br&gt;
  |                  |&lt;br&gt;
  |             Enterprise Systems&lt;br&gt;
  |------------------|&lt;br&gt;
  |&lt;br&gt;
Output Validation&lt;br&gt;
  |&lt;br&gt;
Response&lt;br&gt;
  |&lt;br&gt;
Logs / Metrics / Traces&lt;/p&gt;

&lt;p&gt;The actual architecture will vary, but several concerns should be addressed before release.&lt;/p&gt;

&lt;p&gt;Integration: Can the system interact reliably with existing APIs, databases, CRMs, ERPs, or internal services?&lt;/p&gt;

&lt;p&gt;Security: Are permissions enforced outside the model? Can retrieved documents or tool calls expose data the current user should not access?&lt;/p&gt;

&lt;p&gt;Reliability: What happens when a model provider times out, a retrieval service becomes unavailable, or an upstream API returns an error?&lt;/p&gt;

&lt;p&gt;Consistency: If a tool call times out after a transaction succeeds, can a retry accidentally create a duplicate operation?&lt;/p&gt;

&lt;p&gt;For state-changing tools, use idempotency keys or equivalent safeguards where appropriate. Validate tool inputs and enforce authorization in the application layer.&lt;/p&gt;

&lt;p&gt;The model may propose an action. The application must decide whether that action is permitted.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deploy Against Real Constraints&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Deployment architecture should follow the workload and operating environment.&lt;/p&gt;

&lt;p&gt;Public cloud, private cloud, on-premise, edge, and hybrid deployments each introduce different trade-offs around latency, data residency, connectivity, scalability, and maintenance.&lt;/p&gt;

&lt;p&gt;For example, an AI inspection system in a factory with no internet access cannot depend on a remote inference API during normal operation.&lt;/p&gt;

&lt;p&gt;That constraint affects model selection, hardware requirements, update mechanisms, and monitoring from the beginning.&lt;/p&gt;

&lt;p&gt;The same principle applies to enterprise LLM applications: data sensitivity, network boundaries, and response-time requirements should influence the design before the deployment stage.&lt;/p&gt;

&lt;p&gt;A production release should also include:&lt;/p&gt;

&lt;p&gt;Staged rollout where feasible&lt;/p&gt;

&lt;p&gt;Health checks and readiness checks&lt;/p&gt;

&lt;p&gt;Security and load testing&lt;/p&gt;

&lt;p&gt;Versioned models and configuration&lt;/p&gt;

&lt;p&gt;Rollback procedures&lt;/p&gt;

&lt;p&gt;A defined human-review path for high-risk decisions&lt;/p&gt;

&lt;p&gt;Deployment is not complete simply because the endpoint responds successfully.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Monitor the System After Launch&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI systems can degrade even when the application code hasn't changed.&lt;/p&gt;

&lt;p&gt;Documents become outdated. User behavior shifts. Input distributions change. Model providers update their services. Traffic patterns alter latency and cost.&lt;/p&gt;

&lt;p&gt;A useful monitoring plan should cover several layers:&lt;/p&gt;

&lt;p&gt;Layer&lt;/p&gt;

&lt;p&gt;What to monitor&lt;/p&gt;

&lt;p&gt;Model&lt;/p&gt;

&lt;p&gt;Output quality, refusal behavior, task success&lt;/p&gt;

&lt;p&gt;Retrieval&lt;/p&gt;

&lt;p&gt;Recall, relevance, stale or missing documents&lt;/p&gt;

&lt;p&gt;Application&lt;/p&gt;

&lt;p&gt;Errors, timeouts, tool failures&lt;/p&gt;

&lt;p&gt;Performance&lt;/p&gt;

&lt;p&gt;P50/P95 latency, throughput&lt;/p&gt;

&lt;p&gt;Economics&lt;/p&gt;

&lt;p&gt;Cost per request and cost per successful task&lt;/p&gt;

&lt;p&gt;Data&lt;/p&gt;

&lt;p&gt;Distribution shifts, missing fields, drift&lt;/p&gt;

&lt;p&gt;User experience&lt;/p&gt;

&lt;p&gt;Feedback, abandonment, correction rates&lt;/p&gt;

&lt;p&gt;For systems using RAG, retrieval quality and answer quality should be monitored separately. A weak answer may result from poor retrieval rather than the model's generation capability.&lt;/p&gt;

&lt;p&gt;Similarly, a rise in cost per request may come from longer prompts, more retrieved context, repeated tool calls, or routing too many requests to a large model.&lt;/p&gt;

&lt;p&gt;Monitoring should help identify the source of degradation, not merely report that something went wrong.&lt;/p&gt;

&lt;p&gt;Every metric needs an owner, an acceptable range, and a response plan.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use Go/No-Go Gates to Control Risk&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The lifecycle becomes more useful when each stage produces evidence for the next decision.&lt;/p&gt;

&lt;p&gt;Stage&lt;/p&gt;

&lt;p&gt;Required evidence&lt;/p&gt;

&lt;p&gt;Decision&lt;/p&gt;

&lt;p&gt;Discovery&lt;/p&gt;

&lt;p&gt;KPI, baseline, acceptance criteria&lt;/p&gt;

&lt;p&gt;Is the problem worth solving?&lt;/p&gt;

&lt;p&gt;Data readiness&lt;/p&gt;

&lt;p&gt;Data audit and access plan&lt;/p&gt;

&lt;p&gt;Can the data support the use case?&lt;/p&gt;

&lt;p&gt;Architecture&lt;/p&gt;

&lt;p&gt;Evaluated approach and risk assessment&lt;/p&gt;

&lt;p&gt;Does the design fit the constraints?&lt;/p&gt;

&lt;p&gt;PoC&lt;/p&gt;

&lt;p&gt;Results against the evaluation set&lt;/p&gt;

&lt;p&gt;Does it beat the baseline?&lt;/p&gt;

&lt;p&gt;Production engineering&lt;/p&gt;

&lt;p&gt;Integration, security, and load-test results&lt;/p&gt;

&lt;p&gt;Is the system ready to release?&lt;/p&gt;

&lt;p&gt;Deployment&lt;/p&gt;

&lt;p&gt;Rollback plan and operational checks&lt;/p&gt;

&lt;p&gt;Can the release be operated safely?&lt;/p&gt;

&lt;p&gt;Monitoring&lt;/p&gt;

&lt;p&gt;Quality, latency, cost, and drift metrics&lt;/p&gt;

&lt;p&gt;Is the system still meeting its targets?&lt;/p&gt;

&lt;p&gt;The point is not to create more meetings or paperwork. It's to make technical and business decisions explicit while changing direction is still relatively inexpensive.&lt;/p&gt;

&lt;p&gt;The Real Deliverable Is a Reliable System&lt;/p&gt;

&lt;p&gt;The AI development lifecycle is not simply a sequence of model-building tasks.&lt;/p&gt;

&lt;p&gt;It's a way to manage uncertainty across data, architecture, evaluation, integration, security, deployment, and ongoing operations.&lt;/p&gt;

&lt;p&gt;A useful mental model is:&lt;/p&gt;

&lt;p&gt;Production AI = Model + Data + Application + Integration + Evaluation + Security + Operations&lt;/p&gt;

&lt;p&gt;Leaving out any of these layers can turn a promising prototype into a system that's expensive to maintain, difficult to trust, or impossible to scale reliably.&lt;/p&gt;

&lt;p&gt;At SotaTek, this systems-level perspective guides the transition from AI feasibility and PoC validation to production engineering, integration, and MLOps.&lt;/p&gt;

&lt;p&gt;The objective isn't just to make an AI model work. It's to build a system that continues to deliver measurable value after launch.&lt;/p&gt;

&lt;p&gt;For a broader breakdown of the seven stages, their deliverables, and the go/no-go criteria that keep projects on track, see our &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/ai-and-machine-learning/ai-development-process/" rel="noopener noreferrer"&gt;AI Development Process guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>machinelearning</category>
      <category>devops</category>
    </item>
    <item>
      <title>Your AI System Is More Than the Model: What Production AI Architecture Actually Looks Like</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Tue, 06 Oct 2026 10:50:10 +0000</pubDate>
      <link>https://dev.to/devsotatek/your-ai-system-is-more-than-the-model-what-production-ai-architecture-actually-looks-like-4lk5</link>
      <guid>https://dev.to/devsotatek/your-ai-system-is-more-than-the-model-what-production-ai-architecture-actually-looks-like-4lk5</guid>
      <description>&lt;p&gt;A production AI system is rarely just:&lt;br&gt;
User → API → LLM → Response&lt;/p&gt;

&lt;p&gt;That architecture works well in a demo.&lt;br&gt;
Production is different.&lt;br&gt;
Once an AI system has to work with private data, enterprise systems, user permissions, unreliable model outputs, latency constraints, cost limits, and changing requirements, the model becomes only one component of a much larger system.&lt;br&gt;
At &lt;strong&gt;SotaTek&lt;/strong&gt;, we approach AI development from this broader systems perspective: the model is only one layer of the product, while data, application logic, integrations, security, evaluation, infrastructure, and observability determine whether that capability can actually work in production.&lt;br&gt;
A more realistic architecture looks like this:&lt;br&gt;
User / Business Workflow&lt;br&gt;
          ↓&lt;br&gt;
     Application&lt;br&gt;
          ↓&lt;br&gt;
 Authentication / Authorization&lt;br&gt;
          ↓&lt;br&gt;
   AI Orchestration Layer&lt;br&gt;
      ↙          ↘&lt;br&gt;
 Retrieval       Tools&lt;br&gt;
    ↓              ↓&lt;br&gt;
Knowledge       Enterprise&lt;br&gt;
Sources          Systems&lt;br&gt;
      \          /&lt;br&gt;
       \        /&lt;br&gt;
         Model&lt;br&gt;
          ↓&lt;br&gt;
 Guardrails / Validation&lt;br&gt;
          ↓&lt;br&gt;
      Response&lt;br&gt;
          ↓&lt;br&gt;
 Logging / Evaluation&lt;br&gt;
          ↓&lt;br&gt;
 Monitoring / Feedback&lt;/p&gt;

&lt;p&gt;The interesting engineering problems are usually somewhere between those boxes.&lt;br&gt;
**Start With the Workflow, Not the Model&lt;br&gt;
**One of the easiest mistakes in AI development is starting with:&lt;br&gt;
Which model should we use?&lt;/p&gt;

&lt;p&gt;A better starting point is:&lt;br&gt;
What changes in the business workflow if the AI system works exactly as intended?&lt;/p&gt;

&lt;p&gt;Consider an internal support assistant.&lt;br&gt;
A naive implementation might look like:&lt;br&gt;
response = llm.generate(user_question)&lt;/p&gt;

&lt;p&gt;But the real requirement may be:&lt;br&gt;
User&lt;br&gt;
 ↓&lt;br&gt;
Ask question&lt;br&gt;
 ↓&lt;br&gt;
Check permissions&lt;br&gt;
 ↓&lt;br&gt;
Find relevant company information&lt;br&gt;
 ↓&lt;br&gt;
Generate answer&lt;br&gt;
 ↓&lt;br&gt;
Validate response&lt;br&gt;
 ↓&lt;br&gt;
Log interaction&lt;br&gt;
 ↓&lt;br&gt;
Return answer&lt;/p&gt;

&lt;p&gt;The model is only responsible for part of that workflow.&lt;br&gt;
This distinction becomes important as soon as the application has real users and real data.&lt;br&gt;
**The Application Layer Owns the Business Logic&lt;br&gt;
**A common anti-pattern is putting too much responsibility inside the prompt.&lt;br&gt;
For example:&lt;br&gt;
SYSTEM_PROMPT = """You are an enterprise assistant.Only access information the user is allowed to see.Never modify financial records.Never approve a transaction.Always follow company policy."""&lt;/p&gt;

&lt;p&gt;That sounds reasonable, but prompts are not an authorization system.&lt;br&gt;
Permissions should be enforced by application code.&lt;br&gt;
async def get_customer_data(user, customer_id):    if not user.can_access("customer", customer_id):        raise PermissionError("Access denied")    return await customer_repository.get(customer_id)&lt;/p&gt;

&lt;p&gt;The LLM can decide what information it needs.&lt;br&gt;
The application decides whether it is allowed to access that information.&lt;br&gt;
That boundary matters.&lt;br&gt;
                LLM&lt;br&gt;
                 │&lt;br&gt;
          "I need customer data"&lt;br&gt;
                 ↓&lt;br&gt;
          Tool / API Layer&lt;br&gt;
                 ↓&lt;br&gt;
       Authorization Check&lt;br&gt;
                 ↓&lt;br&gt;
          Enterprise API&lt;/p&gt;

&lt;p&gt;This also makes the system easier to audit and test.&lt;br&gt;
&lt;strong&gt;RAG Is an Application Architecture, Not Just a Vector Database&lt;/strong&gt;&lt;br&gt;
For enterprise knowledge systems, retrieval-augmented generation is useful when information changes frequently or is private to the organization.&lt;br&gt;
A simplified pipeline looks like:&lt;br&gt;
Document&lt;br&gt;
   ↓&lt;br&gt;
Chunking&lt;br&gt;
   ↓&lt;br&gt;
Embedding&lt;br&gt;
   ↓&lt;br&gt;
Vector Database&lt;br&gt;
   ↓&lt;br&gt;
User Query&lt;br&gt;
   ↓&lt;br&gt;
Query Embedding&lt;br&gt;
   ↓&lt;br&gt;
Similarity Search&lt;br&gt;
   ↓&lt;br&gt;
Retrieved Context&lt;br&gt;
   ↓&lt;br&gt;
LLM&lt;br&gt;
   ↓&lt;br&gt;
Answer&lt;/p&gt;

&lt;p&gt;A minimal implementation might look like:&lt;br&gt;
async def answer_question(question: str):    query_vector = await embed(question)    documents = await vector_db.search(        vector=query_vector,        top_k=5    )    context = "\n\n".join(        document.content        for document in documents    )    return await llm.generate(        system=SYSTEM_PROMPT,        user=question,        context=context    )&lt;/p&gt;

&lt;p&gt;But this is still missing an important part:&lt;br&gt;
&lt;strong&gt;authorization-aware retrieval&lt;/strong&gt;.&lt;br&gt;
Suppose the vector database contains:&lt;br&gt;
Public documents&lt;br&gt;
Internal documents&lt;br&gt;
Finance documents&lt;br&gt;
HR documents&lt;br&gt;
Executive documents&lt;/p&gt;

&lt;p&gt;A semantic search returning the most relevant document does not mean the user should see it.&lt;br&gt;
The retrieval layer may therefore need metadata filtering:&lt;br&gt;
documents = await vector_db.search(    vector=query_vector,    top_k=5,    filters={        "tenant_id": user.tenant_id,        "allowed_roles": {            "$in": user.roles        }    })&lt;/p&gt;

&lt;p&gt;The retrieval system is now part of the security boundary.&lt;br&gt;
&lt;strong&gt;AI Agents Add a Different Class of Engineering Problems&lt;/strong&gt;&lt;br&gt;
A chatbot mostly generates responses.&lt;br&gt;
An agent can take actions.&lt;br&gt;
For example:&lt;br&gt;
User&lt;br&gt;
 ↓&lt;br&gt;
Agent&lt;br&gt;
 ├── search_customer()&lt;br&gt;
 ├── get_invoice()&lt;br&gt;
 ├── create_ticket()&lt;br&gt;
 ├── update_order()&lt;br&gt;
 └── escalate_to_human()&lt;/p&gt;

&lt;p&gt;A simplified tool-calling loop might look like:&lt;br&gt;
async def run_agent(user, request):    response = await llm.generate(        messages=[request],        tools=AVAILABLE_TOOLS    )    if not response.tool_calls:        return response.text    for call in response.tool_calls:        tool = get_tool(call.name)        if not user.can_execute(tool.permission):            raise PermissionError(                f"Not allowed: {call.name}"            )        result = await tool.execute(            **call.arguments        )        await audit_log.write(            user=user.id,            tool=call.name,            arguments=call.arguments        )    return await llm.generate(        messages=[request, result],        tools=AVAILABLE_TOOLS    )&lt;/p&gt;

&lt;p&gt;Now the architecture needs more than an LLM.&lt;br&gt;
It needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;permissions&lt;/li&gt;
&lt;li&gt;tool contracts&lt;/li&gt;
&lt;li&gt;state management&lt;/li&gt;
&lt;li&gt;audit logs&lt;/li&gt;
&lt;li&gt;approval rules&lt;/li&gt;
&lt;li&gt;retries&lt;/li&gt;
&lt;li&gt;idempotency&lt;/li&gt;
&lt;li&gt;human escalation&lt;/li&gt;
&lt;li&gt;failure handling
This is where an AI agent starts looking much more like a distributed application than a chatbot.
&lt;strong&gt;Tool Calls Need Idempotency&lt;/strong&gt;
Consider an agent that can create an order.
The model calls:
{
"tool": "create_order",
"arguments": {
"customer_id": "123",
"amount": 500
}
}&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What happens if:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The API succeeds.&lt;/li&gt;
&lt;li&gt;The network times out.&lt;/li&gt;
&lt;li&gt;The model retries the tool call.
Without idempotency, you might create two orders.
A safer API design is:
POST /orders
Idempotency-Key: agent-run-8f32...&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The backend can then ensure that repeated requests with the same key do not create duplicate side effects.&lt;br&gt;
This is a good example of why AI engineering overlaps heavily with conventional backend engineering.&lt;br&gt;
The model can decide what it wants to do.&lt;br&gt;
The backend still has to guarantee what actually happens.&lt;br&gt;
&lt;strong&gt;Model Selection Is a System Trade-off&lt;/strong&gt;&lt;br&gt;
There is rarely a universally correct model.&lt;br&gt;
The architecture may use:&lt;br&gt;
                    AI Request&lt;br&gt;
                        ↓&lt;br&gt;
                 Routing Layer&lt;br&gt;
                  ↙    ↓    ↘&lt;br&gt;
               Small  Large  Vision&lt;br&gt;
              Model   Model   Model&lt;/p&gt;

&lt;p&gt;A simple routing strategy could look like:&lt;br&gt;
def select_model(task):    if task.type == "classification":        return SMALL_MODEL    if task.requires_reasoning:        return LARGE_MODEL    if task.requires_vision:        return VISION_MODEL    return DEFAULT_MODEL&lt;/p&gt;

&lt;p&gt;The decision should consider more than benchmark quality.&lt;br&gt;
Typical variables include:&lt;br&gt;
Accuracy&lt;br&gt;
Latency&lt;br&gt;
Cost&lt;br&gt;
Context length&lt;br&gt;
Privacy&lt;br&gt;
Throughput&lt;br&gt;
Availability&lt;br&gt;
Deployment model&lt;br&gt;
Vendor dependency&lt;br&gt;
Maintenance complexity&lt;/p&gt;

&lt;p&gt;For some workloads, a smaller model with predictable latency can be more practical than a larger model that produces slightly better answers but costs significantly more.&lt;br&gt;
For others, additional reasoning capability may justify the cost.&lt;br&gt;
The architecture should make this trade-off measurable rather than ideological.&lt;br&gt;
&lt;strong&gt;Evaluation Is Part of the Product&lt;/strong&gt;&lt;br&gt;
One of the biggest differences between a demo and a production AI system is evaluation.&lt;br&gt;
Traditional software often has deterministic tests:&lt;br&gt;
assert calculate_total(100, 10) == 110&lt;/p&gt;

&lt;p&gt;AI systems are more complicated.&lt;br&gt;
A useful evaluation pipeline might look like:&lt;br&gt;
Test Dataset&lt;br&gt;
     ↓&lt;br&gt;
     Model&lt;br&gt;
     ↓&lt;br&gt;
Generated Output&lt;br&gt;
     ↓&lt;br&gt;
Evaluation&lt;br&gt;
 ┌───┼───────────┐&lt;br&gt;
 ↓   ↓           ↓&lt;br&gt;
Quality  Grounding  Latency&lt;br&gt;
 ↓       ↓           ↓&lt;br&gt;
     Evaluation Report&lt;/p&gt;

&lt;p&gt;For a RAG system, you might track:&lt;br&gt;
metrics = {    "retrieval_precision": ...,    "answer_groundedness": ...,    "answer_relevance": ...,    "hallucination_rate": ...,    "latency_p95": ...,    "cost_per_request": ...}&lt;/p&gt;

&lt;p&gt;The important part is defining what “good enough” means before production.&lt;br&gt;
Otherwise, teams can discover that the system technically works but nobody can agree whether it works well.&lt;br&gt;
&lt;strong&gt;Observability Needs to Cover More Than API Errors&lt;/strong&gt;&lt;br&gt;
A normal backend might monitor:&lt;br&gt;
HTTP 5xx&lt;br&gt;
CPU&lt;br&gt;
Memory&lt;br&gt;
Latency&lt;br&gt;
Request volume&lt;/p&gt;

&lt;p&gt;An AI system needs additional signals.&lt;br&gt;
For example:&lt;br&gt;
Request&lt;br&gt;
  ↓&lt;br&gt;
Prompt&lt;br&gt;
  ↓&lt;br&gt;
Retrieval&lt;br&gt;
  ↓&lt;br&gt;
Model&lt;br&gt;
  ↓&lt;br&gt;
Tool Calls&lt;br&gt;
  ↓&lt;br&gt;
Response&lt;/p&gt;

&lt;p&gt;Useful telemetry can include:&lt;br&gt;
Model latency&lt;br&gt;
Time to first token&lt;br&gt;
Total tokens&lt;br&gt;
Input tokens&lt;br&gt;
Output tokens&lt;br&gt;
Retrieval latency&lt;br&gt;
Number of retrieved documents&lt;br&gt;
Tool execution time&lt;br&gt;
Tool failures&lt;br&gt;
Guardrail violations&lt;br&gt;
User feedback&lt;br&gt;
Cost per request&lt;/p&gt;

&lt;p&gt;A production trace might therefore look like:&lt;br&gt;
request_id: 7f82...&lt;/p&gt;

&lt;p&gt;API latency:       1.2s&lt;br&gt;
retrieval latency: 180ms&lt;br&gt;
LLM latency:       820ms&lt;br&gt;
tokens:            2,431&lt;br&gt;
tools called:      2&lt;br&gt;
retrieved docs:    5&lt;br&gt;
estimated cost:    $0.014&lt;/p&gt;

&lt;p&gt;Now you can investigate why an AI request became slow or expensive instead of treating the model as a black box.&lt;br&gt;
&lt;strong&gt;Guardrails Should Sit Around the Model&lt;/strong&gt;&lt;br&gt;
Guardrails are often described as a single safety layer.&lt;br&gt;
In production, they can exist at several points:&lt;br&gt;
User Input&lt;br&gt;
    ↓&lt;br&gt;
Input Validation&lt;br&gt;
    ↓&lt;br&gt;
Authorization&lt;br&gt;
    ↓&lt;br&gt;
Retrieval&lt;br&gt;
    ↓&lt;br&gt;
LLM&lt;br&gt;
    ↓&lt;br&gt;
Output Validation&lt;br&gt;
    ↓&lt;br&gt;
Tool Authorization&lt;br&gt;
    ↓&lt;br&gt;
Final Response&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
if contains_sensitive_request(user_input):    return "This request cannot be processed."response = await llm.generate(...)if not passes_output_policy(response):    return "The generated response requires review."&lt;/p&gt;

&lt;p&gt;For systems that can execute actions, the tool layer should also enforce permissions independently of the model.&lt;br&gt;
The model should never be the final authority for security-sensitive operations.&lt;br&gt;
&lt;strong&gt;Deployment Changes the Architecture&lt;/strong&gt;&lt;br&gt;
The same AI application can require very different infrastructure depending on the environment.&lt;br&gt;
                    AI Application&lt;br&gt;
                         ↓&lt;br&gt;
              ┌──────────┼──────────┐&lt;br&gt;
              ↓          ↓          ↓&lt;br&gt;
            Cloud      Private     Edge&lt;br&gt;
              ↓          ↓          ↓&lt;br&gt;
          Managed      On-prem    Local&lt;br&gt;
           APIs        Models     Models&lt;/p&gt;

&lt;p&gt;The choice depends on factors such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;latency&lt;/li&gt;
&lt;li&gt;data sensitivity&lt;/li&gt;
&lt;li&gt;connectivity&lt;/li&gt;
&lt;li&gt;GPU availability&lt;/li&gt;
&lt;li&gt;operational requirements&lt;/li&gt;
&lt;li&gt;infrastructure cost&lt;/li&gt;
&lt;li&gt;compliance requirements&lt;/li&gt;
&lt;li&gt;expected traffic
For example, an industrial computer vision system operating inside a factory may have very different requirements from a cloud-based enterprise chatbot.
The model is only one part of the deployment decision.
&lt;strong&gt;The Production Architecture&lt;/strong&gt;
Putting the pieces together:
                    ┌──────────────────┐
                    │      Users       │
                    └────────┬─────────┘
                             ↓
                    ┌──────────────────┐
                    │  Application/API │
                    └────────┬─────────┘
                             ↓
                ┌────────────────────────┐
                │ Authentication / AuthZ │
                └────────────┬───────────┘
                             ↓
                ┌────────────────────────┐
                │   AI Orchestration     │
                └───────┬────────┬────────┘
                        ↓        ↓
                   Retrieval   Tools
                       ↓        ↓
                 Knowledge   Enterprise
                   Base       Systems
                       \        /
                        \      /
                         ↓    ↓
                     ┌───────────┐
                     │   Model   │
                     └─────┬─────┘
                           ↓
                 ┌──────────────────┐
                 │ Guardrails / Eval│
                 └────────┬─────────┘
                          ↓
                     Final Output
                          ↓
              ┌────────────────────────┐
              │ Logging / Monitoring   │
              │ Cost / Quality / SLOs  │
              └────────────────────────┘&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why “adding an LLM” and “building an AI system” are two very different engineering tasks.&lt;br&gt;
If you want the broader view of how these components fit into an AI development engagement, from use-case discovery and readiness assessment through PoC, production engineering, deployment, and ongoing optimization, see our AI Development Company guide.&lt;br&gt;
&lt;strong&gt;A Practical AI Development Lifecycle&lt;/strong&gt;&lt;br&gt;
A production project can be reduced to a fairly simple sequence:&lt;br&gt;
Discovery&lt;br&gt;
    ↓&lt;br&gt;
Feasibility&lt;br&gt;
    ↓&lt;br&gt;
Data / AI Readiness&lt;br&gt;
    ↓&lt;br&gt;
Architecture&lt;br&gt;
    ↓&lt;br&gt;
PoC&lt;br&gt;
    ↓&lt;br&gt;
Evaluation&lt;br&gt;
    ↓&lt;br&gt;
Production Engineering&lt;br&gt;
    ↓&lt;br&gt;
Integration&lt;br&gt;
    ↓&lt;br&gt;
Deployment&lt;br&gt;
    ↓&lt;br&gt;
Monitoring&lt;br&gt;
    ↓&lt;br&gt;
Continuous Optimization&lt;/p&gt;

&lt;p&gt;The important part is not to jump directly from:&lt;br&gt;
Idea → Production&lt;/p&gt;

&lt;p&gt;without validating the intermediate assumptions.&lt;br&gt;
A PoC should answer questions such as:&lt;br&gt;
Can the data support the use case?&lt;/p&gt;

&lt;p&gt;Is the model accurate enough?&lt;/p&gt;

&lt;p&gt;Is retrieval good enough?&lt;/p&gt;

&lt;p&gt;Is latency acceptable?&lt;/p&gt;

&lt;p&gt;Is the cost acceptable?&lt;/p&gt;

&lt;p&gt;Can the system integrate with existing workflows?&lt;/p&gt;

&lt;p&gt;What security risks exist?&lt;/p&gt;

&lt;p&gt;What happens when the model is wrong?&lt;/p&gt;

&lt;p&gt;If those questions cannot be answered, scaling the infrastructure will not solve the underlying problem.&lt;br&gt;
For a deeper look at how these components come together across the AI development lifecycle, from use-case discovery and PoC validation to production deployment and optimization, we’ve covered the broader process in our &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/ai-and-machine-learning/ai-development-company/" rel="noopener noreferrer"&gt;AI Development Company guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Engineering Boundary That Matters Most&lt;/strong&gt;&lt;br&gt;
The most useful mental model is probably this:&lt;br&gt;
              AI Model&lt;br&gt;
                 │&lt;br&gt;
        ┌────────┴────────┐&lt;br&gt;
        │                 │&lt;br&gt;
    What to generate   What to do&lt;br&gt;
        │                 │&lt;br&gt;
        ↓                 ↓&lt;br&gt;
   Application        Tool Layer&lt;br&gt;
      Logic          Permissions&lt;br&gt;
      RAG             Validation&lt;br&gt;
      Context         Audit Logs&lt;br&gt;
      Evaluation      Transactions&lt;br&gt;
        │                 │&lt;br&gt;
        └────────┬────────┘&lt;br&gt;
                 ↓&lt;br&gt;
             Production&lt;/p&gt;

&lt;p&gt;The model provides intelligence.&lt;br&gt;
The surrounding software provides reliability.&lt;br&gt;
That distinction becomes increasingly important as AI systems move from demos into business-critical workflows.&lt;br&gt;
&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;br&gt;
The hardest part of AI development is often not getting a model to produce an impressive output.&lt;br&gt;
It is turning that capability into a system that can operate reliably with real data, real users, real permissions, real infrastructure, and real business constraints.&lt;br&gt;
That means treating AI development as a systems engineering problem:&lt;br&gt;
Model&lt;br&gt;
+&lt;br&gt;
Data&lt;br&gt;
+&lt;br&gt;
Application&lt;br&gt;
+&lt;br&gt;
Integration&lt;br&gt;
+&lt;br&gt;
Security&lt;br&gt;
+&lt;br&gt;
Evaluation&lt;br&gt;
+&lt;br&gt;
Infrastructure&lt;br&gt;
+&lt;/p&gt;

&lt;h1&gt;
  
  
  Observability
&lt;/h1&gt;

&lt;p&gt;Production AI System&lt;/p&gt;

&lt;p&gt;At SotaTek, this broader system perspective is particularly important when moving from PoC validation into production AI applications, enterprise integrations, and AI operations.&lt;br&gt;
The interesting question is no longer:&lt;br&gt;
Which AI model should we use?&lt;/p&gt;

&lt;p&gt;It is:&lt;br&gt;
What system needs to exist around the model for this capability to work reliably in production?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>softwareengineering</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>What Actually Happens When You Mint an NFT?</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Mon, 28 Sep 2026 07:51:12 +0000</pubDate>
      <link>https://dev.to/devsotatek/what-actually-happens-when-you-mint-an-nft-28k5</link>
      <guid>https://dev.to/devsotatek/what-actually-happens-when-you-mint-an-nft-28k5</guid>
      <description>&lt;p&gt;“Mint an NFT” sounds like a single operation.&lt;/p&gt;

&lt;p&gt;From a user's perspective, it often looks like this:&lt;/p&gt;

&lt;p&gt;Connect Wallet&lt;br&gt;
      ↓&lt;br&gt;
Click Mint&lt;br&gt;
      ↓&lt;br&gt;
Confirm Transaction&lt;br&gt;
      ↓&lt;br&gt;
NFT Appears in Wallet&lt;/p&gt;

&lt;p&gt;Underneath that button, several systems have to agree on the same state.&lt;/p&gt;

&lt;p&gt;The image is not necessarily stored on the blockchain. The metadata may live on IPFS or another storage layer. The smart contract owns the token ID and ownership state. The wallet signs the transaction. An indexer eventually makes the new asset visible to the application.&lt;/p&gt;

&lt;p&gt;A simplified architecture looks like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                NFT Application
                      │
                      ▼
                 Mint UI
                      │
                      ▼
                   Wallet
                      │
                signed tx
                      ▼
              Smart Contract
                /          \
               /            \
              ▼              ▼
         Token State     Metadata URI
              │              │
              ▼              ▼
         Blockchain     IPFS / Storage
              │
              ▼
            Events
              │
              ▼
           Indexer
              │
              ▼
        Marketplace / UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The interesting part is that the NFT itself is only one piece of the system.&lt;/p&gt;

&lt;p&gt;Start With What the NFT Actually Represents&lt;/p&gt;

&lt;p&gt;Before writing a contract, you need to define the asset.&lt;/p&gt;

&lt;p&gt;An NFT could represent:&lt;/p&gt;

&lt;p&gt;A unique collectible&lt;br&gt;
A game character&lt;br&gt;
A ticket&lt;br&gt;
A membership credential&lt;br&gt;
A digital certificate&lt;br&gt;
A real-world asset&lt;br&gt;
A composable digital asset&lt;/p&gt;

&lt;p&gt;That decision affects the contract design, metadata structure, token standard, and transfer model.&lt;/p&gt;

&lt;p&gt;For example, a collection of unique digital artworks has a different structure from a game inventory containing thousands of identical consumable items.&lt;/p&gt;

&lt;p&gt;This is why token standard selection should happen before implementation.&lt;/p&gt;

&lt;p&gt;ERC-721 vs ERC-1155&lt;/p&gt;

&lt;p&gt;For a simple one-of-a-kind asset, ERC-721 is usually the easier mental model.&lt;/p&gt;

&lt;p&gt;Each token has its own ID:&lt;/p&gt;

&lt;p&gt;Collection&lt;br&gt;
│&lt;br&gt;
├── Token #1&lt;br&gt;
├── Token #2&lt;br&gt;
├── Token #3&lt;br&gt;
└── Token #4&lt;/p&gt;

&lt;p&gt;ERC-1155 takes a different approach.&lt;/p&gt;

&lt;p&gt;A single contract can represent multiple token types and quantities:&lt;/p&gt;

&lt;p&gt;Contract&lt;br&gt;
│&lt;br&gt;
├── Item #1001 → 5,000 copies&lt;br&gt;
├── Item #1002 → 2,000 copies&lt;br&gt;
└── Item #1003 → 1 copy&lt;/p&gt;

&lt;p&gt;This makes ERC-1155 useful for applications such as gaming, where an inventory may contain both unique assets and high-volume items.&lt;/p&gt;

&lt;p&gt;The choice is therefore not about which standard is “better”.&lt;/p&gt;

&lt;p&gt;It depends on the asset model.&lt;/p&gt;

&lt;p&gt;A useful rule is:&lt;/p&gt;

&lt;p&gt;Unique asset&lt;br&gt;
    ↓&lt;br&gt;
ERC-721&lt;/p&gt;

&lt;p&gt;Multiple / batch-oriented assets&lt;br&gt;
    ↓&lt;br&gt;
ERC-1155&lt;/p&gt;

&lt;p&gt;NFTs that own other assets&lt;br&gt;
    ↓&lt;br&gt;
Composable design such as ERC-998&lt;/p&gt;

&lt;p&gt;The source article also identifies ERC-721, ERC-1155, ERC-998 and TRC-721 as common options, with the choice depending on asset structure, blockchain and marketplace compatibility.&lt;/p&gt;

&lt;p&gt;The Image Is Not the NFT&lt;/p&gt;

&lt;p&gt;This is one of the most common misconceptions.&lt;/p&gt;

&lt;p&gt;Suppose an NFT displays:&lt;/p&gt;

&lt;p&gt;Golden Sword&lt;br&gt;
Attack: 95&lt;br&gt;
Rarity: Legendary&lt;br&gt;
Image: sword.png&lt;/p&gt;

&lt;p&gt;Those properties are generally represented through metadata.&lt;/p&gt;

&lt;p&gt;A simplified metadata document could look like:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "name": "Golden Sword",&lt;br&gt;
  "description": "Legendary in-game weapon",&lt;br&gt;
  "image": "ipfs://...",&lt;br&gt;
  "attributes": [&lt;br&gt;
    {&lt;br&gt;
      "trait_type": "Rarity",&lt;br&gt;
      "value": "Legendary"&lt;br&gt;
    },&lt;br&gt;
    {&lt;br&gt;
      "trait_type": "Attack",&lt;br&gt;
      "value": 95&lt;br&gt;
    }&lt;br&gt;
  ]&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;The smart contract does not necessarily store this entire JSON object.&lt;/p&gt;

&lt;p&gt;Instead, the token commonly exposes a metadata URI:&lt;/p&gt;

&lt;p&gt;NFT #1842&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
tokenURI(1842)&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
ipfs://metadata...&lt;/p&gt;

&lt;p&gt;This keeps large assets and metadata outside the blockchain while allowing the token to reference them.&lt;/p&gt;

&lt;p&gt;The source architecture similarly separates metadata from the token itself, with metadata commonly stored off-chain using systems such as IPFS or Arweave and referenced from the token.&lt;/p&gt;

&lt;p&gt;Why Put Metadata Off-Chain?&lt;/p&gt;

&lt;p&gt;Storing an image directly on-chain is possible, but it can be expensive and impractical for many collections.&lt;/p&gt;

&lt;p&gt;A common architecture is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Blockchain
                    │
                    │ tokenURI
                    ▼
              Metadata URI
                    │
                    ▼
            Decentralized Storage
                    │
          ┌─────────┴─────────┐
          ▼                   ▼
       Metadata             Image
          │                   │
          └─────────┬─────────┘
                    ▼
               NFT Interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The important distinction is:&lt;/p&gt;

&lt;p&gt;The blockchain proves token ownership.&lt;/p&gt;

&lt;p&gt;It does not automatically guarantee that every external asset referenced by the token will remain available forever.&lt;/p&gt;

&lt;p&gt;That is why storage architecture is part of NFT engineering, not just a frontend concern.&lt;/p&gt;

&lt;p&gt;The Smart Contract Defines Ownership&lt;/p&gt;

&lt;p&gt;A minimal ERC-721 contract might look like:&lt;/p&gt;

&lt;p&gt;contract GameAsset is ERC721 {&lt;br&gt;
    uint256 private nextTokenId;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function mint(address to)
    external
    returns (uint256)
{
    uint256 tokenId = nextTokenId++;
    _safeMint(to, tokenId);

    return tokenId;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;The important operation here is not the image or metadata.&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;p&gt;_mint(to, tokenId)&lt;/p&gt;

&lt;p&gt;The blockchain now records that:&lt;/p&gt;

&lt;p&gt;Token #1842&lt;br&gt;
        ↓&lt;br&gt;
Owner = 0xA91...&lt;/p&gt;

&lt;p&gt;That ownership state can then be independently verified.&lt;/p&gt;

&lt;p&gt;A marketplace does not need to trust your database to determine who owns the NFT.&lt;/p&gt;

&lt;p&gt;It can query the contract or indexed blockchain data.&lt;/p&gt;

&lt;p&gt;What Actually Happens During Minting?&lt;/p&gt;

&lt;p&gt;Let's follow a mint transaction.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The application prepares the transaction&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The frontend knows:&lt;/p&gt;

&lt;p&gt;Contract address&lt;br&gt;
Token ID / mint parameters&lt;br&gt;
Recipient&lt;br&gt;
Metadata configuration&lt;/p&gt;

&lt;p&gt;It prepares a contract call.&lt;/p&gt;

&lt;p&gt;mint(recipient)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The wallet signs it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The user confirms the transaction through their wallet.&lt;/p&gt;

&lt;p&gt;The wallet signs the transaction with the user's private key.&lt;/p&gt;

&lt;p&gt;The application does not receive the private key.&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Wallet&lt;br&gt;
 │&lt;br&gt;
 │ signed transaction&lt;br&gt;
 ▼&lt;br&gt;
Blockchain Network&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The transaction reaches the smart contract&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The blockchain executes the contract.&lt;/p&gt;

&lt;p&gt;The contract checks whatever rules have been implemented:&lt;/p&gt;

&lt;p&gt;Can this caller mint?&lt;br&gt;
        │&lt;br&gt;
        ├── No → revert&lt;br&gt;
        │&lt;br&gt;
        └── Yes&lt;br&gt;
             ↓&lt;br&gt;
        Create token&lt;br&gt;
             ↓&lt;br&gt;
        Assign owner&lt;br&gt;
             ↓&lt;br&gt;
        Emit event&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ownership is written to blockchain state&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After successful execution:&lt;/p&gt;

&lt;p&gt;Token #1842&lt;br&gt;
    │&lt;br&gt;
    ├── Owner → 0xA91...&lt;br&gt;
    └── Metadata → ipfs://...&lt;/p&gt;

&lt;p&gt;The transaction receipt and event logs provide evidence of the state transition.&lt;/p&gt;

&lt;p&gt;Minting Is Also a Security Boundary&lt;/p&gt;

&lt;p&gt;The simple contract above has a major problem:&lt;/p&gt;

&lt;p&gt;Who is allowed to call mint()?&lt;/p&gt;

&lt;p&gt;If anyone can call it, anyone can create unlimited tokens.&lt;/p&gt;

&lt;p&gt;Production contracts therefore need access control.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;function mint(address to)&lt;br&gt;
    external&lt;br&gt;
    onlyRole(MINTER_ROLE)&lt;br&gt;
{&lt;br&gt;
    ...&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Other controls may include:&lt;/p&gt;

&lt;p&gt;Maximum supply&lt;br&gt;
Per-wallet limits&lt;br&gt;
Pausing&lt;br&gt;
Signature-based mint authorization&lt;br&gt;
Payment validation&lt;br&gt;
Allow lists&lt;br&gt;
Mint phases&lt;br&gt;
Upgrade permissions&lt;/p&gt;

&lt;p&gt;This is why smart contract development is one of the security-sensitive stages of NFT development. The source article specifically identifies smart contract security, access control, and transaction integrity as major risks.&lt;/p&gt;

&lt;p&gt;The Event Is Just as Important as the State&lt;/p&gt;

&lt;p&gt;Suppose the contract emits:&lt;/p&gt;

&lt;p&gt;event NFTMinted(&lt;br&gt;
    address indexed owner,&lt;br&gt;
    uint256 indexed tokenId&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;The event can then be consumed by off-chain infrastructure:&lt;/p&gt;

&lt;p&gt;Smart Contract&lt;br&gt;
      │&lt;br&gt;
      │ NFTMinted&lt;br&gt;
      ▼&lt;br&gt;
Blockchain Node&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Event Listener&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Indexer&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Application Database&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Marketplace / UI&lt;/p&gt;

&lt;p&gt;This is how the application can discover that a new NFT has been minted without constantly scanning every transaction manually.&lt;/p&gt;

&lt;p&gt;The blockchain remains the source of truth.&lt;/p&gt;

&lt;p&gt;The indexer becomes the query layer.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;Why an Indexer Is Necessary&lt;/p&gt;

&lt;p&gt;Imagine a marketplace displaying:&lt;/p&gt;

&lt;p&gt;Latest NFTs&lt;br&gt;
Trending Collections&lt;br&gt;
Owner History&lt;br&gt;
Sales History&lt;br&gt;
Floor Price&lt;br&gt;
Trading Volume&lt;/p&gt;

&lt;p&gt;Querying raw blockchain state for every page load quickly becomes impractical.&lt;/p&gt;

&lt;p&gt;An indexer can transform blockchain events into application-friendly data:&lt;/p&gt;

&lt;p&gt;Blockchain Events&lt;br&gt;
       │&lt;br&gt;
       ▼&lt;br&gt;
    Indexer&lt;br&gt;
       │&lt;br&gt;
       ├── NFT ownership&lt;br&gt;
       ├── Transfers&lt;br&gt;
       ├── Sales&lt;br&gt;
       ├── Collections&lt;br&gt;
       └── Metadata&lt;br&gt;
              │&lt;br&gt;
              ▼&lt;br&gt;
          Database&lt;br&gt;
              │&lt;br&gt;
              ▼&lt;br&gt;
          Frontend&lt;/p&gt;

&lt;p&gt;But indexing introduces its own engineering problems.&lt;/p&gt;

&lt;p&gt;You need to handle:&lt;/p&gt;

&lt;p&gt;Duplicate events&lt;br&gt;
RPC failures&lt;br&gt;
Delayed confirmations&lt;br&gt;
Chain reorganizations&lt;br&gt;
Reprocessing&lt;br&gt;
Idempotency&lt;br&gt;
Metadata synchronization&lt;/p&gt;

&lt;p&gt;So the NFT does not become “visible everywhere” immediately after the user clicks Mint.&lt;/p&gt;

&lt;p&gt;There is a state transition between transaction submitted and application synchronized.&lt;/p&gt;

&lt;p&gt;The Marketplace Does Not Own the NFT&lt;/p&gt;

&lt;p&gt;A marketplace typically facilitates trading.&lt;/p&gt;

&lt;p&gt;The underlying NFT remains governed by its smart contract.&lt;/p&gt;

&lt;p&gt;A simplified secondary sale looks like:&lt;/p&gt;

&lt;p&gt;Seller&lt;br&gt;
  │&lt;br&gt;
  │ list NFT&lt;br&gt;
  ▼&lt;br&gt;
Marketplace&lt;br&gt;
  │&lt;br&gt;
  │ buyer purchases&lt;br&gt;
  ▼&lt;br&gt;
Smart Contract&lt;br&gt;
  │&lt;br&gt;
  ├── transfer NFT&lt;br&gt;
  ├── transfer payment&lt;br&gt;
  └── emit events&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
       Indexer&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
    Updated marketplace&lt;/p&gt;

&lt;p&gt;This is an important architectural boundary.&lt;/p&gt;

&lt;p&gt;The marketplace database should not become the authority for ownership.&lt;/p&gt;

&lt;p&gt;The contract should enforce the actual asset transfer.&lt;/p&gt;

&lt;p&gt;Royalties Are a Contract Design Problem&lt;/p&gt;

&lt;p&gt;NFT projects often want creators to receive a percentage from secondary sales.&lt;/p&gt;

&lt;p&gt;That sounds straightforward:&lt;/p&gt;

&lt;p&gt;Sale = $1,000&lt;br&gt;
Royalty = 5%&lt;br&gt;
Creator = $50&lt;br&gt;
Seller = $950&lt;/p&gt;

&lt;p&gt;But royalty behavior is not uniformly enforced across every marketplace and trading environment.&lt;/p&gt;

&lt;p&gt;This means royalty requirements need to be considered at both levels:&lt;/p&gt;

&lt;p&gt;Smart Contract&lt;br&gt;
      +&lt;br&gt;
Marketplace Integration&lt;/p&gt;

&lt;p&gt;A technically correct royalty implementation does not guarantee identical behavior across every external marketplace.&lt;/p&gt;

&lt;p&gt;This is one reason marketplace compatibility should be considered early rather than after the contract is deployed.&lt;/p&gt;

&lt;p&gt;Immutable vs Upgradeable Contracts&lt;/p&gt;

&lt;p&gt;Another architectural decision is whether the contract should be immutable or upgradeable.&lt;/p&gt;

&lt;p&gt;An immutable contract provides a strong guarantee:&lt;/p&gt;

&lt;p&gt;Deployed&lt;br&gt;
   ↓&lt;br&gt;
Logic stays fixed&lt;/p&gt;

&lt;p&gt;An upgradeable architecture introduces:&lt;/p&gt;

&lt;p&gt;Proxy&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Implementation&lt;br&gt;
  │&lt;br&gt;
  ├── V1&lt;br&gt;
  ├── V2&lt;br&gt;
  └── V3&lt;/p&gt;

&lt;p&gt;Upgradeability can be useful when requirements are expected to evolve.&lt;/p&gt;

&lt;p&gt;But it also introduces additional trust and security assumptions.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Who controls upgrades?&lt;br&gt;
Can the administrator change ownership logic?&lt;br&gt;
Can metadata behavior change?&lt;br&gt;
Is the upgrade mechanism secured?&lt;br&gt;
What happens if the upgrade key is compromised?&lt;/p&gt;

&lt;p&gt;There is no universal answer.&lt;/p&gt;

&lt;p&gt;The important thing is to make the trust model explicit before deployment.&lt;/p&gt;

&lt;p&gt;Gas Is an Architecture Constraint&lt;/p&gt;

&lt;p&gt;Every on-chain operation has a cost.&lt;/p&gt;

&lt;p&gt;The cost can be affected by:&lt;/p&gt;

&lt;p&gt;Blockchain network&lt;br&gt;
Contract complexity&lt;br&gt;
Storage operations&lt;br&gt;
Minting model&lt;br&gt;
Batch size&lt;br&gt;
Current network demand&lt;/p&gt;

&lt;p&gt;For large collections, this can influence whether you use:&lt;/p&gt;

&lt;p&gt;One transaction per NFT&lt;/p&gt;

&lt;p&gt;or a batch-oriented approach.&lt;/p&gt;

&lt;p&gt;ERC-1155 can be particularly useful when many token types or quantities need to be managed efficiently.&lt;/p&gt;

&lt;p&gt;This is why blockchain selection should happen before implementation rather than being treated as an infrastructure detail at the end.&lt;/p&gt;

&lt;p&gt;The Architecture I Would Start With&lt;/p&gt;

&lt;p&gt;For a typical NFT platform, I would separate responsibilities like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     User
                      │
                      ▼
                Web / Mobile App
                      │
          ┌───────────┴───────────┐
          ▼                       ▼
       Wallet                  Backend
                                  │
                   ┌──────────────┼──────────────┐
                   ▼              ▼              ▼
               Metadata        Indexer       Marketplace
               Service           │
                   │             │
                   ▼             ▼
            IPFS / Storage   Application DB
                                  │
                                  │
                              Blockchain
                                  │
                       ┌──────────┴──────────┐
                       ▼                     ▼
                NFT Contract            Token Contract
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The responsibilities stay clear:&lt;/p&gt;

&lt;p&gt;Wallet       → authorization&lt;br&gt;
Frontend     → user interaction&lt;br&gt;
Backend      → application logic&lt;br&gt;
Smart contract → ownership + on-chain rules&lt;br&gt;
Storage      → metadata + assets&lt;br&gt;
Indexer      → blockchain read model&lt;br&gt;
Marketplace  → trading experience&lt;br&gt;
Blockchain   → settlement + ownership truth&lt;/p&gt;

&lt;p&gt;This separation also makes it easier to replace individual components without redesigning the entire system.&lt;/p&gt;

&lt;p&gt;The Hard Part Isn't Minting&lt;/p&gt;

&lt;p&gt;Writing a basic NFT contract is not particularly difficult.&lt;/p&gt;

&lt;p&gt;Writing a basic NFT contract is not particularly difficult.&lt;/p&gt;

&lt;p&gt;The difficult questions appear around the contract:&lt;/p&gt;

&lt;p&gt;What exactly does the token represent?&lt;br&gt;
Where does the metadata live?&lt;br&gt;
Who can mint?&lt;br&gt;
Can the contract be upgraded?&lt;br&gt;
How is ownership indexed?&lt;br&gt;
How are royalties handled?&lt;br&gt;
What happens when the RPC provider fails?&lt;br&gt;
How does the application reconcile pending transactions?&lt;br&gt;
Which marketplaces support the required behavior?&lt;br&gt;
What happens if metadata becomes unavailable?&lt;/p&gt;

&lt;p&gt;In our blockchain work at SotaTek, these are often the questions that require more architectural consideration than the minting logic itself. The contract may only take a few functions to implement, but making the entire system reliable means thinking through storage, indexing, wallet flows, marketplace compatibility, and the boundary between on-chain and off-chain state.&lt;/p&gt;

&lt;p&gt;These are architecture questions, not Solidity syntax questions.&lt;/p&gt;

&lt;p&gt;That is why a production NFT implementation needs to consider smart contracts, metadata, storage, wallets, indexing, marketplaces, security, and blockchain infrastructure as one system.&lt;/p&gt;

&lt;p&gt;Final Takeaway&lt;/p&gt;

&lt;p&gt;An NFT is not an image stored on a blockchain.&lt;/p&gt;

&lt;p&gt;It is better understood as a combination of:&lt;/p&gt;

&lt;p&gt;Token Standard&lt;br&gt;
      +&lt;br&gt;
Smart Contract&lt;br&gt;
      +&lt;br&gt;
Ownership State&lt;br&gt;
      +&lt;br&gt;
Metadata&lt;br&gt;
      +&lt;br&gt;
Off-chain Storage&lt;br&gt;
      +&lt;br&gt;
Wallet&lt;br&gt;
      +&lt;br&gt;
Blockchain&lt;br&gt;
      +&lt;br&gt;
Indexing&lt;/p&gt;

&lt;p&gt;The blockchain provides verifiable ownership and transaction history.&lt;/p&gt;

&lt;p&gt;The smart contract defines the rules.&lt;/p&gt;

&lt;p&gt;The metadata describes the asset.&lt;/p&gt;

&lt;p&gt;The wallet authorizes transactions.&lt;/p&gt;

&lt;p&gt;The indexer makes blockchain state usable by applications.&lt;/p&gt;

&lt;p&gt;And the marketplace connects that infrastructure to users.&lt;/p&gt;

&lt;p&gt;Once you understand these boundaries, NFT development becomes less about “minting a token” and more about designing a system where on-chain truth and off-chain application state remain consistent.&lt;/p&gt;

&lt;p&gt;For a broader overview of NFT token standards, development stages, use cases, and the cost factors involved in taking an NFT project from contract deployment to marketplace integration, this &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/blockchain/nft-token-development-services/" rel="noopener noreferrer"&gt;NFT token development guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; provides additional context.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>nft</category>
      <category>smartcontract</category>
    </item>
    <item>
      <title>What Actually Happens When You Swap Tokens on a DEX?</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Fri, 25 Sep 2026 09:10:29 +0000</pubDate>
      <link>https://dev.to/devsotatek/what-actually-happens-when-you-swap-tokens-on-a-dex-1dk</link>
      <guid>https://dev.to/devsotatek/what-actually-happens-when-you-swap-tokens-on-a-dex-1dk</guid>
      <description>&lt;p&gt;A DEX can look deceptively simple from the frontend.&lt;/p&gt;

&lt;p&gt;Select two tokens, enter an amount, click Swap, approve the transaction, and wait.&lt;/p&gt;

&lt;p&gt;Underneath that button, however, several systems are working together:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Wallet&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
DEX Frontend&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Router / Smart Contract&lt;br&gt;
  │&lt;br&gt;
  ├── Liquidity Pool&lt;br&gt;
  ├── Token Contracts&lt;br&gt;
  └── Pricing Logic&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
      Blockchain&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
       Event Logs&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
       Indexer&lt;/p&gt;

&lt;p&gt;Understanding this flow is useful because a DEX is not simply a UI connected to a smart contract.&lt;/p&gt;

&lt;p&gt;It is a distributed trading system where pricing, liquidity, execution, settlement, and indexing all have different responsibilities.&lt;/p&gt;

&lt;p&gt;Start With the Liquidity Pool&lt;/p&gt;

&lt;p&gt;Consider a simple ETH/USDC pool.&lt;/p&gt;

&lt;p&gt;The pool contains:&lt;/p&gt;

&lt;p&gt;ETH  → 10&lt;br&gt;
USDC → 30,000&lt;/p&gt;

&lt;p&gt;A trader wants to swap ETH for USDC.&lt;/p&gt;

&lt;p&gt;In an AMM-based DEX, the trade does not need to find another trader willing to take the opposite side.&lt;/p&gt;

&lt;p&gt;The trader interacts with the liquidity pool itself.&lt;/p&gt;

&lt;p&gt;Liquidity providers supply the assets, and the AMM determines the exchange rate according to its pricing function.&lt;/p&gt;

&lt;p&gt;A simplified constant-product model is:&lt;/p&gt;

&lt;p&gt;x × y = k&lt;/p&gt;

&lt;p&gt;Where:&lt;/p&gt;

&lt;p&gt;x = reserve of token A&lt;br&gt;
y = reserve of token B&lt;br&gt;
k = invariant&lt;/p&gt;

&lt;p&gt;Before the trade:&lt;/p&gt;

&lt;p&gt;10 ETH × 30,000 USDC&lt;br&gt;
= 300,000&lt;/p&gt;

&lt;p&gt;Suppose the trader sends 1 ETH into the pool.&lt;/p&gt;

&lt;p&gt;The new ETH reserve becomes:&lt;/p&gt;

&lt;p&gt;x' = 11 ETH&lt;/p&gt;

&lt;p&gt;The AMM needs to maintain the invariant:&lt;/p&gt;

&lt;p&gt;11 × y' = 300,000&lt;/p&gt;

&lt;p&gt;Therefore:&lt;/p&gt;

&lt;p&gt;y' ≈ 27,272.73 USDC&lt;/p&gt;

&lt;p&gt;The difference between the old and new reserves represents the amount of USDC that can be removed from the pool, before fees and other implementation details are applied.&lt;/p&gt;

&lt;p&gt;This is the basic idea behind an AMM.&lt;/p&gt;

&lt;p&gt;The important part is that the pool itself becomes the counterparty.&lt;/p&gt;

&lt;p&gt;Price and Execution Price Are Not the Same&lt;/p&gt;

&lt;p&gt;This is where things become more interesting.&lt;/p&gt;

&lt;p&gt;The displayed price might look like:&lt;/p&gt;

&lt;p&gt;1 ETH = 3,000 USDC&lt;/p&gt;

&lt;p&gt;But that does not mean a trader can necessarily swap a large amount of ETH at exactly 3,000 USDC.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because the trade changes the pool reserves.&lt;/p&gt;

&lt;p&gt;A larger trade moves the pool further along its pricing curve.&lt;/p&gt;

&lt;p&gt;This creates price impact.&lt;/p&gt;

&lt;p&gt;There is also a difference between:&lt;/p&gt;

&lt;p&gt;Market price&lt;br&gt;
Quoted execution price&lt;br&gt;
Price impact&lt;br&gt;
Slippage tolerance&lt;/p&gt;

&lt;p&gt;A production DEX needs to expose these clearly before the user signs the transaction.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Input:              1.0 ETH&lt;br&gt;
Expected output:    2,970 USDC&lt;br&gt;
Price impact:       0.8%&lt;br&gt;
Minimum received:   2,940 USDC&lt;br&gt;
Network fee:        0.002 ETH&lt;/p&gt;

&lt;p&gt;These numbers are not just UI decoration.&lt;/p&gt;

&lt;p&gt;They are part of the transaction safety model.&lt;/p&gt;

&lt;p&gt;The Frontend Does Not Execute the Swap&lt;/p&gt;

&lt;p&gt;The frontend calculates or retrieves a quote.&lt;/p&gt;

&lt;p&gt;It does not ultimately control the token transfer.&lt;/p&gt;

&lt;p&gt;The actual state transition happens through smart contracts.&lt;/p&gt;

&lt;p&gt;A simplified flow is:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 │ "Swap 1 ETH for USDC"&lt;br&gt;
 ▼&lt;br&gt;
Frontend&lt;br&gt;
 │&lt;br&gt;
 │ request quote&lt;br&gt;
 ▼&lt;br&gt;
Router&lt;br&gt;
 │&lt;br&gt;
 │ calculate route&lt;br&gt;
 ▼&lt;br&gt;
Smart Contract&lt;br&gt;
 │&lt;br&gt;
 │ execute swap&lt;br&gt;
 ▼&lt;br&gt;
Liquidity Pool&lt;br&gt;
 │&lt;br&gt;
 │ update reserves&lt;br&gt;
 ▼&lt;br&gt;
Blockchain State&lt;/p&gt;

&lt;p&gt;The wallet signs the transaction.&lt;/p&gt;

&lt;p&gt;The blockchain executes it.&lt;/p&gt;

&lt;p&gt;The smart contract determines whether the requested operation is valid.&lt;/p&gt;

&lt;p&gt;This distinction is important because the frontend should be treated as an untrusted interface.&lt;/p&gt;

&lt;p&gt;Anyone can call the contract directly.&lt;/p&gt;

&lt;p&gt;The contract itself must enforce the rules.&lt;/p&gt;

&lt;p&gt;Token Approvals Add Another Transaction&lt;/p&gt;

&lt;p&gt;For ERC-20 tokens, users typically need to authorize a contract to spend their tokens.&lt;/p&gt;

&lt;p&gt;This creates an additional step:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
approve()&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Token Contract&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
DEX Router&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
swap()&lt;/p&gt;

&lt;p&gt;So the first interaction with a token may require two transactions:&lt;/p&gt;

&lt;p&gt;approve&lt;br&gt;
swap&lt;/p&gt;

&lt;p&gt;A production frontend needs to make this state understandable.&lt;/p&gt;

&lt;p&gt;Otherwise users may see:&lt;/p&gt;

&lt;p&gt;“Transaction successful”&lt;/p&gt;

&lt;p&gt;and still wonder why the swap has not happened.&lt;/p&gt;

&lt;p&gt;The frontend should distinguish between:&lt;/p&gt;

&lt;p&gt;Approval confirmed&lt;br&gt;
Swap pending&lt;br&gt;
Swap confirmed&lt;br&gt;
Swap failed&lt;/p&gt;

&lt;p&gt;This is a small UX detail with a large operational impact.&lt;/p&gt;

&lt;p&gt;The Router Is Where Things Get Interesting&lt;/p&gt;

&lt;p&gt;A simple DEX might execute:&lt;/p&gt;

&lt;p&gt;ETH → USDC&lt;/p&gt;

&lt;p&gt;But users may not always get the best execution through a single pool.&lt;/p&gt;

&lt;p&gt;A router can split or chain trades:&lt;/p&gt;

&lt;p&gt;ETH&lt;br&gt;
 │&lt;br&gt;
 ├── Pool A&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
USDC&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Pool B&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
DAI&lt;/p&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;p&gt;ETH&lt;br&gt;
 │&lt;br&gt;
 ├── 60% → Pool A&lt;br&gt;
 │&lt;br&gt;
 └── 40% → Pool B&lt;br&gt;
              │&lt;br&gt;
              ▼&lt;br&gt;
             USDC&lt;/p&gt;

&lt;p&gt;The router's job is to determine how the requested trade should be executed according to the available liquidity and routing logic.&lt;/p&gt;

&lt;p&gt;This creates a trade-off.&lt;/p&gt;

&lt;p&gt;More sophisticated routing can improve execution, but it also increases:&lt;/p&gt;

&lt;p&gt;Gas consumption&lt;br&gt;
Contract complexity&lt;br&gt;
Failure modes&lt;br&gt;
Simulation requirements&lt;br&gt;
Security surface&lt;/p&gt;

&lt;p&gt;The cheapest route computationally is not necessarily the route with the best execution price.&lt;/p&gt;

&lt;p&gt;What Happens When the User Clicks "Swap"?&lt;/p&gt;

&lt;p&gt;Let's follow the transaction.&lt;/p&gt;

&lt;p&gt;Step 1: The frontend creates a transaction&lt;/p&gt;

&lt;p&gt;The application prepares something conceptually similar to:&lt;/p&gt;

&lt;p&gt;to:&lt;br&gt;
  DEX Router&lt;/p&gt;

&lt;p&gt;method:&lt;br&gt;
  swapExactTokensForTokens()&lt;/p&gt;

&lt;p&gt;parameters:&lt;br&gt;
  amountIn&lt;br&gt;
  amountOutMin&lt;br&gt;
  path&lt;br&gt;
  recipient&lt;br&gt;
  deadline&lt;br&gt;
Step 2: The wallet asks for authorization&lt;/p&gt;

&lt;p&gt;The user reviews the transaction and signs it.&lt;/p&gt;

&lt;p&gt;The wallet produces a cryptographic signature proving that the account authorized the transaction.&lt;/p&gt;

&lt;p&gt;Step 3: The transaction reaches the network&lt;/p&gt;

&lt;p&gt;The transaction is broadcast to the blockchain network.&lt;/p&gt;

&lt;p&gt;At this point it is not necessarily finalized.&lt;/p&gt;

&lt;p&gt;It may be:&lt;/p&gt;

&lt;p&gt;Pending&lt;br&gt;
   ↓&lt;br&gt;
Included in block&lt;br&gt;
   ↓&lt;br&gt;
Executed&lt;br&gt;
   ↓&lt;br&gt;
Confirmed / finalized&lt;/p&gt;

&lt;p&gt;The frontend therefore needs to handle asynchronous transaction state rather than assuming that submission equals completion.&lt;/p&gt;

&lt;p&gt;Step 4: The smart contract executes&lt;/p&gt;

&lt;p&gt;The router calls the required contracts.&lt;/p&gt;

&lt;p&gt;The transaction may involve:&lt;/p&gt;

&lt;p&gt;Router&lt;br&gt;
  ↓&lt;br&gt;
Token A&lt;br&gt;
  ↓&lt;br&gt;
Pool&lt;br&gt;
  ↓&lt;br&gt;
Token B&lt;/p&gt;

&lt;p&gt;Each contract call changes blockchain state.&lt;/p&gt;

&lt;p&gt;If any required condition fails, the transaction reverts.&lt;/p&gt;

&lt;p&gt;What Happens Inside the Pool?&lt;/p&gt;

&lt;p&gt;The pool receives the input token.&lt;/p&gt;

&lt;p&gt;Then the contract calculates how much output can be released while respecting its pricing rules.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;Before:&lt;/p&gt;

&lt;p&gt;Token A reserve = 10&lt;br&gt;
Token B reserve = 30,000&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ↓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Trader sends Token A&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ↓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;AMM calculation&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ↓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After:&lt;/p&gt;

&lt;p&gt;Token A reserve = 11&lt;br&gt;
Token B reserve = ~27,272&lt;/p&gt;

&lt;p&gt;The exact calculation depends on the AMM implementation.&lt;/p&gt;

&lt;p&gt;Real protocols may also account for:&lt;/p&gt;

&lt;p&gt;Trading fees&lt;br&gt;
Concentrated liquidity&lt;br&gt;
Multiple price ranges&lt;br&gt;
Dynamic fees&lt;br&gt;
Different invariant designs&lt;/p&gt;

&lt;p&gt;So the simple x × y = k model is useful for understanding the concept, but it is not a complete representation of every modern AMM.&lt;/p&gt;

&lt;p&gt;Where Do Liquidity Providers Fit?&lt;/p&gt;

&lt;p&gt;The pool needs liquidity.&lt;/p&gt;

&lt;p&gt;Liquidity providers deposit assets into the protocol and receive a claim representing their share of the pool.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;Liquidity Provider&lt;br&gt;
       │&lt;br&gt;
       ├── Token A&lt;br&gt;
       └── Token B&lt;br&gt;
             │&lt;br&gt;
             ▼&lt;br&gt;
       Liquidity Pool&lt;br&gt;
             │&lt;br&gt;
             ▼&lt;br&gt;
          Traders&lt;/p&gt;

&lt;p&gt;In return, LPs can receive a portion of trading fees according to the protocol's rules.&lt;/p&gt;

&lt;p&gt;But providing liquidity is not risk-free.&lt;/p&gt;

&lt;p&gt;LPs can be exposed to:&lt;/p&gt;

&lt;p&gt;Impermanent loss&lt;br&gt;
Smart contract risk&lt;br&gt;
Asset volatility&lt;br&gt;
Oracle risk&lt;br&gt;
Protocol-specific risks&lt;/p&gt;

&lt;p&gt;From an engineering perspective, liquidity is therefore not simply a feature.&lt;/p&gt;

&lt;p&gt;It is part of the protocol's economic design.&lt;/p&gt;

&lt;p&gt;The Blockchain Is the Source of Settlement Truth&lt;/p&gt;

&lt;p&gt;After the transaction executes, the blockchain contains the resulting state.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Trader&lt;br&gt;
  ↓&lt;br&gt;
-1 ETH&lt;br&gt;
+2,970 USDC&lt;/p&gt;

&lt;p&gt;Pool&lt;br&gt;
  ↓&lt;br&gt;
+1 ETH&lt;br&gt;
-2,970 USDC&lt;/p&gt;

&lt;p&gt;The DEX frontend should not invent this state.&lt;/p&gt;

&lt;p&gt;It should derive it from blockchain data.&lt;/p&gt;

&lt;p&gt;That creates an important architecture:&lt;/p&gt;

&lt;p&gt;Blockchain&lt;br&gt;
    │&lt;br&gt;
    ├── Transactions&lt;br&gt;
    ├── Events&lt;br&gt;
    └── Contract State&lt;br&gt;
            │&lt;br&gt;
            ▼&lt;br&gt;
         Indexer&lt;br&gt;
            │&lt;br&gt;
            ▼&lt;br&gt;
       Application DB&lt;br&gt;
            │&lt;br&gt;
            ▼&lt;br&gt;
       DEX Frontend&lt;br&gt;
Why You Need an Indexer&lt;/p&gt;

&lt;p&gt;Reading raw blockchain data directly from the frontend becomes expensive and inconvenient as the application grows.&lt;/p&gt;

&lt;p&gt;Consider a trading page that needs:&lt;/p&gt;

&lt;p&gt;Historical trades&lt;br&gt;
Token prices&lt;br&gt;
Volume&lt;br&gt;
Liquidity&lt;br&gt;
User positions&lt;br&gt;
Transaction history&lt;br&gt;
Pool activity&lt;/p&gt;

&lt;p&gt;You could query the blockchain repeatedly.&lt;/p&gt;

&lt;p&gt;But that is not an efficient application architecture.&lt;/p&gt;

&lt;p&gt;An indexer processes blockchain events and transforms them into application-friendly data.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Swap Event&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Event Listener&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Indexer&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Database&lt;br&gt;
    │&lt;br&gt;
    ├── price history&lt;br&gt;
    ├── volume&lt;br&gt;
    ├── transactions&lt;br&gt;
    └── pool analytics&lt;/p&gt;

&lt;p&gt;The blockchain remains the source of truth.&lt;/p&gt;

&lt;p&gt;The indexed database becomes the query layer.&lt;/p&gt;

&lt;p&gt;That distinction is important.&lt;/p&gt;

&lt;p&gt;Events Are Part of the Integration Contract&lt;/p&gt;

&lt;p&gt;Smart contracts can emit events such as:&lt;/p&gt;

&lt;p&gt;event Swap(&lt;br&gt;
    address indexed sender,&lt;br&gt;
    uint256 amountIn,&lt;br&gt;
    uint256 amountOut&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;The event allows off-chain systems to observe state transitions without repeatedly reconstructing every operation from scratch.&lt;/p&gt;

&lt;p&gt;But event processing needs to be designed carefully.&lt;/p&gt;

&lt;p&gt;An indexer should account for:&lt;/p&gt;

&lt;p&gt;Duplicate processing&lt;br&gt;
Missed events&lt;br&gt;
RPC failures&lt;br&gt;
Chain reorganizations&lt;br&gt;
Reprocessing&lt;br&gt;
Idempotency&lt;/p&gt;

&lt;p&gt;For example, processing the same Swap event twice should not create two trades in the database.&lt;/p&gt;

&lt;p&gt;This is a distributed-systems problem hiding inside a DeFi application.&lt;/p&gt;

&lt;p&gt;Slippage Is a Safety Mechanism&lt;/p&gt;

&lt;p&gt;Suppose the frontend quotes:&lt;/p&gt;

&lt;p&gt;1 ETH → 3,000 USDC&lt;/p&gt;

&lt;p&gt;But market conditions change before the transaction is executed.&lt;/p&gt;

&lt;p&gt;The user might receive:&lt;/p&gt;

&lt;p&gt;1 ETH → 2,700 USDC&lt;/p&gt;

&lt;p&gt;That may be unacceptable.&lt;/p&gt;

&lt;p&gt;The transaction therefore includes a minimum acceptable output:&lt;/p&gt;

&lt;p&gt;amountOutMin = 2,950 USDC&lt;/p&gt;

&lt;p&gt;If the actual output falls below that threshold, the transaction reverts.&lt;/p&gt;

&lt;p&gt;This is why slippage tolerance is more than a UI preference.&lt;/p&gt;

&lt;p&gt;It becomes a parameter enforced by the smart contract.&lt;/p&gt;

&lt;p&gt;The Mempool Creates Another Problem: MEV&lt;/p&gt;

&lt;p&gt;There is a gap between:&lt;/p&gt;

&lt;p&gt;User signs transaction&lt;/p&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;p&gt;Transaction is executed&lt;/p&gt;

&lt;p&gt;During that period, the transaction may be visible to actors that can observe pending transactions.&lt;/p&gt;

&lt;p&gt;This creates opportunities for Maximal Extractable Value (MEV).&lt;/p&gt;

&lt;p&gt;One common example is a sandwich attack:&lt;/p&gt;

&lt;p&gt;User's swap&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Attacker observes transaction&lt;br&gt;
     │&lt;br&gt;
     ├── Buy before user&lt;br&gt;
     │&lt;br&gt;
     ├── User executes at worse price&lt;br&gt;
     │&lt;br&gt;
     └── Sell after user&lt;/p&gt;

&lt;p&gt;The result can be worse execution for the original trader.&lt;/p&gt;

&lt;p&gt;DEX design therefore needs to consider:&lt;/p&gt;

&lt;p&gt;Slippage limits&lt;br&gt;
Transaction ordering&lt;br&gt;
Private transaction mechanisms&lt;br&gt;
Routing&lt;br&gt;
Liquidity depth&lt;/p&gt;

&lt;p&gt;MEV is not purely a smart-contract bug.&lt;/p&gt;

&lt;p&gt;It is a consequence of how transaction ordering and public blockchains interact.&lt;/p&gt;

&lt;p&gt;Gas Is Part of the Product&lt;/p&gt;

&lt;p&gt;A technically correct swap can still provide a poor user experience if the transaction costs too much.&lt;/p&gt;

&lt;p&gt;Gas usage depends on factors such as:&lt;/p&gt;

&lt;p&gt;Number of contract calls&lt;br&gt;
Storage operations&lt;br&gt;
Routing complexity&lt;br&gt;
Network conditions&lt;br&gt;
Smart contract implementation&lt;/p&gt;

&lt;p&gt;A simple swap may require relatively little computation, while a multi-hop or multi-contract transaction can be considerably more expensive.&lt;/p&gt;

&lt;p&gt;This creates an important optimization question:&lt;/p&gt;

&lt;p&gt;Is the better price worth the additional execution cost?&lt;/p&gt;

&lt;p&gt;A routing algorithm that saves a user 5 USDC but costs an additional 8 USDC in gas is not actually improving execution.&lt;/p&gt;

&lt;p&gt;The system needs to optimize for net user outcome, not just quoted token output.&lt;/p&gt;

&lt;p&gt;Cross-Chain DEXs Add Another Trust Boundary&lt;/p&gt;

&lt;p&gt;Supporting multiple blockchains sounds like a frontend feature.&lt;/p&gt;

&lt;p&gt;It is not.&lt;/p&gt;

&lt;p&gt;A cross-chain DEX may involve:&lt;/p&gt;

&lt;p&gt;Chain A&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Bridge / Messaging Layer&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Chain B&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
DEX / Liquidity&lt;/p&gt;

&lt;p&gt;Now the system depends on additional components:&lt;/p&gt;

&lt;p&gt;Bridges&lt;br&gt;
Messaging protocols&lt;br&gt;
Relayers&lt;br&gt;
Multiple RPC providers&lt;br&gt;
Multiple smart contract environments&lt;br&gt;
Cross-chain liquidity&lt;/p&gt;

&lt;p&gt;Every new dependency expands the attack surface.&lt;/p&gt;

&lt;p&gt;Supporting ten chains is not simply ten times the configuration.&lt;/p&gt;

&lt;p&gt;The security model becomes significantly more complex.&lt;/p&gt;

&lt;p&gt;The Architecture I Would Start With&lt;/p&gt;

&lt;p&gt;For a production-oriented AMM DEX, a reasonable architecture is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                User
                  │
                  ▼
            Web / Mobile UI
                  │
        ┌─────────┴─────────┐
        ▼                   ▼
     Wallet              API Layer
                            │
                     ┌──────┴──────┐
                     ▼             ▼
                 Indexer       Analytics
                     │
                     ▼
                Application DB

                  Blockchain
                       │
         ┌─────────────┴─────────────┐
         ▼                           ▼
    Router Contract             Token Contracts
         │
         ▼
    Liquidity Pools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Each layer has a specific responsibility:&lt;/p&gt;

&lt;p&gt;Frontend       → interaction&lt;br&gt;
Wallet         → authorization&lt;br&gt;
Smart contract → execution + settlement&lt;br&gt;
Liquidity pool → available liquidity&lt;br&gt;
Blockchain     → state + finality&lt;br&gt;
Indexer        → queryable blockchain data&lt;br&gt;
Database       → application read model&lt;br&gt;
Analytics      → aggregated insights&lt;/p&gt;

&lt;p&gt;Keeping these boundaries clear makes the system much easier to test, monitor, and evolve.&lt;/p&gt;

&lt;p&gt;The Hard Part Isn't the Swap&lt;/p&gt;

&lt;p&gt;Writing a basic swap contract is not the hardest part of building a DEX.&lt;/p&gt;

&lt;p&gt;The difficult engineering problems appear around it:&lt;/p&gt;

&lt;p&gt;How much liquidity is available?&lt;br&gt;
How do we calculate a safe quote?&lt;br&gt;
What happens when the transaction is delayed?&lt;br&gt;
How do we handle failed transactions?&lt;br&gt;
How do we prevent unauthorized actions?&lt;br&gt;
How do we index millions of events?&lt;br&gt;
How do we protect users against bad execution?&lt;br&gt;
How do we manage MEV?&lt;br&gt;
What happens when an RPC provider fails?&lt;br&gt;
What changes when we add another chain?&lt;/p&gt;

&lt;p&gt;The swap is only one state transition inside a much larger distributed system.&lt;/p&gt;

&lt;p&gt;Final Takeaway&lt;/p&gt;

&lt;p&gt;A DEX is best understood as a combination of:&lt;/p&gt;

&lt;p&gt;Trading Logic&lt;br&gt;
      +&lt;br&gt;
Liquidity&lt;br&gt;
      +&lt;br&gt;
Smart Contracts&lt;br&gt;
      +&lt;br&gt;
Wallets&lt;br&gt;
      +&lt;br&gt;
Blockchain Infrastructure&lt;br&gt;
      +&lt;br&gt;
Indexing&lt;br&gt;
      +&lt;br&gt;
User Protection&lt;/p&gt;

&lt;p&gt;The frontend makes the system look simple.&lt;/p&gt;

&lt;p&gt;Underneath it, the protocol has to coordinate pricing, liquidity, authorization, execution, settlement, and off-chain data.&lt;/p&gt;

&lt;p&gt;That is why DEX development is less about building a “swap page” and more about designing a reliable financial system around blockchain constraints.&lt;/p&gt;

&lt;p&gt;The most important architectural question is not:&lt;/p&gt;

&lt;p&gt;“How do we build a token swap?”&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;p&gt;“Which parts of the trading system need to be trustless, which parts can remain off-chain, and how do we keep the two consistent?”&lt;/p&gt;

&lt;p&gt;That decision shapes almost every other engineering choice.&lt;/p&gt;

&lt;p&gt;For a broader overview of DEX architecture, trading models, development stages, and the infrastructure involved, see &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/blockchain/dex-development/" rel="noopener noreferrer"&gt;SotaTek's DEX Development guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>smartcontract</category>
      <category>ethereum</category>
    </item>
    <item>
      <title>Building an Enterprise AI Chatbot: What the Architecture Actually Looks Like</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Thu, 24 Sep 2026 08:35:12 +0000</pubDate>
      <link>https://dev.to/devsotatek/building-an-enterprise-ai-chatbot-what-the-architecture-actually-looks-like-3a14</link>
      <guid>https://dev.to/devsotatek/building-an-enterprise-ai-chatbot-what-the-architecture-actually-looks-like-3a14</guid>
      <description>&lt;p&gt;An enterprise AI chatbot is easy to demo.&lt;/p&gt;

&lt;p&gt;Connect an LLM to a chat interface, add a system prompt, upload a few documents, and you have something that looks impressive in an afternoon.&lt;/p&gt;

&lt;p&gt;Production is different.&lt;/p&gt;

&lt;p&gt;The moment a chatbot needs to access private company data, respect user permissions, retrieve current information, call internal APIs, and operate reliably at scale, it stops being a simple LLM application.&lt;/p&gt;

&lt;p&gt;It becomes a distributed system.&lt;/p&gt;

&lt;p&gt;A practical architecture usually looks something like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     User
                       │
                       ▼
                Chat Interface
                       │
                       ▼
                API / Gateway
                       │
                       ▼
             AI Orchestration Layer
                /      |       \
               /       |        \
              ▼        ▼         ▼
           RAG      Tools      Policies
            │         │           │
            ▼         ▼           ▼
      Knowledge DB  CRM/ERP   Access Control
            │         │
            └────┬────┘
                 ▼
                LLM
                 │
                 ▼
          Response / Action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The LLM is only one component.&lt;/p&gt;

&lt;p&gt;The LLM Should Not Be Your Application Backend&lt;/p&gt;

&lt;p&gt;A common first architecture looks like this:&lt;/p&gt;

&lt;p&gt;User → LLM → Response&lt;/p&gt;

&lt;p&gt;That works for general questions.&lt;/p&gt;

&lt;p&gt;It breaks down as soon as the user asks:&lt;/p&gt;

&lt;p&gt;“What is the status of my latest support ticket?”&lt;/p&gt;

&lt;p&gt;The model does not inherently know the answer.&lt;/p&gt;

&lt;p&gt;The application needs to:&lt;/p&gt;

&lt;p&gt;Authenticate the user.&lt;br&gt;
Determine what data the user is allowed to access.&lt;br&gt;
Retrieve the relevant ticket.&lt;br&gt;
Provide that context to the model.&lt;br&gt;
Generate a response.&lt;br&gt;
Return the result without exposing unauthorized data.&lt;/p&gt;

&lt;p&gt;The architecture becomes:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Authentication&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Authorization&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Application Backend&lt;br&gt;
 │&lt;br&gt;
 ├── CRM / Ticketing API&lt;br&gt;
 ├── Knowledge Base&lt;br&gt;
 └── AI Orchestrator&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
         LLM&lt;/p&gt;

&lt;p&gt;This distinction is important:&lt;/p&gt;

&lt;p&gt;The LLM generates language. The application owns the business rules.&lt;/p&gt;

&lt;p&gt;Do not put authorization logic into a prompt and expect the model to enforce it.&lt;/p&gt;

&lt;p&gt;RAG Is a Retrieval System First&lt;/p&gt;

&lt;p&gt;Enterprise chatbots frequently use Retrieval-Augmented Generation (RAG) to answer questions from internal knowledge.&lt;/p&gt;

&lt;p&gt;A simplified pipeline is:&lt;/p&gt;

&lt;p&gt;Documents&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Ingestion&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Chunking&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Embeddings&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Vector Database&lt;/p&gt;

&lt;p&gt;At query time:&lt;/p&gt;

&lt;p&gt;User Query&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Embedding&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Retriever&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Relevant Documents&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Prompt + Context&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
LLM&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Answer&lt;/p&gt;

&lt;p&gt;The important engineering point is that RAG quality depends heavily on the retrieval layer.&lt;/p&gt;

&lt;p&gt;If the wrong documents are retrieved, a more capable model does not automatically fix the problem.&lt;/p&gt;

&lt;p&gt;That means production RAG needs to consider:&lt;/p&gt;

&lt;p&gt;Chunking strategy&lt;br&gt;
Metadata&lt;br&gt;
Embedding model&lt;br&gt;
Retrieval strategy&lt;br&gt;
Top-K selection&lt;br&gt;
Filtering&lt;br&gt;
Document freshness&lt;br&gt;
Source citations&lt;br&gt;
Access permissions&lt;/p&gt;

&lt;p&gt;A vector database is therefore not just a storage component. It is part of the answer-quality pipeline.&lt;/p&gt;

&lt;p&gt;Authorization Must Happen Before Retrieval&lt;/p&gt;

&lt;p&gt;This is one of the easiest mistakes to make in an enterprise RAG system.&lt;/p&gt;

&lt;p&gt;Imagine a company has documents belonging to:&lt;/p&gt;

&lt;p&gt;Finance&lt;br&gt;
HR&lt;br&gt;
Engineering&lt;br&gt;
Sales&lt;/p&gt;

&lt;p&gt;A user from Sales asks:&lt;/p&gt;

&lt;p&gt;“Show me the latest compensation policy.”&lt;/p&gt;

&lt;p&gt;If the retriever searches the entire vector database first and applies permissions afterward, sensitive HR content may already have entered the model context.&lt;/p&gt;

&lt;p&gt;The safer flow is:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Identity&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Permissions&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Filtered Retrieval&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Authorized Documents&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
LLM&lt;/p&gt;

&lt;p&gt;Access control should be part of retrieval itself.&lt;/p&gt;

&lt;p&gt;For multi-tenant systems, this becomes even more important:&lt;/p&gt;

&lt;p&gt;tenant_id = customer_123&lt;br&gt;
user_role = manager&lt;br&gt;
department = sales&lt;/p&gt;

&lt;p&gt;These attributes should influence what the retrieval layer is allowed to return.&lt;/p&gt;

&lt;p&gt;The model should never be responsible for deciding whether a user is authorized to see a document.&lt;/p&gt;

&lt;p&gt;When RAG Is Not Enough&lt;/p&gt;

&lt;p&gt;RAG works well when the chatbot needs to answer questions from relatively stable knowledge.&lt;/p&gt;

&lt;p&gt;But consider:&lt;/p&gt;

&lt;p&gt;“Create a support ticket for this issue.”&lt;/p&gt;

&lt;p&gt;Retrieving documentation does not solve that problem.&lt;/p&gt;

&lt;p&gt;The system needs to perform an action.&lt;/p&gt;

&lt;p&gt;This is where tool calling or agentic workflows become useful.&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
LLM&lt;br&gt;
 │&lt;br&gt;
 ├── Search knowledge&lt;br&gt;
 ├── Get customer&lt;br&gt;
 ├── Create ticket&lt;br&gt;
 └── Check ticket status&lt;/p&gt;

&lt;p&gt;The LLM decides which tool is relevant, but the tools themselves should expose controlled interfaces.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;create_ticket(&lt;br&gt;
    customer_id,&lt;br&gt;
    category,&lt;br&gt;
    description&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;The model should not receive unrestricted database access.&lt;/p&gt;

&lt;p&gt;Give it narrowly scoped capabilities.&lt;/p&gt;

&lt;p&gt;This creates a useful principle:&lt;/p&gt;

&lt;p&gt;Give the model tools, not infrastructure access.&lt;/p&gt;

&lt;p&gt;Chatbot vs Agent&lt;/p&gt;

&lt;p&gt;There is a meaningful architectural difference between answering and acting.&lt;/p&gt;

&lt;p&gt;A traditional enterprise chatbot:&lt;/p&gt;

&lt;p&gt;Question&lt;br&gt;
   ↓&lt;br&gt;
Retrieve&lt;br&gt;
   ↓&lt;br&gt;
Generate&lt;br&gt;
   ↓&lt;br&gt;
Answer&lt;/p&gt;

&lt;p&gt;An agentic workflow:&lt;/p&gt;

&lt;p&gt;Goal&lt;br&gt;
 ↓&lt;br&gt;
Plan&lt;br&gt;
 ↓&lt;br&gt;
Tool&lt;br&gt;
 ↓&lt;br&gt;
Observe&lt;br&gt;
 ↓&lt;br&gt;
Tool&lt;br&gt;
 ↓&lt;br&gt;
Observe&lt;br&gt;
 ↓&lt;br&gt;
Final Result&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;“Find the customer's last three orders, identify the delayed one, and open a support ticket.”&lt;/p&gt;

&lt;p&gt;The system may need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Query CRM&lt;/li&gt;
&lt;li&gt;Query order service&lt;/li&gt;
&lt;li&gt;Compare delivery status&lt;/li&gt;
&lt;li&gt;Generate ticket content&lt;/li&gt;
&lt;li&gt;Create ticket&lt;/li&gt;
&lt;li&gt;Return confirmation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is no longer just a chatbot.&lt;/p&gt;

&lt;p&gt;It is an orchestration system with an LLM as one of its decision-making components.&lt;/p&gt;

&lt;p&gt;Keep the Tool Layer Deterministic&lt;/p&gt;

&lt;p&gt;One of the most useful design principles for agentic systems is to keep tool execution deterministic.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;LLM&lt;br&gt;
 │&lt;br&gt;
 │ create_ticket(...)&lt;br&gt;
 ▼&lt;br&gt;
Tool Gateway&lt;br&gt;
 │&lt;br&gt;
 ├── Validate parameters&lt;br&gt;
 ├── Check authorization&lt;br&gt;
 ├── Apply business rules&lt;br&gt;
 ├── Execute API call&lt;br&gt;
 └── Return structured result&lt;/p&gt;

&lt;p&gt;Do not let the model directly execute arbitrary SQL or arbitrary HTTP requests.&lt;/p&gt;

&lt;p&gt;Instead, expose explicit capabilities:&lt;/p&gt;

&lt;p&gt;get_customer()&lt;br&gt;
get_order()&lt;br&gt;
search_policy()&lt;br&gt;
create_ticket()&lt;br&gt;
update_ticket()&lt;/p&gt;

&lt;p&gt;This makes the system easier to secure, test, monitor, and audit.&lt;/p&gt;

&lt;p&gt;Enterprise Data Is Usually the Hard Part&lt;/p&gt;

&lt;p&gt;The LLM is often the easiest component to replace.&lt;/p&gt;

&lt;p&gt;Enterprise data is not.&lt;/p&gt;

&lt;p&gt;A real deployment may need to connect:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             AI Application
                   │
   ┌───────────────┼────────────────┐
   ▼               ▼                ▼
  CRM             ERP           Knowledge Base
   │               │                │
   ▼               ▼                ▼
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Customer Data   Transactions      Documents&lt;/p&gt;

&lt;p&gt;These systems often have different:&lt;/p&gt;

&lt;p&gt;APIs&lt;br&gt;
Authentication models&lt;br&gt;
Data formats&lt;br&gt;
Update frequencies&lt;br&gt;
Failure modes&lt;br&gt;
Rate limits&lt;/p&gt;

&lt;p&gt;The AI layer therefore needs an integration boundary rather than a collection of ad-hoc API calls buried inside prompts.&lt;/p&gt;

&lt;p&gt;Observability Is Part of the Architecture&lt;/p&gt;

&lt;p&gt;A production chatbot should not only log:&lt;/p&gt;

&lt;p&gt;user → response&lt;/p&gt;

&lt;p&gt;You need to understand how the response was produced.&lt;/p&gt;

&lt;p&gt;A useful trace might contain:&lt;/p&gt;

&lt;p&gt;Request ID&lt;br&gt;
User ID&lt;br&gt;
Model&lt;br&gt;
Prompt version&lt;br&gt;
Retrieved documents&lt;br&gt;
Tool calls&lt;br&gt;
Latency&lt;br&gt;
Token usage&lt;br&gt;
Errors&lt;br&gt;
Final response&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Request&lt;br&gt;
 │&lt;br&gt;
 ├── Retrieval: 180 ms&lt;br&gt;
 ├── CRM API: 240 ms&lt;br&gt;
 ├── LLM: 1.8 s&lt;br&gt;
 ├── Tokens: 2,431&lt;br&gt;
 └── Total: 2.3 s&lt;/p&gt;

&lt;p&gt;Without this information, debugging a bad answer becomes guesswork.&lt;/p&gt;

&lt;p&gt;Observability also gives you the data needed to optimize cost and latency.&lt;/p&gt;

&lt;p&gt;Evaluation Should Test the System, Not Just the Model&lt;/p&gt;

&lt;p&gt;A model benchmark is not enough to determine whether an enterprise chatbot works.&lt;/p&gt;

&lt;p&gt;You need to evaluate the complete pipeline:&lt;/p&gt;

&lt;p&gt;Question&lt;br&gt;
   ↓&lt;br&gt;
Retrieval&lt;br&gt;
   ↓&lt;br&gt;
Context&lt;br&gt;
   ↓&lt;br&gt;
Model&lt;br&gt;
   ↓&lt;br&gt;
Tool Calls&lt;br&gt;
   ↓&lt;br&gt;
Response&lt;/p&gt;

&lt;p&gt;Useful metrics include:&lt;/p&gt;

&lt;p&gt;Retrieval relevance&lt;br&gt;
Answer correctness&lt;br&gt;
Citation accuracy&lt;br&gt;
Hallucination rate&lt;br&gt;
Tool-call accuracy&lt;br&gt;
Task completion rate&lt;br&gt;
Latency&lt;br&gt;
Cost per request&lt;br&gt;
Human escalation rate&lt;/p&gt;

&lt;p&gt;A model can produce an excellent answer from the wrong document.&lt;/p&gt;

&lt;p&gt;That is still a system failure.&lt;/p&gt;

&lt;p&gt;A Production-Oriented Architecture&lt;/p&gt;

&lt;p&gt;Putting the pieces together:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     User
                       │
                       ▼
                ┌─────────────┐
                │ API Gateway │
                └──────┬──────┘
                       │
                Authentication
                       │
                       ▼
              ┌─────────────────┐
              │ AI Orchestrator │
              └───────┬─────────┘
                      /|\
                     / | \
                    /  |  \
                   ▼   ▼   ▼
                 RAG Tools Policy
                  │    │     │
                  ▼    ▼     ▼
               Vector CRM   AuthZ
               Store  ERP
                  │    │
                  └────┬┘
                       ▼
                      LLM
                       │
                       ▼
                Validation Layer
                       │
                       ▼
                    Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Around the entire system, you also need:&lt;/p&gt;

&lt;p&gt;Observability&lt;br&gt;
Evaluation&lt;br&gt;
Audit Logging&lt;br&gt;
Rate Limiting&lt;br&gt;
Secrets Management&lt;br&gt;
Cost Controls&lt;/p&gt;

&lt;p&gt;These are not optional production extras.&lt;/p&gt;

&lt;p&gt;They are part of the system.&lt;/p&gt;

&lt;p&gt;The Real Architecture Decision&lt;/p&gt;

&lt;p&gt;The interesting question is not:&lt;/p&gt;

&lt;p&gt;“Which LLM should we use?”&lt;/p&gt;

&lt;p&gt;Models change quickly.&lt;/p&gt;

&lt;p&gt;The more durable engineering decisions are:&lt;/p&gt;

&lt;p&gt;Where does enterprise knowledge live?&lt;br&gt;
How is it retrieved?&lt;br&gt;
Where is authorization enforced?&lt;br&gt;
Which actions can the model perform?&lt;br&gt;
How are tool calls validated?&lt;br&gt;
How do we handle failures?&lt;br&gt;
How do we evaluate output quality?&lt;br&gt;
How do we observe the complete request lifecycle?&lt;/p&gt;

&lt;p&gt;Once these boundaries are clear, the underlying model becomes a replaceable component rather than the foundation of the entire architecture.&lt;/p&gt;

&lt;p&gt;Final Takeaway&lt;/p&gt;

&lt;p&gt;An enterprise AI chatbot is not an LLM with a chat UI.&lt;/p&gt;

&lt;p&gt;It is an application architecture that combines:&lt;/p&gt;

&lt;p&gt;LLM&lt;br&gt;
+&lt;br&gt;
RAG&lt;br&gt;
+&lt;br&gt;
Enterprise APIs&lt;br&gt;
+&lt;br&gt;
Access Control&lt;br&gt;
+&lt;br&gt;
Tool Calling&lt;br&gt;
+&lt;br&gt;
Observability&lt;br&gt;
+&lt;br&gt;
Evaluation&lt;/p&gt;

&lt;p&gt;The LLM provides the language interface.&lt;/p&gt;

&lt;p&gt;The surrounding system provides data, permissions, actions, and reliability.&lt;/p&gt;

&lt;p&gt;That is the difference between a chatbot that looks impressive in a demo and one that can actually operate inside an enterprise environment.&lt;/p&gt;

&lt;p&gt;If you're looking at the broader implementation lifecycle, including data preparation, architecture selection, enterprise integration, security, and deployment, this &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/ai-and-machine-learning/enterprise-ai-chatbots/" rel="noopener noreferrer"&gt;enterprise AI chatbot implementation guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; provides additional context.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>softwareengineering</category>
      <category>architecture</category>
    </item>
    <item>
      <title>What Actually Happens When You Put an NFT Into a Game?</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Thu, 24 Sep 2026 08:25:43 +0000</pubDate>
      <link>https://dev.to/devsotatek/what-actually-happens-when-you-put-an-nft-into-a-game-hhb</link>
      <guid>https://dev.to/devsotatek/what-actually-happens-when-you-put-an-nft-into-a-game-hhb</guid>
      <description>&lt;p&gt;Putting an NFT into a game sounds simple:&lt;/p&gt;

&lt;p&gt;Mint an NFT, connect a wallet, and let players trade it.&lt;/p&gt;

&lt;p&gt;That is the easy part.&lt;/p&gt;

&lt;p&gt;The difficult part is deciding what belongs on-chain, what stays off-chain, and how the two systems communicate without turning every gameplay action into a blockchain transaction.&lt;/p&gt;

&lt;p&gt;A production NFT game is not a traditional game with a smart contract attached to it. It is a distributed system with two very different execution environments:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                NFT GAME
                   │
         ┌─────────┴─────────┐
         │                   │
     OFF-CHAIN             ON-CHAIN
         │                   │
    Game Engine         Smart Contracts
    Game Server         NFT Ownership
    Database            Token Balances
    Matchmaking         Asset Transfers
    Gameplay            Marketplace
         │                   │
         └─────────┬─────────┘
                   │
              Wallet / RPC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once you look at it this way, many of the architecture decisions become much easier to reason about.&lt;/p&gt;

&lt;p&gt;The Game Should Not Run on the Blockchain&lt;/p&gt;

&lt;p&gt;The first mistake is trying to put gameplay logic on-chain.&lt;/p&gt;

&lt;p&gt;Imagine a multiplayer game where every movement generates a blockchain transaction:&lt;/p&gt;

&lt;p&gt;Player moves&lt;br&gt;
    ↓&lt;br&gt;
Transaction&lt;br&gt;
    ↓&lt;br&gt;
Validator&lt;br&gt;
    ↓&lt;br&gt;
State update&lt;br&gt;
    ↓&lt;br&gt;
Game server&lt;br&gt;
    ↓&lt;br&gt;
Other players&lt;/p&gt;

&lt;p&gt;It would be slow, expensive, and completely unnecessary.&lt;/p&gt;

&lt;p&gt;The blockchain is good at things that need shared, verifiable state.&lt;/p&gt;

&lt;p&gt;A game engine is good at things that need fast, mutable state.&lt;/p&gt;

&lt;p&gt;So the architecture should usually look more like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Game Client
                      │
          ┌───────────┴───────────┐
          │                       │
          ▼                       ▼
    Game Backend              Wallet
          │                       │
          ▼                       ▼
    Game Database            Blockchain
          │                       │
          │                ┌──────┴──────┐
          │                │             │
          │             NFT Contract  Token Contract
          │
          └─────── Asset State ──────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The game server handles gameplay.&lt;/p&gt;

&lt;p&gt;The blockchain handles ownership and other state that needs to be independently verifiable.&lt;/p&gt;

&lt;p&gt;That boundary is probably the most important architectural decision in an NFT game.&lt;/p&gt;

&lt;p&gt;What Actually Goes On-Chain?&lt;/p&gt;

&lt;p&gt;A useful rule is:&lt;/p&gt;

&lt;p&gt;Put the minimum amount of state on-chain that needs blockchain-level ownership, verification, or settlement.&lt;/p&gt;

&lt;p&gt;For an NFT game, that might include:&lt;/p&gt;

&lt;p&gt;Token ownership&lt;br&gt;
NFT ID&lt;br&gt;
Token metadata reference&lt;br&gt;
Supply constraints&lt;br&gt;
Transfer rules&lt;br&gt;
Marketplace transactions&lt;br&gt;
Royalty logic&lt;br&gt;
In-game token balances&lt;/p&gt;

&lt;p&gt;It usually should not include:&lt;/p&gt;

&lt;p&gt;Player coordinates&lt;br&gt;
Animation state&lt;br&gt;
Matchmaking&lt;br&gt;
Real-time combat&lt;br&gt;
Chat&lt;br&gt;
Temporary game state&lt;br&gt;
Every player interaction&lt;/p&gt;

&lt;p&gt;For example, a sword might exist as an NFT:&lt;/p&gt;

&lt;p&gt;NFT #1842&lt;br&gt;
    │&lt;br&gt;
    ├── Owner: 0xA91...&lt;br&gt;
    ├── Token URI&lt;br&gt;
    ├── Rarity&lt;br&gt;
    └── Asset ID&lt;/p&gt;

&lt;p&gt;But the fact that the player currently has that sword equipped belongs in the game layer.&lt;/p&gt;

&lt;p&gt;This gives you two states:&lt;/p&gt;

&lt;p&gt;Blockchain:&lt;br&gt;
"Wallet X owns Sword #1842"&lt;/p&gt;

&lt;p&gt;Game server:&lt;br&gt;
"Player 928 has Sword #1842 equipped"&lt;/p&gt;

&lt;p&gt;The second state can change thousands of times without touching the blockchain.&lt;/p&gt;

&lt;p&gt;The Smart Contract Is the Ownership Layer&lt;/p&gt;

&lt;p&gt;The smart contract should be treated as the authoritative source for blockchain ownership.&lt;/p&gt;

&lt;p&gt;A simplified NFT contract might look like:&lt;/p&gt;

&lt;p&gt;contract GameItem is ERC721 {&lt;br&gt;
    uint256 private nextTokenId;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function mint(address player)
    external
    returns (uint256)
{
    uint256 tokenId = nextTokenId++;
    _safeMint(player, tokenId);
    return tokenId;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;The important part is not the exact implementation.&lt;/p&gt;

&lt;p&gt;It is the responsibility boundary.&lt;/p&gt;

&lt;p&gt;The contract answers:&lt;/p&gt;

&lt;p&gt;Who owns this asset?&lt;br&gt;
Can it be transferred?&lt;br&gt;
Can it be minted?&lt;br&gt;
How many can exist?&lt;br&gt;
What rules apply to the transfer?&lt;/p&gt;

&lt;p&gt;The game server should not maintain a second independent truth about ownership.&lt;/p&gt;

&lt;p&gt;If the database says:&lt;/p&gt;

&lt;p&gt;Player A → Sword #1842&lt;/p&gt;

&lt;p&gt;but the blockchain says:&lt;/p&gt;

&lt;p&gt;Player B → Sword #1842&lt;/p&gt;

&lt;p&gt;the system has a consistency problem.&lt;/p&gt;

&lt;p&gt;For ownership, the blockchain should win.&lt;/p&gt;

&lt;p&gt;What Happens When a Player Buys an NFT?&lt;/p&gt;

&lt;p&gt;This is where the distributed architecture becomes interesting.&lt;/p&gt;

&lt;p&gt;Suppose Player A buys an NFT from Player B.&lt;/p&gt;

&lt;p&gt;A simplified flow is:&lt;/p&gt;

&lt;p&gt;Player A&lt;br&gt;
   │&lt;br&gt;
   │ purchase&lt;br&gt;
   ▼&lt;br&gt;
Marketplace&lt;br&gt;
   │&lt;br&gt;
   │ transaction&lt;br&gt;
   ▼&lt;br&gt;
Blockchain&lt;br&gt;
   │&lt;br&gt;
   ├── transfer NFT&lt;br&gt;
   ├── transfer payment&lt;br&gt;
   └── emit event&lt;br&gt;
           │&lt;br&gt;
           ▼&lt;br&gt;
        Indexer&lt;br&gt;
           │&lt;br&gt;
           ▼&lt;br&gt;
      Game Backend&lt;br&gt;
           │&lt;br&gt;
           ▼&lt;br&gt;
       Game Client&lt;/p&gt;

&lt;p&gt;The blockchain transaction changes ownership.&lt;/p&gt;

&lt;p&gt;The game backend then observes that change and updates its local representation.&lt;/p&gt;

&lt;p&gt;This introduces an important concept:&lt;/p&gt;

&lt;p&gt;Blockchain state and application state are eventually synchronized, not necessarily updated at exactly the same time.&lt;/p&gt;

&lt;p&gt;That means the backend must handle:&lt;/p&gt;

&lt;p&gt;Pending transactions&lt;br&gt;
Failed transactions&lt;br&gt;
Reorganizations&lt;br&gt;
Duplicate events&lt;br&gt;
Delayed confirmations&lt;br&gt;
RPC failures&lt;/p&gt;

&lt;p&gt;A production integration cannot simply assume:&lt;/p&gt;

&lt;p&gt;sendTransaction()&lt;br&gt;
    ↓&lt;br&gt;
success = true&lt;br&gt;
    ↓&lt;br&gt;
updateDatabase()&lt;/p&gt;

&lt;p&gt;The transaction lifecycle is asynchronous.&lt;/p&gt;

&lt;p&gt;Events Are the Bridge&lt;/p&gt;

&lt;p&gt;Smart contract events are useful for synchronizing blockchain activity with the game backend.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;event ItemTransferred(&lt;br&gt;
    address indexed from,&lt;br&gt;
    address indexed to,&lt;br&gt;
    uint256 indexed tokenId&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;The backend can subscribe to blockchain events and update its internal state.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;Smart Contract&lt;br&gt;
      │&lt;br&gt;
      │ ItemTransferred&lt;br&gt;
      ▼&lt;br&gt;
Blockchain Node / RPC&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Event Listener&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Game Database&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Game API&lt;/p&gt;

&lt;p&gt;This is much more scalable than having the game client repeatedly query the blockchain for every piece of state.&lt;/p&gt;

&lt;p&gt;Wallets Are Not Just Login Buttons&lt;/p&gt;

&lt;p&gt;Wallet integration is another place where traditional game architecture changes.&lt;/p&gt;

&lt;p&gt;A wallet provides an address and, more importantly, control over the private key associated with that address.&lt;/p&gt;

&lt;p&gt;The game might therefore use:&lt;/p&gt;

&lt;p&gt;Game Account&lt;br&gt;
     │&lt;br&gt;
     ├── player profile&lt;br&gt;
     ├── progression&lt;br&gt;
     ├── preferences&lt;br&gt;
     └── wallet address&lt;/p&gt;

&lt;p&gt;The wallet address identifies the blockchain account, but it should not automatically become the entire identity system of the game.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Player ID: 92814&lt;br&gt;
Wallet: 0xA91...&lt;/p&gt;

&lt;p&gt;The backend can associate the two after a secure wallet-signature authentication flow.&lt;/p&gt;

&lt;p&gt;This allows the game to maintain normal application functionality while using the wallet for blockchain ownership.&lt;/p&gt;

&lt;p&gt;NFT Metadata Is Another Distributed-System Problem&lt;/p&gt;

&lt;p&gt;The NFT itself may only contain a reference to metadata rather than storing every attribute directly on-chain.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;NFT&lt;br&gt;
 │&lt;br&gt;
 └── tokenURI&lt;br&gt;
       │&lt;br&gt;
       ▼&lt;br&gt;
    Metadata&lt;br&gt;
       │&lt;br&gt;
       ├── name&lt;br&gt;
       ├── image&lt;br&gt;
       ├── attributes&lt;br&gt;
       └── game asset reference&lt;/p&gt;

&lt;p&gt;That creates another architectural question:&lt;/p&gt;

&lt;p&gt;What happens if the metadata disappears or changes?&lt;/p&gt;

&lt;p&gt;If the game depends on a centralized URL, the NFT may technically exist on-chain while the actual asset becomes unavailable.&lt;/p&gt;

&lt;p&gt;For long-lived assets, the storage strategy therefore matters almost as much as the smart contract itself.&lt;/p&gt;

&lt;p&gt;The blockchain can prove ownership.&lt;/p&gt;

&lt;p&gt;It does not automatically guarantee that every piece of off-chain data associated with that ownership will remain available forever.&lt;/p&gt;

&lt;p&gt;The Game Engine Is Still the Game Engine&lt;/p&gt;

&lt;p&gt;Unity or Unreal Engine remains responsible for what it has always been good at:&lt;/p&gt;

&lt;p&gt;Input&lt;br&gt;
  ↓&lt;br&gt;
Gameplay Logic&lt;br&gt;
  ↓&lt;br&gt;
Rendering&lt;br&gt;
  ↓&lt;br&gt;
Physics&lt;br&gt;
  ↓&lt;br&gt;
Audio&lt;br&gt;
  ↓&lt;br&gt;
Networking&lt;/p&gt;

&lt;p&gt;Blockchain integration becomes another service boundary.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Unity / Unreal&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Blockchain SDK / Backend API&lt;br&gt;
      │&lt;br&gt;
      ├── Wallet&lt;br&gt;
      ├── NFT data&lt;br&gt;
      ├── Marketplace&lt;br&gt;
      └── Smart contract calls&lt;/p&gt;

&lt;p&gt;This separation is important.&lt;/p&gt;

&lt;p&gt;You do not want blockchain-specific logic spread across hundreds of gameplay components.&lt;/p&gt;

&lt;p&gt;Keep wallet operations, contract interactions, transaction state, and blockchain synchronization behind well-defined interfaces.&lt;/p&gt;

&lt;p&gt;The Real Challenge Is Consistency&lt;/p&gt;

&lt;p&gt;Once you have two state machines, consistency becomes the hard problem.&lt;/p&gt;

&lt;p&gt;Consider this sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Player buys NFT&lt;/li&gt;
&lt;li&gt;Transaction submitted&lt;/li&gt;
&lt;li&gt;Transaction pending&lt;/li&gt;
&lt;li&gt;Game server receives request&lt;/li&gt;
&lt;li&gt;Player closes the game&lt;/li&gt;
&lt;li&gt;Transaction confirms&lt;/li&gt;
&lt;li&gt;Backend misses the event&lt;/li&gt;
&lt;li&gt;Player logs in again&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What does the game show?&lt;/p&gt;

&lt;p&gt;This is no longer simply a smart-contract problem.&lt;/p&gt;

&lt;p&gt;It is a distributed-systems problem.&lt;/p&gt;

&lt;p&gt;You need mechanisms for:&lt;/p&gt;

&lt;p&gt;Event replay&lt;br&gt;
Idempotent processing&lt;br&gt;
Transaction status tracking&lt;br&gt;
Confirmation handling&lt;br&gt;
Reconciliation&lt;br&gt;
Retry logic&lt;br&gt;
RPC failover&lt;/p&gt;

&lt;p&gt;A useful backend design is:&lt;/p&gt;

&lt;p&gt;Blockchain&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Event Listener&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Message Queue&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Indexer&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Game Database&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Game API&lt;/p&gt;

&lt;p&gt;The indexer becomes the bridge between blockchain state and application state.&lt;/p&gt;

&lt;p&gt;Where the Economy Lives&lt;/p&gt;

&lt;p&gt;NFT games often add another layer: fungible tokens.&lt;/p&gt;

&lt;p&gt;You may have:&lt;/p&gt;

&lt;p&gt;NFT&lt;br&gt;
 ├── Characters&lt;br&gt;
 ├── Weapons&lt;br&gt;
 ├── Skins&lt;br&gt;
 └── Land&lt;/p&gt;

&lt;p&gt;Token&lt;br&gt;
 ├── Rewards&lt;br&gt;
 ├── Purchases&lt;br&gt;
 └── Marketplace payments&lt;/p&gt;

&lt;p&gt;This is where tokenomics becomes an engineering concern.&lt;/p&gt;

&lt;p&gt;A reward mechanism that continuously creates tokens without corresponding demand can create an economic problem even if the smart contract is perfectly secure.&lt;/p&gt;

&lt;p&gt;The technical architecture therefore has to support the economic model rather than treating tokenomics as a separate document.&lt;/p&gt;

&lt;p&gt;Security Changes Everything&lt;/p&gt;

&lt;p&gt;Traditional game security focuses heavily on the client and server.&lt;/p&gt;

&lt;p&gt;Blockchain games add another security boundary:&lt;/p&gt;

&lt;p&gt;Client&lt;br&gt;
  ↓&lt;br&gt;
Backend&lt;br&gt;
  ↓&lt;br&gt;
Smart Contract&lt;br&gt;
  ↓&lt;br&gt;
Blockchain&lt;/p&gt;

&lt;p&gt;A vulnerability in a deployed contract can be fundamentally different from a server-side bug.&lt;/p&gt;

&lt;p&gt;You cannot simply deploy a patch and assume the old state disappears.&lt;/p&gt;

&lt;p&gt;Smart contracts handling NFTs, tokens, marketplace transactions, and royalties should therefore be treated as security-critical infrastructure.&lt;/p&gt;

&lt;p&gt;At minimum, review:&lt;/p&gt;

&lt;p&gt;Access control&lt;br&gt;
Mint authorization&lt;br&gt;
Transfer restrictions&lt;br&gt;
Reentrancy&lt;br&gt;
Integer handling&lt;br&gt;
Signature validation&lt;br&gt;
Replay protection&lt;br&gt;
Upgradeability assumptions&lt;br&gt;
Economic attack vectors&lt;/p&gt;

&lt;p&gt;The blockchain layer should be audited independently from the game client.&lt;/p&gt;

&lt;p&gt;The Architecture I Would Start With&lt;/p&gt;

&lt;p&gt;For a typical NFT game, a reasonable starting architecture is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 ┌───────────────┐
                 │ Game Client   │
                 │ Unity/Unreal  │
                 └───────┬───────┘
                         │
                         ▼
                 ┌───────────────┐
                 │ Game Backend  │
                 └───────┬───────┘
                         │
           ┌─────────────┼─────────────┐
           ▼             ▼             ▼
      Game DB       Blockchain API   Marketplace
                         │
                         ▼
                     RPC Node
                         │
                         ▼
                 ┌───────────────┐
                 │ Smart Contract│
                 ├───────────────┤
                 │ NFT           │
                 │ Token         │
                 │ Marketplace   │
                 └───────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The important thing is not the number of components.&lt;/p&gt;

&lt;p&gt;It is the ownership of responsibilities.&lt;/p&gt;

&lt;p&gt;Game server  → gameplay state&lt;br&gt;
Database     → application state&lt;br&gt;
Blockchain   → verifiable ownership and settlement&lt;br&gt;
Smart contract → enforceable on-chain rules&lt;br&gt;
Wallet       → player-controlled blockchain identity&lt;br&gt;
Indexer      → synchronization&lt;/p&gt;

&lt;p&gt;Once those boundaries are explicit, the system becomes much easier to scale and debug.&lt;/p&gt;

&lt;p&gt;The Main Takeaway&lt;/p&gt;

&lt;p&gt;An NFT game is not a game that happens to use NFTs.&lt;/p&gt;

&lt;p&gt;It is a system where gameplay, blockchain state, wallets, smart contracts, and off-chain infrastructure have to agree on what is true.&lt;/p&gt;

&lt;p&gt;The most important architectural decision is therefore not which blockchain to choose.&lt;/p&gt;

&lt;p&gt;It is deciding:&lt;/p&gt;

&lt;p&gt;What needs to be trustless, and what doesn't?&lt;/p&gt;

&lt;p&gt;Put ownership and settlement where independent verification matters.&lt;/p&gt;

&lt;p&gt;Keep high-frequency gameplay where low latency matters.&lt;/p&gt;

&lt;p&gt;Use the backend and indexer to connect the two worlds.&lt;/p&gt;

&lt;p&gt;That separation keeps the blockchain useful without forcing the entire game to behave like a blockchain.&lt;/p&gt;

&lt;p&gt;And once you understand that boundary, NFT game development starts looking less like “adding Web3 to a game” and more like what it really is:&lt;/p&gt;

&lt;p&gt;designing a distributed system with a game engine on one side and a blockchain on the other.&lt;/p&gt;

&lt;p&gt;If you want to explore the broader NFT game development lifecycle, including asset design, tokenomics, smart contracts, wallet integration, and marketplace architecture, this &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/blockchain/nft-game-development/" rel="noopener noreferrer"&gt;NFT Game Development guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; provides the wider context.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>gamedev</category>
      <category>smartcontract</category>
    </item>
    <item>
      <title>Zero-Knowledge Proofs Without the Magic: What the Prover and Verifier Actually Do</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Mon, 14 Sep 2026 11:18:27 +0000</pubDate>
      <link>https://dev.to/devsotatek/zero-knowledge-proofs-without-the-magic-what-the-prover-and-verifier-actually-do-1533</link>
      <guid>https://dev.to/devsotatek/zero-knowledge-proofs-without-the-magic-what-the-prover-and-verifier-actually-do-1533</guid>
      <description>&lt;h1&gt;
  
  
  Zero-Knowledge Proofs Without the Magic: What the Prover and Verifier Actually Do
&lt;/h1&gt;

&lt;p&gt;Zero-knowledge proofs are often described with a sentence that sounds almost impossible:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Prove that you know something without revealing what you know.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That description is correct, but it hides the part developers actually need to understand.&lt;/p&gt;

&lt;p&gt;A zero-knowledge proof is not encryption. The prover does not simply hide some data and send it to the verifier.&lt;/p&gt;

&lt;p&gt;Instead, the prover constructs a &lt;strong&gt;proof that a computation is valid&lt;/strong&gt;, while revealing only the information that the protocol allows the verifier to see.&lt;/p&gt;

&lt;p&gt;This distinction becomes important when ZK proofs are used in blockchain systems, where computation can be performed privately off-chain and verified cheaply on-chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start With a Simple Problem
&lt;/h2&gt;

&lt;p&gt;Suppose Alice knows a secret value &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There is a public value derived from it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = hash(x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alice wants to prove:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I know a value &lt;code&gt;x&lt;/code&gt; such that &lt;code&gt;hash(x) = y&lt;/code&gt;.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But she does not want to reveal &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A traditional solution would require Alice to reveal the secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alice
  |
  | x
  v
Verifier
  |
  | hash(x) == y ?
  v
Valid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A zero-knowledge protocol changes the interaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             secret x
                |
                v
Alice       Prover
                |
                | proof
                v
           Verifier
                |
                v
        "The statement is valid"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The verifier learns that Alice knows a valid &lt;code&gt;x&lt;/code&gt;, but does not learn &lt;code&gt;x&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;The interesting part is how the proof is constructed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Things You Need to Separate
&lt;/h2&gt;

&lt;p&gt;When working with ZK systems, three concepts are easy to mix together:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The witness
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;witness&lt;/strong&gt; is the private information known by the prover.&lt;/p&gt;

&lt;p&gt;In our example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;witness = x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The witness never needs to be exposed to the verifier.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The public inputs
&lt;/h3&gt;

&lt;p&gt;These are values that the verifier is allowed to know.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public input = y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. The statement
&lt;/h3&gt;

&lt;p&gt;The statement defines what must be proven.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hash(x) == y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the prover is effectively proving:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I know x
such that
hash(x) == y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without sending &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That separation between &lt;strong&gt;witness, public inputs, and computation&lt;/strong&gt; is one of the most useful mental models for understanding ZK systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  A ZK Proof Is Really a Proof of Computation
&lt;/h2&gt;

&lt;p&gt;This is where ZK becomes more interesting for blockchain developers.&lt;/p&gt;

&lt;p&gt;Instead of thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I want to hide a value.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I want someone to verify that a computation was executed correctly without giving them all of the computation's private inputs.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Private inputs
     |
     v
+-----------+
| Computation|
+-----------+
     |
     v
   Result
     |
     v
   Proof
     |
     v
+-----------+
| Verifier  |
+-----------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The verifier does not need to reproduce the entire computation.&lt;/p&gt;

&lt;p&gt;It only needs to verify the proof.&lt;/p&gt;

&lt;p&gt;This is why ZK proofs are useful for blockchain scaling and privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the Blockchain Fits
&lt;/h2&gt;

&lt;p&gt;Blockchains are good at verification, but expensive as general-purpose computation environments.&lt;/p&gt;

&lt;p&gt;Imagine a computation that requires millions of operations.&lt;/p&gt;

&lt;p&gt;Executing all of them directly on-chain can be expensive.&lt;/p&gt;

&lt;p&gt;A ZK-based architecture can move the expensive computation off-chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Off-chain
              ┌──────────────┐
              │   Prover     │
              │              │
Input ────────&amp;gt;│ Computation  │
              │              │
              │ Generate ZK  │
              │    Proof     │
              └──────┬───────┘
                     │
                     │ proof
                     v
              ┌──────────────┐
              │ Blockchain   │
              │              │
              │   Verifier   │
              └──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The blockchain does not need to trust the prover.&lt;/p&gt;

&lt;p&gt;It only needs to verify the proof.&lt;/p&gt;

&lt;p&gt;This creates an important engineering trade-off:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Move computation off-chain, but preserve verifiability on-chain.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Is Different From Encryption
&lt;/h2&gt;

&lt;p&gt;A common misunderstanding is that ZK proofs are simply another form of encryption.&lt;/p&gt;

&lt;p&gt;They solve different problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encryption:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Only authorized parties should be able to read this data.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Zero-knowledge proof:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“You should be able to verify that this statement is true without learning my private information.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can also combine both techniques in the same system.&lt;/p&gt;

&lt;p&gt;For example, sensitive application data can remain encrypted while a ZK proof demonstrates that the data satisfies a particular condition.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Simple Examples to Real ZK Circuits
&lt;/h2&gt;

&lt;p&gt;Real ZK systems don't usually express the computation as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hash(x) == y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and stop there.&lt;/p&gt;

&lt;p&gt;The computation is represented as a set of constraints.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x ──&amp;gt; Constraint 1
 │
 ├──&amp;gt; Constraint 2
 │
 └──&amp;gt; Constraint 3
          |
          v
      Valid / Invalid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The proving system then transforms those constraints into a proof that can be verified without exposing the private witness.&lt;/p&gt;

&lt;p&gt;Depending on the system, this can involve polynomial commitments, elliptic-curve operations, finite fields, and sophisticated proving algorithms.&lt;/p&gt;

&lt;p&gt;You do not need to understand every mathematical detail to build a ZK application.&lt;/p&gt;

&lt;p&gt;But you do need to understand the engineering boundary:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The circuit defines what is provable.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the required business logic cannot be represented correctly in the circuit, the rest of the architecture does not matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cost Is Not Gone. It Has Moved.
&lt;/h2&gt;

&lt;p&gt;This is one of the most important practical considerations.&lt;/p&gt;

&lt;p&gt;ZK systems can reduce the amount of computation that needs to happen on-chain, but generating the proof can itself be computationally expensive.&lt;/p&gt;

&lt;p&gt;A simplified cost model looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                ZK Application
                      |
          +-----------+-----------+
          |                       |
          v                       v
   Proof Generation          Proof Verification
       expensive                 cheaper
      off-chain                  on-chain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a trade-off between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prover compute&lt;/li&gt;
&lt;li&gt;Proof generation time&lt;/li&gt;
&lt;li&gt;Proof size&lt;/li&gt;
&lt;li&gt;Verification cost&lt;/li&gt;
&lt;li&gt;On-chain gas&lt;/li&gt;
&lt;li&gt;Hardware requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The optimal design depends on the application.&lt;/p&gt;

&lt;p&gt;A system that minimizes gas consumption may require significantly more off-chain computation.&lt;/p&gt;

&lt;p&gt;A system optimized for proof-generation speed may have different hardware or circuit constraints.&lt;/p&gt;

&lt;p&gt;There is no universal “ZK is cheaper” rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where ZK Proofs Become Useful
&lt;/h2&gt;

&lt;p&gt;The same architecture can support several classes of applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Private identity
&lt;/h3&gt;

&lt;p&gt;A user could prove:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I satisfy eligibility condition X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without revealing every piece of information used to determine eligibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Private transactions
&lt;/h3&gt;

&lt;p&gt;A system can prove that a transaction satisfies the required rules without exposing all transaction details publicly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling
&lt;/h3&gt;

&lt;p&gt;A prover can execute a large amount of computation off-chain and submit a compact proof that the computation was performed correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verifiable computation
&lt;/h3&gt;

&lt;p&gt;A service can perform computation for a user while providing cryptographic evidence that the result was generated according to a defined computation.&lt;/p&gt;

&lt;p&gt;The common pattern is not simply privacy.&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Compute privately or off-chain → generate proof → verify independently.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Engineering Problems Are Different From Traditional Applications
&lt;/h2&gt;

&lt;p&gt;ZK systems introduce constraints that are easy to underestimate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Circuit complexity
&lt;/h3&gt;

&lt;p&gt;The way you express an algorithm can have a major impact on proving cost.&lt;/p&gt;

&lt;p&gt;An algorithm that is efficient in normal software may be expensive to represent as a ZK circuit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prover performance
&lt;/h3&gt;

&lt;p&gt;Proof generation can require significant CPU, memory, or specialized hardware depending on the proving system and workload.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data availability
&lt;/h3&gt;

&lt;p&gt;In blockchain applications, proving that something is correct is not the same as making the underlying data available.&lt;/p&gt;

&lt;p&gt;You still need to design how relevant data is stored, retrieved, and verified.&lt;/p&gt;

&lt;h3&gt;
  
  
  Smart contract integration
&lt;/h3&gt;

&lt;p&gt;If proofs are verified on-chain, the verifier contract becomes part of the security-critical path.&lt;/p&gt;

&lt;p&gt;Its interface, gas consumption, and failure handling need to be treated like any other production smart contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key management
&lt;/h3&gt;

&lt;p&gt;Some proving systems involve trusted setup assumptions or proving/verifying keys.&lt;/p&gt;

&lt;p&gt;The security model of those components needs to be understood before deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mental Model I Use
&lt;/h2&gt;

&lt;p&gt;When evaluating a ZK architecture, I find it useful to reduce it to four questions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. What is private?
        ↓
2. What must be proven?
        ↓
3. Where is the computation executed?
        ↓
4. Where is the proof verified?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Private:
Customer eligibility data

        ↓

Prove:
Customer satisfies eligibility rules

        ↓

Compute:
Off-chain prover

        ↓

Verify:
Smart contract
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If those four answers are clear, the rest of the architecture becomes much easier to reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  ZK Is Not a Magic Privacy Layer
&lt;/h2&gt;

&lt;p&gt;Zero-knowledge proofs can provide powerful privacy and verification guarantees, but they do not automatically make an application private or secure.&lt;/p&gt;

&lt;p&gt;The application still needs to handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access control&lt;/li&gt;
&lt;li&gt;Key management&lt;/li&gt;
&lt;li&gt;Smart contract security&lt;/li&gt;
&lt;li&gt;Data availability&lt;/li&gt;
&lt;li&gt;Circuit correctness&lt;/li&gt;
&lt;li&gt;Prover infrastructure&lt;/li&gt;
&lt;li&gt;Client-side security&lt;/li&gt;
&lt;li&gt;Protocol assumptions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A perfectly verified proof can still be part of a badly designed system.&lt;/p&gt;

&lt;p&gt;The strongest ZK architectures are therefore not the ones with the most complicated cryptography.&lt;/p&gt;

&lt;p&gt;They are the ones where the &lt;strong&gt;trust boundary is explicit&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Takeaway
&lt;/h2&gt;

&lt;p&gt;The easiest way to understand zero-knowledge proofs is to stop thinking about them as a mechanism for “hiding data.”&lt;/p&gt;

&lt;p&gt;Think of them as a way to establish:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“This computation was performed correctly, and I can prove it without revealing everything involved in that computation.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That model explains why ZK proofs are useful for privacy, blockchain scaling, identity, and verifiable computation.&lt;/p&gt;

&lt;p&gt;And it also explains the engineering trade-off: &lt;strong&gt;you are not eliminating computation—you are moving it to a place where it can be performed privately and then verified efficiently.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a broader introduction to Zero-Knowledge Proofs, their privacy applications, and practical challenges, see SotaTek's &lt;a href="https://www.sotatek.com/blogs/zero-knowledge-proof-in-blockchain/" rel="noopener noreferrer"&gt;Zero-Knowledge Proof in Blockchain&lt;/a&gt; guide.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>cryptocurrency</category>
      <category>web3</category>
      <category>zeroknowledge</category>
    </item>
    <item>
      <title>AI Readiness Assessment for Developers: What to Check Before Building an AI System</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Wed, 09 Sep 2026 10:52:58 +0000</pubDate>
      <link>https://dev.to/devsotatek/ai-readiness-assessment-for-developers-what-to-check-before-building-an-ai-system-3k79</link>
      <guid>https://dev.to/devsotatek/ai-readiness-assessment-for-developers-what-to-check-before-building-an-ai-system-3k79</guid>
      <description>&lt;p&gt;Having access to an LLM API doesn't mean your application is ready for AI.&lt;/p&gt;

&lt;p&gt;A team can have access to GPT, Claude, Gemini, or an open-source model and still fail to move beyond a proof of concept because of poor data quality, missing integrations, security gaps, unpredictable costs, or an architecture that cannot survive production workloads.&lt;/p&gt;

&lt;p&gt;Before choosing a model, engineering teams should answer a more important question:&lt;/p&gt;

&lt;p&gt;Is the system actually ready to support an AI workload?&lt;/p&gt;

&lt;p&gt;An AI readiness assessment provides a structured way to evaluate that question before committing significant engineering resources.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start With the Use Case, Not the Model&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One of the most common mistakes is starting with model selection:&lt;/p&gt;

&lt;p&gt;“Should we use GPT, Claude, or an open-source LLM?”&lt;/p&gt;

&lt;p&gt;The better question is:&lt;/p&gt;

&lt;p&gt;“What decision or workflow are we trying to improve?”&lt;/p&gt;

&lt;p&gt;A well-defined AI use case should have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A clear input and expected output&lt;/li&gt;
&lt;li&gt;A measurable success criterion&lt;/li&gt;
&lt;li&gt;A defined tolerance for errors&lt;/li&gt;
&lt;li&gt;A known human fallback when necessary&lt;/li&gt;
&lt;li&gt;A reason to use AI instead of deterministic logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, “use AI for customer support” is too broad.&lt;/p&gt;

&lt;p&gt;A more actionable definition is:&lt;/p&gt;

&lt;p&gt;Generate a response draft using the customer's ticket history and product documentation, then require human approval before sending.&lt;/p&gt;

&lt;p&gt;The second definition gives engineers something they can actually architect, test, and measure.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Evaluate Data Readiness&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For most AI systems, data is a bigger constraint than model availability.&lt;/p&gt;

&lt;p&gt;Before development, check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Availability: Does the required data exist?&lt;/li&gt;
&lt;li&gt;Quality: Is it accurate, consistent, and complete?&lt;/li&gt;
&lt;li&gt;Accessibility: Can the application retrieve it reliably?&lt;/li&gt;
&lt;li&gt;Freshness: How frequently does it change?&lt;/li&gt;
&lt;li&gt;Structure: Is the data usable without extensive transformation?&lt;/li&gt;
&lt;li&gt;Security: Can it legally and safely be exposed to the AI workflow?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For RAG-based systems, for example, simply having thousands of documents is not enough.&lt;/p&gt;

&lt;p&gt;You also need a reliable ingestion pipeline, appropriate chunking, metadata, retrieval strategy, and access control.&lt;/p&gt;

&lt;p&gt;A technically impressive RAG architecture built on unreliable source data will still produce unreliable answers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check Integration Readiness&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI rarely operates as an isolated component.&lt;/p&gt;

&lt;p&gt;A production AI feature usually needs to interact with existing systems such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CRM or ERP platforms&lt;/li&gt;
&lt;li&gt;Internal APIs&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Authentication services&lt;/li&gt;
&lt;li&gt;Document storage&lt;/li&gt;
&lt;li&gt;Event queues&lt;/li&gt;
&lt;li&gt;Third-party SaaS platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Evaluate whether these systems provide stable interfaces and sufficient access to the required data.&lt;/p&gt;

&lt;p&gt;Pay particular attention to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API rate limits&lt;/li&gt;
&lt;li&gt;Authentication and authorization&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Failure handling&lt;/li&gt;
&lt;li&gt;Data synchronization&lt;/li&gt;
&lt;li&gt;Legacy system constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If critical data is trapped inside an unreliable legacy system, the problem is not your LLM. The integration layer is the actual bottleneck.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Assess Infrastructure and Architecture&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The infrastructure requirements depend heavily on the AI workload.&lt;/p&gt;

&lt;p&gt;A simple API-based LLM feature may only require an application backend, while a more complex system could involve:&lt;/p&gt;

&lt;p&gt;Client&lt;br&gt;
  ↓&lt;br&gt;
Application API&lt;br&gt;
  ↓&lt;br&gt;
AI Orchestrator&lt;br&gt;
  ├── LLM&lt;br&gt;
  ├── Vector Database&lt;br&gt;
  ├── Business APIs&lt;br&gt;
  └── Tool / Function Calls&lt;br&gt;
  ↓&lt;br&gt;
Response + Observability&lt;/p&gt;

&lt;p&gt;Before implementation, determine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where models will run&lt;/li&gt;
&lt;li&gt;Where data will be stored&lt;/li&gt;
&lt;li&gt;Whether GPUs are required&lt;/li&gt;
&lt;li&gt;Expected request volume&lt;/li&gt;
&lt;li&gt;Latency requirements&lt;/li&gt;
&lt;li&gt;Scaling strategy&lt;/li&gt;
&lt;li&gt;Availability requirements&lt;/li&gt;
&lt;li&gt;Provider dependency and fallback options&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid over-engineering the first version.&lt;/p&gt;

&lt;p&gt;A managed LLM API may be the right choice for an early production workload. Self-hosting becomes more attractive when requirements around cost, latency, data residency, model customization, or scale justify the additional operational complexity.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Treat Security as an Architecture Concern&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI introduces attack surfaces that traditional applications may not have.&lt;/p&gt;

&lt;p&gt;An AI readiness assessment should consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PII and sensitive data handling&lt;/li&gt;
&lt;li&gt;Model and API access control&lt;/li&gt;
&lt;li&gt;Prompt injection&lt;/li&gt;
&lt;li&gt;Data leakage&lt;/li&gt;
&lt;li&gt;Secrets management&lt;/li&gt;
&lt;li&gt;Tenant isolation&lt;/li&gt;
&lt;li&gt;Audit logging&lt;/li&gt;
&lt;li&gt;Output validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not assume that an LLM understands your application's authorization model.&lt;/p&gt;

&lt;p&gt;For example, if a user can only access documents belonging to their organization, the retrieval layer must enforce that constraint. It should not rely on the model to “remember” the rule.&lt;/p&gt;

&lt;p&gt;Authorization belongs in the application architecture, not in the prompt.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define Evaluation Before Development&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A traditional application can often be tested against deterministic expected outputs.&lt;/p&gt;

&lt;p&gt;AI systems are different.&lt;/p&gt;

&lt;p&gt;The same input can produce multiple valid responses, and “looks good in a demo” is not a measurable quality standard.&lt;/p&gt;

&lt;p&gt;Before building, define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evaluation datasets&lt;/li&gt;
&lt;li&gt;Accuracy or relevance metrics&lt;/li&gt;
&lt;li&gt;Hallucination criteria&lt;/li&gt;
&lt;li&gt;Safety requirements&lt;/li&gt;
&lt;li&gt;Latency targets&lt;/li&gt;
&lt;li&gt;Acceptable failure rates&lt;/li&gt;
&lt;li&gt;Human evaluation criteria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple evaluation pipeline might look like:&lt;/p&gt;

&lt;p&gt;Input&lt;br&gt;
  ↓&lt;br&gt;
AI System&lt;br&gt;
  ↓&lt;br&gt;
Generated Output&lt;br&gt;
  ↓&lt;br&gt;
Automated Evaluation&lt;br&gt;
  ↓&lt;br&gt;
Human Evaluation (if required)&lt;br&gt;
  ↓&lt;br&gt;
Release / Reject&lt;/p&gt;

&lt;p&gt;This becomes especially important when changing models, prompts, retrieval strategies, or system instructions.&lt;/p&gt;

&lt;p&gt;Without a regression evaluation set, every AI change is partly a production experiment.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Plan for Production Operations&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A successful proof of concept answers:&lt;/p&gt;

&lt;p&gt;“Can we make it work?”&lt;/p&gt;

&lt;p&gt;A production system needs to answer:&lt;/p&gt;

&lt;p&gt;“Can we operate it reliably?”&lt;/p&gt;

&lt;p&gt;At minimum, monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Error rates&lt;/li&gt;
&lt;li&gt;Token usage&lt;/li&gt;
&lt;li&gt;Cost per request&lt;/li&gt;
&lt;li&gt;Model failures&lt;/li&gt;
&lt;li&gt;Retrieval quality&lt;/li&gt;
&lt;li&gt;Output quality&lt;/li&gt;
&lt;li&gt;User feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Version prompts, system instructions, model configurations, and evaluation datasets just as you would version application code.&lt;/p&gt;

&lt;p&gt;Also design explicit fallback paths.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Primary LLM&lt;br&gt;
    ↓&lt;br&gt;
Failure / Timeout&lt;br&gt;
    ↓&lt;br&gt;
Fallback Model&lt;br&gt;
    ↓&lt;br&gt;
Human Escalation&lt;/p&gt;

&lt;p&gt;The goal is not to eliminate every AI failure. The goal is to contain failures so they do not become system failures.&lt;/p&gt;

&lt;p&gt;A Practical AI Readiness Checklist&lt;/p&gt;

&lt;p&gt;Before starting implementation, engineering teams should be able to answer “yes” to most of these questions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbptfsrj0t9x5mhei8sd0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbptfsrj0t9x5mhei8sd0.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If several answers are “no,” building the AI feature immediately may create more technical debt than business value.&lt;/p&gt;

&lt;p&gt;The engineering layer is only part of the equation; this &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/ai-and-machine-learning/ai-readiness-assessment/" rel="noopener noreferrer"&gt;AI Readiness Assessment&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; looks at the organizational, data, and business factors that also determine whether an AI initiative is ready to move forward.&lt;/p&gt;

&lt;p&gt;From Readiness Assessment to Production&lt;/p&gt;

&lt;p&gt;AI readiness is not about achieving a perfect score.&lt;/p&gt;

&lt;p&gt;It is about identifying the constraints that could prevent an AI system from delivering reliable value.&lt;/p&gt;

&lt;p&gt;A practical path is:&lt;/p&gt;

&lt;p&gt;Assess&lt;br&gt;
  ↓&lt;br&gt;
Identify Gaps&lt;br&gt;
  ↓&lt;br&gt;
Prioritize Use Case&lt;br&gt;
  ↓&lt;br&gt;
Design Architecture&lt;br&gt;
  ↓&lt;br&gt;
Build PoC&lt;br&gt;
  ↓&lt;br&gt;
Evaluate&lt;br&gt;
  ↓&lt;br&gt;
Harden&lt;br&gt;
  ↓&lt;br&gt;
Deploy&lt;br&gt;
  ↓&lt;br&gt;
Monitor &amp;amp; Iterate&lt;/p&gt;

&lt;p&gt;The most important decision is often not which AI model to use, but whether the surrounding system is ready to use one effectively.&lt;/p&gt;

&lt;p&gt;Good AI engineering starts before the first API call.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>software</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
