<?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: Maganti parthive</title>
    <description>The latest articles on DEV Community by Maganti parthive (@maganti_parthive_dd3f77cd).</description>
    <link>https://dev.to/maganti_parthive_dd3f77cd</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%2F4075127%2F9a33f110-fa3e-40c9-a251-ddbae7056fc3.png</url>
      <title>DEV Community: Maganti parthive</title>
      <link>https://dev.to/maganti_parthive_dd3f77cd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maganti_parthive_dd3f77cd"/>
    <language>en</language>
    <item>
      <title>MRS MILLE</title>
      <dc:creator>Maganti parthive</dc:creator>
      <pubDate>Wed, 12 Aug 2026 17:34:51 +0000</pubDate>
      <link>https://dev.to/maganti_parthive_dd3f77cd/mrs-mille-4f8i</link>
      <guid>https://dev.to/maganti_parthive_dd3f77cd/mrs-mille-4f8i</guid>
      <description>&lt;p&gt;I Built an Agricultural Agent That Treats Field History as Memory&lt;/p&gt;

&lt;p&gt;Most agricultural software is very good at answering a question about the field in front of it. The harder problem is answering the next question without forgetting everything that happened before.&lt;/p&gt;

&lt;p&gt;That is the problem I built MRS MILLE around. It is an agricultural agent that keeps a longitudinal memory of a farmer and field, then uses that history when making the next recommendation. The interesting part is not storing conversations. It is making past actions and outcomes affect future decisions.&lt;/p&gt;

&lt;p&gt;What MRS MILLE actually does&lt;/p&gt;

&lt;p&gt;MRS MILLE combines structured field data, agricultural observations, an LLM, and Hindsight as a long-term memory layer.&lt;/p&gt;

&lt;p&gt;The basic flow is:&lt;/p&gt;

&lt;p&gt;Farmer question&lt;br&gt;
      |&lt;br&gt;
      v&lt;br&gt;
Current field conditions&lt;br&gt;
      |&lt;br&gt;
      +------&amp;gt; Hindsight recall&lt;br&gt;
      |              |&lt;br&gt;
      |              v&lt;br&gt;
      |       Previous experiences&lt;br&gt;
      |       Farmer actions&lt;br&gt;
      |       Outcomes&lt;br&gt;
      |       Learned observations&lt;br&gt;
      |&lt;br&gt;
      v&lt;br&gt;
Agricultural reasoning&lt;br&gt;
      |&lt;br&gt;
      v&lt;br&gt;
Recommendation&lt;br&gt;
      |&lt;br&gt;
      v&lt;br&gt;
Farmer action&lt;br&gt;
      |&lt;br&gt;
      v&lt;br&gt;
Outcome&lt;br&gt;
      |&lt;br&gt;
      +------&amp;gt; Hindsight retain&lt;/p&gt;

&lt;p&gt;I use Hindsight because I don't want the memory layer to be just another database table. Its job is to retrieve relevant experience and help consolidate observations from that experience.&lt;/p&gt;

&lt;p&gt;I keep Hindsight behind a dedicated memory service, so the rest of the application does not depend on its API directly.&lt;/p&gt;

&lt;p&gt;The service starts with a simple rule:&lt;/p&gt;

&lt;p&gt;@staticmethod&lt;br&gt;
def _bank(farmer_id: str) -&amp;gt; str:&lt;br&gt;
    if not farmer_id or not str(farmer_id).strip():&lt;br&gt;
        raise ValueError("farmer_id is required for memory isolation")&lt;br&gt;
    return f"mrsmille-farmer-{_slug(str(farmer_id))}"&lt;/p&gt;

&lt;p&gt;I deliberately make the farmer identity part of the Hindsight bank ID. Memory isolation is structural rather than something I expect every query to remember to enforce.&lt;/p&gt;

&lt;p&gt;Within that bank, field, crop, season, and event information is represented with tags.&lt;/p&gt;

&lt;p&gt;That gives me two levels of scope:&lt;/p&gt;

