Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cited-memo

An AI-drafted investment memo where every number shows its working.

AI writes a plausible investment memo in seconds. The problem is the next hour, where an associate re-checks every figure against the data room because nobody can tell which numbers came from the accounts and which the model invented. That verification cost is why most AI drafting tools quietly stop being used after week three.

This tool inverts it. It drafts from source documents only, cites the exact page behind every figure, and then grades its own output:

traceable figures : 24/26  (92%)
invalid citations : 0
unsupported claims: 2
  - EBITDA margin of 18% is expected to hold through FY26.
  - Management estimates a further £400k of synergies.

Two uncited claims, surfaced by name. That is the whole point: you check two sentences instead of twenty-six.


How it works

  1. Extract: every page of every PDF in a folder becomes a numbered passage tagged with its document and page number.
  2. Draft: the model writes the memo from those passages only, and must follow each figure with the citation it came from, like [3].
  3. Verify: this is the part that matters, and it runs offline with no API key. It finds every figure in the draft, checks whether the sentence containing it cites a real passage, and reports coverage.

Verification catches three separate failures: a number with no citation, a citation pointing at a passage that does not exist, and a claim asserted without evidence.

Use

pip install -r requirements.txt

# extract, draft, verify, write a Word file
export ANTHROPIC_API_KEY=...
python cited_memo.py draft ./filings --out memo.docx

# verify a draft that already exists, no API key needed
python cited_memo.py check memo.md --sources ./filings

--out memo.md writes markdown instead. Both formats append a Sources table mapping every citation to its document and page, plus the provenance report.

check exits non-zero if any citation points at a passage that does not exist, so it drops into CI or a pre-send hook.

Run the checks

python test_cited_memo.py

Five assertions covering the cases that matter: cited figures counted, uncited figures flagged, citations to non-existent passages rejected, prose without figures ignored, and multiples/percentages recognised as figures.

Design notes

Page-level citations, not span-level. A page is small enough to check a number against in a few seconds and large enough to survive imperfect PDF text extraction. Span-level citation looks more precise and breaks more often.

Attribution is sentence-scoped. A figure counts as traceable if its sentence cites a real passage. That is good enough to catch an uncited number, which is the actual failure mode. Marked in the source where it would need to change.

Coverage is a number, not a claim. "AI-assisted, human-verified" means nothing. 92% traceable, with the other 8% named, means something.

Stack

Python, pypdf for extraction, the Anthropic API for drafting, python-docx for Word output. No framework.

Why it exists

I write investment memos and run buy-side diligence for PE funds. The bottleneck was never the writing.

About

AI-drafted investment memos where every figure cites its source page, and the tool grades its own provenance. Verification runs offline.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages