<?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: Quoc Bao An Nguyen</title>
    <description>The latest articles on DEV Community by Quoc Bao An Nguyen (@jasonpg).</description>
    <link>https://dev.to/jasonpg</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%2F3906196%2Ffe2857c4-bdd3-4b66-a6d5-84afac55aff5.jpeg</url>
      <title>DEV Community: Quoc Bao An Nguyen</title>
      <link>https://dev.to/jasonpg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jasonpg"/>
    <language>en</language>
    <item>
      <title>How I Built an AI Agent with LLM Function Calling (and Avoided Unnecessary Tool Calls)</title>
      <dc:creator>Quoc Bao An Nguyen</dc:creator>
      <pubDate>Thu, 01 Oct 2026 00:40:17 +0000</pubDate>
      <link>https://dev.to/jasonpg/how-i-built-an-ai-agent-with-llm-function-calling-and-avoided-unnecessary-tool-calls-4g70</link>
      <guid>https://dev.to/jasonpg/how-i-built-an-ai-agent-with-llm-function-calling-and-avoided-unnecessary-tool-calls-4g70</guid>
      <description>&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;When I first started building my AI-powered course recommendation system, I thought integrating an LLM with backend APIs would be straightforward.&lt;/p&gt;

&lt;p&gt;However, I quickly ran into a key problem:&lt;br&gt;
The model was calling backend APIs almost every time—even when it wasn’t necessary.&lt;/p&gt;

&lt;p&gt;This led to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increased latency&lt;/li&gt;
&lt;li&gt;Unnecessary API calls&lt;/li&gt;
&lt;li&gt;Inefficient system behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, I’ll walk through how I redesigned my AI Agent to behave more intelligently using controlled tool-calling and multi-step reasoning.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. The Problem
&lt;/h2&gt;
&lt;h3&gt;
  
  
  2.1 Initial Design (Naive Approach)
&lt;/h3&gt;

&lt;p&gt;My initial architecture looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Input → LLM → Function Call → Backend API → LLM → Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea was simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let the model decide which function to call&lt;/li&gt;
&lt;li&gt;Always execute the function if suggested&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 What Went Wrong
&lt;/h3&gt;

&lt;p&gt;In practice, this caused several issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The model triggered function calls even for simple messages like “Hello”&lt;/li&gt;
&lt;li&gt;Redundant API calls increased backend load&lt;/li&gt;
&lt;li&gt;No clear control over when tools should be executed&lt;/li&gt;
&lt;li&gt;Poor user experience due to unnecessary delays&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, I realized:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Letting the LLM fully control execution without constraints leads to inefficient systems.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Key Insight
&lt;/h2&gt;

&lt;p&gt;The turning point was understanding this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An AI Agent should not just “call tools” — it should &lt;strong&gt;decide when NOT to call them&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This meant I needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A decision layer&lt;/li&gt;
&lt;li&gt;Controlled execution logic&lt;/li&gt;
&lt;li&gt;Better orchestration between LLM and backend&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. System Redesign
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 New Architecture
&lt;/h3&gt;

&lt;p&gt;Instead of blindly executing tool calls, I redesigned the system:&lt;/p&gt;

&lt;p&gt;User Input&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ LLM (intent + decision)
→ Orchestration Layer
→ (Conditional) Backend Tool Execution
→ LLM Final Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4.2 Decision-Based Tool Calling
&lt;/h3&gt;

&lt;p&gt;I introduced logic where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple inputs → direct response (no tool call)&lt;/li&gt;
&lt;li&gt;Informational queries → fetch data via API&lt;/li&gt;
&lt;li&gt;Complex actions → multi-step reasoning before execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;“Hello”&lt;/td&gt;
&lt;td&gt;No tool call&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“What courses do you have?”&lt;/td&gt;
&lt;td&gt;Call course API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“Enroll me in a backend course”&lt;/td&gt;
&lt;td&gt;Gather info → then call tool&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  4.3 Deferred Execution (Important)
&lt;/h3&gt;

&lt;p&gt;Instead of calling tools immediately, the agent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identifies missing information&lt;/li&gt;
&lt;li&gt;Asks follow-up questions&lt;/li&gt;
&lt;li&gt;Executes the function only when all parameters are available&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This significantly reduced unnecessary calls.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Backend as Tools
&lt;/h2&gt;

&lt;p&gt;On the backend (ASP.NET Core), I designed APIs as callable tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GetCourses()&lt;/li&gt;
&lt;li&gt;ValidateUser()&lt;/li&gt;
&lt;li&gt;EnrollCourse()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each function was exposed with structured input/output schemas so the LLM could interact with them safely.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Prompt &amp;amp; Orchestration Strategy
&lt;/h2&gt;