&lt;p&gt;Farmer&lt;br&gt;
  └── Hindsight bank&lt;br&gt;
       ├── Field F001&lt;br&gt;
       │    ├── crop&lt;br&gt;
       │    ├── symptoms&lt;br&gt;
       │    ├── recommendations&lt;br&gt;
       │    └── outcomes&lt;br&gt;
       └── Field F002&lt;/p&gt;

&lt;p&gt;The same farmer can therefore have two fields with different histories.&lt;/p&gt;

&lt;p&gt;Why I chose Hindsight instead of treating memory as CRUD&lt;/p&gt;

&lt;p&gt;I originally thought of memory as something simple: save the farmer's previous messages and retrieve them later.&lt;/p&gt;

&lt;p&gt;That approach breaks down quickly.&lt;/p&gt;

&lt;p&gt;Suppose a farmer says:&lt;/p&gt;

&lt;p&gt;"The leaves turned yellow last time."&lt;/p&gt;

&lt;p&gt;The useful information is not necessarily the sentence itself. I want the system to connect the symptom to the conditions around it, the advice that was given, what the farmer actually did, and what happened afterward.&lt;/p&gt;

&lt;p&gt;So I model an agricultural episode as:&lt;/p&gt;

&lt;p&gt;Condition&lt;br&gt;
   ↓&lt;br&gt;
Symptom&lt;br&gt;
   ↓&lt;br&gt;
Recommendation&lt;br&gt;
   ↓&lt;br&gt;
Farmer action&lt;br&gt;
   ↓&lt;br&gt;
Outcome&lt;/p&gt;

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

&lt;p&gt;Heavy rainfall&lt;br&gt;
   ↓&lt;br&gt;
Leaf yellowing&lt;br&gt;
   ↓&lt;br&gt;
Check drainage before adding water&lt;br&gt;
   ↓&lt;br&gt;
Farmer clears drainage&lt;br&gt;
   ↓&lt;br&gt;
Crop recovers&lt;/p&gt;

&lt;p&gt;Hindsight is the part of the system that lets me retain these experiences and later recall them by meaning and context. The Hindsight agent memory documentation is useful here because the API is built around retaining information, recalling relevant memories, and reflecting over them rather than treating memory as a passive log.&lt;/p&gt;

&lt;p&gt;I also use Hindsight's agent memory architecture as the conceptual model for separating ordinary application state from longer-lived agent experience.&lt;/p&gt;

&lt;p&gt;The memory service is intentionally boring&lt;/p&gt;

&lt;p&gt;One design decision I am happy with is that the Hindsight integration itself is not spread across the application.&lt;/p&gt;

&lt;p&gt;The memory service owns the integration:&lt;/p&gt;

&lt;p&gt;async def recall_field(&lt;br&gt;
    self,&lt;br&gt;
    farmer_id: str,&lt;br&gt;
    field_id: str,&lt;br&gt;
    query: str,&lt;br&gt;
    *,&lt;br&gt;
    budget: str = "mid",&lt;br&gt;
    types: Optional[list[str]] = None,&lt;br&gt;
) -&amp;gt; list[Memory]:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resp = await self._client.arecall(
    bank_id=self._bank(farmer_id),
    query=query,
    tags=[f"field:{_slug(field_id)}"],
    tags_match="all",
    types=types,
    budget=budget,
    max_tokens=4096,
)

return _normalise_recall(resp)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The important line here is not the API call itself. It is the field scope:&lt;/p&gt;

&lt;p&gt;tags=[f"field:{_slug(field_id)}"],&lt;br&gt;
tags_match="all",&lt;/p&gt;

&lt;p&gt;The application can ask, "What happened when this field had a similar problem?" without accidentally pulling memories from another field.&lt;/p&gt;

&lt;p&gt;The other half of the system is reflection. Recall gives me evidence. Reflection is where I ask Hindsight to reason over the field's history alongside today's conditions.&lt;/p&gt;

