STEPHANIE SARKAR
INSTITUTIONAL REAL ESTATE
Selected writing

Writings

Notes on portfolio management systems, institutional real estate organizations, and the practical work of applying AI.

Applied AI · Field Note 03

Building the First Tool in an AI Portfolio Management System

Translating one step of quarterly investor reporting into a repeatable technical workflow.

1. Why I did it

Leading a company sometimes requires getting close to the work—not to replace the specialists, but to understand the process well enough to lead it thoughtfully.

In my work at Front Office Labs, our Head of AI and technical team build the AI systems. My background is in institutional real estate. I undertook this exercise to understand firsthand how a real portfolio-management workflow becomes a functioning AI/technical tool. I worked with the AI team on this - starting with: what must be defined, translated, tested, and refined along the way.

My result is a real portfolio-management task translated into technical instructions and built into a working tool for one our family office clients. The work below represents one of 40+ tools that were implemented and are still in-use for this family.

2. Mapping the full portfolio management function first

We’d already mapped the portfolio-management function—the recurring work, what it runs on, the judgment calls it involves, and what investment committees, family principals, and senior management expect to see. From that map I picked one recurring workflow: the quarterly investor report.

3. Break the workflow into steps

Like all workflows in institutional real estate, producing a high-quality quarterly report is a chain of many small tasks and subtasks, each with its own inputs, controls, and stakes:

Quarterly reporting workflowEight linked steps
  1. Gather the current-quarter materialsBring together rent rolls, Yardi financials, loan documents, current valuations, and other reporting-period evidence.
  2. Identify and categorize the filesDetermine what each file is so the system can route it to the correct extraction rules, validation checks, and downstream steps.Selected for this build
  3. Extract the relevant informationRead the defined fields needed from each document type to support the quarterly report.
  4. Validate against other sourcesCompare overlapping facts across documents and surface differences for review.
  5. Investigate inconsistenciesThe portfolio manager resolves discrepancies with the property or asset manager and documents the answer.
  6. Populate the quarterly reportMove approved current-quarter figures into the appropriate report fields.
  7. Draft commentaryDevelop clear explanations of performance, material changes, and emerging risks.
  8. Review and approveThe portfolio manager reviews the complete report from top to bottom before it is issued.
→

Why this matters: To a portfolio manager, labeling a rent roll as a rent roll can feel almost pointless—the document is recognizable at a glance. A computer does not begin with that context. It must first know what kind of document it is looking at before it can know which information to extract, what to compare it against, or where that information belongs in the report.

That classification tells the computer how to treat the file from that point forward and determines every subsequent step. A folder with all of the files needed for a quarterly report may contain hundreds of files, with each property or asset manager using different naming conventions for all of their submissions.

In many cases, "what" the file is cannot be identified from its name or format alone; it has to be opened and read. That takes time a mental bandwidth away from a portfolio manager who is digging around in the folder looking for a loan agreement at a particular property.

Classifying the files at the outset saves that manual effort later and gives every downstream tool the instructions it needs to process each file correctly.

4. Build the first tool

The tool reviews the current-quarter folder and categorizes its contents. Those contents may include:

A · Rent Roll
B · Prior Q rent roll
C · Signed Loan Agreement
D · Mortgage Statement
E · Fixed property data
F · Valuation file
G · Prior Q valuation file
H · Financial statement
I · Prior Q financial statement
J · Last quarter’s report
K · Email
L · Brokerage report
M · Other

Even this simple-looking step involves real judgment. File names aren’t consistent, and formats vary across property managers, operating partners, assets, and reporting periods—a spreadsheet might have half a dozen tabs, a PDF might be scanned, an email screenshot might carry a real update with no useful metadata attached to it at all.

So the system can’t rely on filenames—it has to look inside the file and recognize what a document actually looks like. A portfolio manager can spot a rent roll almost on sight. But without categorizing and re-naming files, a portfolio manager might need to open a lot of different files before they find the rent roll they specically need.

Making that recognition repeatable means spelling out what the code (or in this case, AI harness) is actually looking for: tenant or unit identifiers, lease dates, square footage, rental amounts, and how those fields relate to each other. This info is used to determine the most liekly file type and property type.

5. The actual build

Here is the working version, reduced only to remove internal paths and client information. The sequence is straightforward: validate the file, convert its contents to Markdown, combine that content with a tightly bounded system prompt, and send both to the model at temperature zero.

Security note. The API key never appears in the script. It is stored as an environment variable named GROQ_API_KEY. The public example also uses a generic filename rather than an internal folder structure.

Python · validate and convert the source file
from pathlib import Path
from markitdown import MarkItDown