&lt;p&gt;To improve behavior, I refined:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System prompts (clear tool usage rules)&lt;/li&gt;
&lt;li&gt;Function descriptions (explicit intent)&lt;/li&gt;
&lt;li&gt;Context handling (multi-turn conversations)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Goal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improve intent recognition&lt;/li&gt;
&lt;li&gt;Reduce incorrect tool selection&lt;/li&gt;
&lt;li&gt;Maintain consistent responses&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Evaluation &amp;amp; Testing
&lt;/h2&gt;

&lt;p&gt;Since I didn’t have large-scale production traffic, I evaluated the system using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simulated user inputs (various intent scenarios)&lt;/li&gt;
&lt;li&gt;Multi-turn conversation testing&lt;/li&gt;
&lt;li&gt;Edge cases (incomplete or ambiguous queries)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduced unnecessary tool calls&lt;/li&gt;
&lt;li&gt;Improved response consistency&lt;/li&gt;
&lt;li&gt;Better handling of complex requests&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. Trade-offs
&lt;/h2&gt;

&lt;p&gt;Every design has trade-offs:&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;More efficient API usage&lt;/li&gt;
&lt;li&gt;Better user experience&lt;/li&gt;
&lt;li&gt;Clearer control over system behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Increased system complexity&lt;/li&gt;
&lt;li&gt;Requires careful prompt and flow design&lt;/li&gt;
&lt;li&gt;Harder to debug than simple chatbot systems&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9. What I Learned
&lt;/h2&gt;

&lt;p&gt;This project changed how I think about AI systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLMs should be &lt;strong&gt;controllers&lt;/strong&gt;, not executors&lt;/li&gt;
&lt;li&gt;Backend systems should be &lt;strong&gt;tools&lt;/strong&gt;, not just APIs&lt;/li&gt;
&lt;li&gt;Good AI systems require &lt;strong&gt;orchestration, not just prompts&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. Conclusion
&lt;/h2&gt;

&lt;p&gt;Building an AI Agent is not just about calling an API.&lt;/p&gt;

&lt;p&gt;It’s about designing a system where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decisions are controlled&lt;/li&gt;
&lt;li&gt;Execution is efficient&lt;/li&gt;
&lt;li&gt;Behavior is predictable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re building AI-powered applications, focus less on “what the model can do”&lt;br&gt;
and more on &lt;strong&gt;how your system controls it&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Future Improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add conversation memory (persistent context)&lt;/li&gt;
&lt;li&gt;Integrate vector search for better recommendations&lt;/li&gt;
&lt;li&gt;Introduce performance metrics (latency, tool-call rate)&lt;/li&gt;
&lt;li&gt;Optimize system for real-world scaling&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  12. Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project pushed me beyond just using LLMs —&lt;br&gt;
it helped me think like an engineer designing systems around them.&lt;/p&gt;

&lt;p&gt;And that’s where real value comes from.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llm</category>
      <category>webdev</category>
    </item>
    <item>
      <title>From MediaPipe to Adaptive AI: Building Mendly's Rehab CV Pipeline</title>
      <dc:creator>Quoc Bao An Nguyen</dc:creator>
      <pubDate>Wed, 30 Sep 2026 21:42:46 +0000</pubDate>
      <link>https://dev.to/jasonpg/how-our-top-11-hophacks-project-turned-noisy-mediapipe-pose-data-into-reliable-rehabilitation-411d</link>
      <guid>https://dev.to/jasonpg/how-our-top-11-hophacks-project-turned-noisy-mediapipe-pose-data-into-reliable-rehabilitation-411d</guid>
      <description>&lt;h1&gt;
  
  
  How our Top 11 HopHacks project turned noisy MediaPipe pose data into reliable rehabilitation metrics for adaptive AI planning
&lt;/h1&gt;

&lt;p&gt;What if a rehabilitation exercise could understand &lt;strong&gt;how&lt;/strong&gt; a patient moved, instead of only knowing whether they finished?&lt;/p&gt;

&lt;p&gt;That was one of the ideas behind &lt;strong&gt;Mendly&lt;/strong&gt;, an AI-powered stroke rehabilitation platform my team built during HopHacks.&lt;/p&gt;

&lt;p&gt;By the end of the hackathon, Mendly became a &lt;strong&gt;Top 11 finalist out of 87 projects&lt;/strong&gt; and won &lt;strong&gt;Best Use of DigitalOcean&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I worked mainly on the computer vision side of the project: pose tracking, joint-angle and range-of-motion measurement, valid-repetition detection, tracking reliability, and the pipeline that turns movement into structured performance data for adaptive AI planning.&lt;/p&gt;

&lt;p&gt;Our core flow looked roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Camera
  ↓
MediaPipe Pose
  ↓
Joint Angles / Range of Motion
  ↓
Repetition Validation
  ↓
Structured Performance Data
  ↓
Future AI Planning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interesting part was not simply getting MediaPipe to detect a person.&lt;/p&gt;

&lt;p&gt;It was figuring out when we should actually &lt;strong&gt;trust&lt;/strong&gt; what the camera was telling us.&lt;/p&gt;