&lt;p&gt;resp = await self._client.areflect(&lt;br&gt;
    bank_id=self._bank(farmer_id),&lt;br&gt;
    query=question,&lt;br&gt;
    context=context,&lt;br&gt;
    tags=[f"field:{_slug(field_id)}"],&lt;br&gt;
    tags_match="all",&lt;br&gt;
    budget=budget,&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;I explicitly pass current conditions into the reflection context.&lt;/p&gt;

&lt;p&gt;That is important because old memory should not automatically win.&lt;/p&gt;

&lt;p&gt;If a field historically needed irrigation during a dry period, that does not mean I should recommend irrigation today when the field has just received heavy rain.&lt;/p&gt;

&lt;p&gt;The current state has to be allowed to override stale history.&lt;/p&gt;

&lt;p&gt;I don't store every conversation&lt;/p&gt;

&lt;p&gt;Another decision I made was to avoid dumping raw chat history into memory.&lt;/p&gt;

&lt;p&gt;The memory service has explicit event types:&lt;/p&gt;

&lt;p&gt;class EventType(str, Enum):&lt;br&gt;
    PROFILE = "profile"&lt;br&gt;
    PREFERENCE = "preference"&lt;br&gt;
    SYMPTOM = "symptom"&lt;br&gt;
    CONDITION = "condition"&lt;br&gt;
    RECOMMENDATION = "recommendation"&lt;br&gt;
    ACTION = "action"&lt;br&gt;
    OUTCOME = "outcome"&lt;br&gt;
    NOTE = "note"&lt;/p&gt;

&lt;p&gt;That vocabulary gives the application a useful mental model.&lt;/p&gt;

&lt;p&gt;A farmer saying "I prefer Telugu" is a preference.&lt;/p&gt;

&lt;p&gt;A farmer saying "I cleared the drainage channel" is an action.&lt;/p&gt;

&lt;p&gt;The later statement "the crop recovered" is an outcome.&lt;/p&gt;

&lt;p&gt;And the recommendation itself is an agent experience.&lt;/p&gt;

&lt;p&gt;That distinction becomes especially useful when the system has to answer questions such as:&lt;/p&gt;

&lt;p&gt;"Did the previous recommendation actually work?"&lt;/p&gt;

&lt;p&gt;The one-year field story&lt;/p&gt;

&lt;p&gt;I use a twelve-month history to exercise the memory system.&lt;/p&gt;

&lt;p&gt;The dataset contains 108 events spanning August 2025 through July 2026, including conditions, symptoms, recommendations, actions, outcomes, recurring problems, and irrigation changes.&lt;/p&gt;

&lt;p&gt;The important part is that the timeline contains conflicting contexts.&lt;/p&gt;

&lt;p&gt;Earlier in the year, the field experiences moisture stress and later recovery after irrigation.&lt;/p&gt;

&lt;p&gt;Later, heavy rainfall creates high soil moisture and temporary waterlogging.&lt;/p&gt;

&lt;p&gt;Those two situations deliberately look similar at the symptom level but require different reasoning.&lt;/p&gt;

&lt;p&gt;That gives MRS MILLE a useful question to answer:&lt;/p&gt;

&lt;p&gt;"The leaves are yellow again. Should I do what I did last time?"&lt;/p&gt;

&lt;p&gt;A conventional assistant might anchor on the previous intervention.&lt;/p&gt;

&lt;p&gt;MRS MILLE should instead retrieve the previous episode, inspect the current conditions, and explain the difference.&lt;/p&gt;

&lt;p&gt;The intended answer is along these lines:&lt;/p&gt;

&lt;p&gt;The field has experienced yellowing before, but the conditions&lt;br&gt;
are not identical.&lt;/p&gt;

&lt;p&gt;Earlier, yellowing occurred during low-moisture stress and the&lt;br&gt;
crop recovered after irrigation.&lt;/p&gt;

&lt;p&gt;A later event followed heavy rainfall and high soil moisture,&lt;br&gt;
where waterlogging became the more relevant explanation.&lt;/p&gt;

&lt;p&gt;Today's readings should determine which historical pattern is&lt;br&gt;
actually comparable before recommending another intervention.&lt;/p&gt;

&lt;p&gt;That is the behavior I care about. Memory is useful because it changes the reasoning, not because it makes the UI look more sophisticated.&lt;/p&gt;

&lt;p&gt;Making memory visible without exposing chain-of-thought&lt;/p&gt;

&lt;p&gt;I wanted the user to be able to answer a simple question:&lt;/p&gt;

&lt;p&gt;Why did MRS MILLE tell me this?&lt;/p&gt;

&lt;p&gt;A response can show:&lt;/p&gt;

&lt;p&gt;MEMORIES USED&lt;/p&gt;

&lt;p&gt;Previous symptom&lt;br&gt;
Leaf yellowing after heavy rainfall&lt;/p&gt;

&lt;p&gt;Previous action&lt;br&gt;
Farmer cleared the drainage channel&lt;/p&gt;

&lt;p&gt;Previous outcome&lt;br&gt;
Crop recovered in four days&lt;/p&gt;

&lt;p&gt;Learned pattern&lt;br&gt;
This field has experienced yellowing under waterlogged&lt;br&gt;
conditions before&lt;/p&gt;

&lt;p&gt;Current condition&lt;br&gt;
Soil moisture 31%, no rain forecast&lt;/p&gt;

&lt;p&gt;Then the recommendation can say:&lt;/p&gt;

&lt;p&gt;"Check drainage first before adding water or nitrogen."&lt;/p&gt;

&lt;p&gt;I am not exposing the model's private chain-of-thought. I am showing the evidence that materially influenced the decision.&lt;/p&gt;

&lt;p&gt;The application layer stays small&lt;/p&gt;

&lt;p&gt;The FastAPI layer is intentionally thin.&lt;/p&gt;

&lt;p&gt;The question endpoint does three important things: retrieve relevant memories, generate the memory-informed recommendation, and return the memories used for provenance.&lt;/p&gt;

&lt;p&gt;memories = await memory.recall_field(&lt;br&gt;
    req.farmer_id,&lt;br&gt;
    req.field_id,&lt;br&gt;
    req.question,&lt;br&gt;
    types=["world", "experience", "observation"],&lt;br&gt;
    budget="mid",&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;answer = await memory.recommend(&lt;br&gt;
    req.farmer_id,&lt;br&gt;
    req.field_id,&lt;br&gt;
    req.question,&lt;br&gt;
    current_conditions=req.current_conditions,&lt;br&gt;
    budget="high",&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;This separation makes the architecture easier to reason about:&lt;/p&gt;

&lt;p&gt;FastAPI&lt;br&gt;
  |&lt;br&gt;
  +-- structured application state&lt;br&gt;
  |&lt;br&gt;
  +-- Hindsight memory service&lt;br&gt;
          |&lt;br&gt;
          +-- Retain&lt;br&gt;
          +-- Recall&lt;br&gt;
          +-- Reflect&lt;/p&gt;

&lt;p&gt;The frontend does not need to know how Hindsight works.&lt;/p&gt;

&lt;p&gt;It only needs to know that an answer has supporting memories and that those memories belong to the current field.&lt;/p&gt;

&lt;p&gt;What a real interaction looks like&lt;/p&gt;

&lt;p&gt;Imagine Ravi returns to the application several months after an earlier crop problem.&lt;/p&gt;

&lt;p&gt;He asks:&lt;/p&gt;

&lt;p&gt;"Did this field have yellowing before?"&lt;/p&gt;

&lt;p&gt;MRS MILLE can answer from the historical record.&lt;/p&gt;

&lt;p&gt;He asks:&lt;/p&gt;

&lt;p&gt;"What happened after that?"&lt;/p&gt;

&lt;p&gt;Now the agent follows the previous event into the action and outcome.&lt;/p&gt;

&lt;p&gt;He asks:&lt;/p&gt;

&lt;p&gt;"What did I do?"&lt;/p&gt;

&lt;p&gt;The answer comes from the farmer action memory.&lt;/p&gt;

&lt;p&gt;Finally:&lt;/p&gt;

&lt;p&gt;"Why are you giving me different advice today?"&lt;/p&gt;

&lt;p&gt;That is where the system becomes more interesting. MRS MILLE can compare the previous event with current conditions and explain why the old intervention is not automatically appropriate.&lt;/p&gt;

&lt;p&gt;The same history can be reached through different phrasing, such as "When did I change the irrigation?" or "Wasn't this field using flood irrigation before?" The production question layer resolves those variations to the same intent and retrieves the underlying history rather than relying on a hardcoded question list.&lt;/p&gt;

&lt;p&gt;The uncomfortable part: memory can be wrong&lt;/p&gt;

&lt;p&gt;Persistent memory creates a new class of bugs.&lt;/p&gt;

&lt;p&gt;A stateless assistant can be wrong about today's answer. A memory-enabled assistant can be confidently wrong because it has an old fact available.&lt;/p&gt;

&lt;p&gt;I therefore treat temporal relevance as part of the reasoning problem.&lt;/p&gt;

&lt;p&gt;The Hindsight bank is configured with temporal retrieval enabled, and the reflection mission explicitly tells the system to prefer newer reliable information when memories conflict.&lt;/p&gt;

&lt;p&gt;The principle is simple:&lt;/p&gt;

&lt;p&gt;Old memory + current evidence&lt;br&gt;
        ↓&lt;br&gt;
      compare&lt;br&gt;
        ↓&lt;br&gt;
same context?&lt;br&gt;
   /          \&lt;br&gt;
 yes           no&lt;br&gt;
 ↓             ↓&lt;br&gt;
reuse       reconsider&lt;/p&gt;

&lt;p&gt;This is more important than maximizing the amount of information stored.&lt;/p&gt;

&lt;p&gt;What I learned building it&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Long-term memory is a data-modeling problem before it is an LLM problem&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The useful unit is not a conversation. It is an experience: condition, decision, action, and outcome.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Isolation needs to happen at the architecture boundary&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I don't want to rely on developers remembering farmer_id on every query. The farmer determines the Hindsight bank; the field determines the tag scope.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Current state must be first-class&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Historical memory is powerful precisely because it can become stale.&lt;/p&gt;

&lt;p&gt;I pass today's field conditions directly into reflection and tell the system to weigh current readings above older memories when they conflict.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Memory provenance is part of the product&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If a recommendation changes because of history, the user should be able to see which historical facts mattered.&lt;/p&gt;

&lt;p&gt;"Trust me, I remember" is not a useful interface.&lt;/p&gt;

&lt;p&gt;"Here are the three previous events that changed today's recommendation" is much better.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A good memory system should make the agent less repetitive, not merely more verbose&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The goal is not for MRS MILLE to mention the farmer's past in every answer.&lt;/p&gt;

&lt;p&gt;The goal is selective recall.&lt;/p&gt;

&lt;p&gt;If history is relevant, use it. If it isn't, don't force it into the response.&lt;/p&gt;

&lt;p&gt;That is the line I keep coming back to with agent memory: the system should remember more than it says.&lt;/p&gt;

&lt;p&gt;Where I would take it next&lt;/p&gt;

&lt;p&gt;The next layer I would invest in is evaluation: the same agricultural question expressed in many ways, across English and Telugu, with temporal references such as "last time", "earlier this year", and "after the rain". I want to measure both retrieval quality and whether the recommendation actually changes when relevant history changes.&lt;/p&gt;

&lt;p&gt;I would also test contradictory memories deliberately. A farmer's irrigation method can change, a field can change crops, and a previously successful intervention can stop being appropriate. Those are not edge cases in a longitudinal system. They are the system.&lt;/p&gt;

&lt;p&gt;MRS MILLE started as an agricultural question-and-answer application. The more interesting architecture emerged when I stopped treating history as a log and started treating it as experience.&lt;/p&gt;

&lt;p&gt;The core loop is now simple:&lt;/p&gt;

&lt;p&gt;Remember what happened.&lt;br&gt;
Recall what matters.&lt;br&gt;
Compare it with what is happening now.&lt;br&gt;
Make a decision.&lt;br&gt;
Remember the outcome.&lt;/p&gt;

&lt;p&gt;That is the part I would build on.&lt;/p&gt;

&lt;p&gt;For engineers interested in the underlying memory system, the Hindsight GitHub repository, Hindsight documentation, and agent memory overview from Vectorize are the places I would start.&lt;/p&gt;

</description>
      <category>agriculture</category>
      <category>runnerhchallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