SUPPORTED = {".pdf", ".xlsx", ".pptx", ".docx", ".md"}

def convert_to_markdown(file_path: str) -> str:
    path = Path(file_path)
    if not path.is_file():
        raise FileNotFoundError(path)
    if path.suffix.lower() not in SUPPORTED:
        raise ValueError(f"Unsupported file type: {path.suffix}")
    if path.suffix.lower() == ".md":
        return path.read_text(encoding="utf-8")
    return MarkItDown().convert(str(path)).text_content

The conversion step gives the model the document’s actual contents, not just its filename. For a spreadsheet, that means labels, tabular fields, values, and sheet context become readable text.

The actual system prompt · fol_file_categorizer.md
Categorize the following content into one of the following file categories:

A) Rent Roll
B) Prior Q rent roll
C) Signed Loan Agreement
D) Mortgage Statement
E) Fixed property data
F) Valuation file
G) Prior Q valuation file
H) Financial statement
I) Prior Q financial statement
J) Last quarter’s report
K) Email
L) Brokerage report
M) Other

Return only the file category and nothing else.

This was the complete prompt for the first prototype. Its job was deliberately narrow: force the model to choose one label from a fixed list. It did not yet produce confidence scores, supporting evidence, or exception flags.

Python · make the bounded model call
import os
from groq import Groq

def classify(markdown: str, prompt_path: str) -> str:
    api_key = os.environ["GROQ_API_KEY"]
    system_prompt = Path(prompt_path).read_text(encoding="utf-8")
    client = Groq(api_key=api_key)
    response = client.chat.completions.create(
        model=os.getenv("GROQ_MODEL", "openai/gpt-oss-120b"),
        temperature=0,
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": markdown},
        ],
    )
    return response.choices[0].message.content
Terminal · run it on one file
python test.py sample_rent_roll.xlsx \
  --prompt fol_file_categorizer.md

For an illustrative office rent roll, the response looks like this:

Plain text · model response
A) Rent Roll
Code handles
File existence, supported format, content conversion, prompt loading and credential handling
Model handles
Choosing one category from the prompt’s fixed A–M taxonomy
Portfolio manager handles
Checking the classification and deciding whether the source is fit for downstream use
Prototype returns
One plain-text category label—and nothing else

This is intentionally not “upload a folder and ask AI to write the report.” It is one inspectable component with a defined input and constrained output. The limitations are equally visible: the first version does not explain its answer or identify uncertainty. A production version should add structured output, evidence, an exception path, source-file and prompt-version logging, and tests against a labeled document set before downstream use.

6. Where it fits

The file-classification tool is one small component of a larger system:

Quarterly reporting workflow
Quarterly reporting tool sequenceFiles are classified, information is extracted, data is validated, exceptions are reviewed, and approved information is placed into report fields.01 · CLASSIFY FILES02 · EXTRACT DATA03 · VALIDATE04 · REVIEW EXCEPTIONS05 · POPULATE FIELDSOrganize the evidenceRead defined fieldsReconcile sourcesPortfolio managerApproved information

This first tool isn’t producing the quarterly report itself. It’s setting up an organized, traceable input layer that later tools can build on—the layer that ties every extracted fact, and eventually every conclusion, back to a specific source.

7. What I learned

The exercise made several principles of institutional AI implementation more concrete:

01

The hardest part is defining the work precisely. Coding doesn’t start until the objective, the evidence, the classifications, the edge cases, and what counts as an acceptable output are all spelled out.

02

A workflow that looks obvious is full of implicit decisions. Experienced portfolio managers resolve inconsistencies without even noticing; a system needs those judgment calls pulled out into the open.

03

File classification establishes provenance—it’s not paperwork, it’s the foundation. Every extraction, variance, and written conclusion downstream should trace back to an identifiable source.

04

Reliable automation depends on narrow, testable components. A bounded tool can be checked, corrected, and supervised in a way an open-ended request never can.

05

Domain experts and engineers need a shared way of describing the process. Workflow maps, classification rules, expected fields, and exception paths are what give them a common language.

06

Executive leaders need real technical fluency. Not enough to build every tool themselves, but enough to tell a demo apart from something that can actually run as an institutional operating system.

If there’s one lesson that keeps showing up, it’s that reliability comes less from the model and more from what’s built around it: narrow scope, explicit rules, traceable evidence, visible uncertainty, human approval.

8. What comes next

  • The next tool extracts defined information from each file.
  • Later components validate and reconcile the extracted information across conflicting sources.
  • Approved data can eventually populate defined fields within the quarterly report.
  • The portfolio manager remains responsible for interpretation, materiality, and final communication.

The system gets built from the function outward, one narrow and accountable piece at a time.