&lt;h2&gt;
  
  
  Missing tracking should stay missing
&lt;/h2&gt;

&lt;p&gt;One bug changed how I thought about computer vision.&lt;/p&gt;

&lt;p&gt;Suppose the tracker sees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frame 1: 40°
Frame 2: 55°
Frame 3: tracking fails
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What should Frame 3 become?&lt;/p&gt;

&lt;p&gt;At first, two obvious choices are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use &lt;code&gt;0°&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;reuse the previous &lt;code&gt;55°&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are wrong.&lt;/p&gt;

&lt;p&gt;If tracking failed, we do not know where the patient's arm actually was.&lt;/p&gt;

&lt;p&gt;Using zero invents movement. Reusing the old value assumes the patient stopped moving.&lt;/p&gt;

&lt;p&gt;So we changed failed inference into an explicit &lt;strong&gt;invalid observation&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pose succeeds
→ process measurement

Pose fails
→ ignore the observation
→ do not update movement state
→ do not count a repetition
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rule became:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Unknown is not zero. Unknown stays unknown.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds simple, but it prevented missing camera evidence from becoming fake movement data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Counting reps is more than crossing a threshold
&lt;/h2&gt;

&lt;p&gt;Another challenge was repetition detection.&lt;/p&gt;

&lt;p&gt;Real movement data does not look perfectly clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;155°
148°
139°
121°
97°
76°
81°
95°
119°
142°
151°
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we count a repetition every time an angle crosses a threshold, noise or partial motion can create false reps.&lt;/p&gt;

&lt;p&gt;Instead, we treated a repetition as a full movement cycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
  ↓
Movement begins
  ↓
Required range reached
  ↓
Optional hold
  ↓
Return
  ↓
Valid repetition
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also helped us separate &lt;strong&gt;attempts&lt;/strong&gt; from &lt;strong&gt;valid repetitions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At one point, an exercise could finish after enough failed attempts even if the patient had not reached the required number of valid reps.&lt;/p&gt;

&lt;p&gt;We changed that so automatic completion depends only on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;validRepCount &amp;gt;= targetRepCount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the target is five valid reps, the patient needs five valid reps.&lt;/p&gt;

&lt;p&gt;Failed attempts can still be recorded, but they do not magically complete the exercise.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recorded data is not always trusted data
&lt;/h2&gt;

&lt;p&gt;We ran into the same distinction with range-of-motion measurements.&lt;/p&gt;

&lt;p&gt;A patient might complete an attempt while tracking confidence is poor.&lt;/p&gt;

&lt;p&gt;That attempt can still be useful as history, but its movement measurement should not automatically become trusted ROM data.&lt;/p&gt;

&lt;p&gt;So we separated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did an attempt happen?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Do we trust the measurement?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Low-confidence repetitions could remain in the result history while being excluded from trusted movement statistics.&lt;/p&gt;

&lt;p&gt;That ended up being one of the most important ideas in the project:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Recorded does not necessarily mean reliable.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The LLM never sees the raw video
&lt;/h2&gt;

&lt;p&gt;One architectural decision I liked about Mendly was keeping computer vision separate from AI reasoning.&lt;/p&gt;

&lt;p&gt;Gemini does not inspect the patient's camera feed or count repetitions.&lt;/p&gt;

&lt;p&gt;The CV layer converts movement into structured performance information first.&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 json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exercise"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arm_flexion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"attempts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"valid_repetitions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"range_of_motion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;83&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tracking_quality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"good"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The computer vision layer answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What happened?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI planning layer answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How should that performance influence a future exercise set?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The patient's current session still follows a practitioner-approved plan.&lt;/p&gt;

&lt;p&gt;When a future set is drafted, Mendly uses &lt;strong&gt;Backboard and Gemini&lt;/strong&gt; with practitioner-defined constraints and accumulated performance data.&lt;/p&gt;

&lt;p&gt;The proposal then goes through deterministic guardrails and practitioner review before it reaches the patient.&lt;/p&gt;

&lt;p&gt;So the model assists with planning, but it does not autonomously decide treatment in real time.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I took away from the project
&lt;/h2&gt;

&lt;p&gt;Before Mendly, it was easy for me to think about computer vision as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;input → model → prediction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After debugging this system, I started thinking more about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;input
  ↓
prediction
  ↓
confidence
  ↓
validation
  ↓
structured data
  ↓
application behavior
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model is only one part of the system.&lt;/p&gt;

&lt;p&gt;The engineering around it determines whether its output is actually useful.&lt;/p&gt;

&lt;p&gt;For me, the biggest lesson was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Good AI is not only about better models. It is also about giving those models reliable information to reason over.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That was the most interesting part of building Mendly - and probably the part I learned the most from.&lt;/p&gt;

</description>
      <category>computervision</category>
      <category>ai</category>
      <category>webdev</category>
      <category>hackathon</category>
    </item>
  </channel>
</rss>
