Python tools, project workflows, and delegated research
Models can be accessed through a browser or an application programming interface (API). An API lets a Python program send prompts and receive responses. chatlas handles this communication and maintains the conversation.
Python program
Provider’s API
Model
Response
Requires an API credential. Setup instructions are in the reference slides.
A tool is a function made available to the model. The model requests a call and supplies its arguments. The surrounding software executes the function and returns its result.
Illustrative tool display; product checked with Python
Tool request: multiply(20598162, 83106206)
Tool result: 1711835094393372
Python adaptation of Wickham, Your LLM can’t math. chatlas tool calling.
The same mechanism gives a model access to project files. Reading supplies information; writing creates a saved research output.
from pathlib import Path
def read_file(path: str) -> str:
"""Read a UTF-8 text file."""
return Path(path).read_text(encoding="utf-8")
def write_file(path: str, content: str) -> str:
"""Save text to a UTF-8 file."""
Path(path).write_text(content, encoding="utf-8")
return f"Saved {path}"
chat.register_tool(read_file)
chat.register_tool(write_file)Adapted from Wickham, coding-agent tools.
Illustrative execution sequence
read_file("directors.csv").write_file(...) with the summary.An agent uses tools repeatedly, choosing its next action from the results. chatlas handles the tool-calling loop.
Coding agents supply tools for inspecting files, editing code, and running commands. Web tools let them find sources and inspect their contents.
| Tool | Example action |
|---|---|
| Read / list / search files | Locate and inspect directors.csv |
| Write / edit files | Create a Python retrieval script |
| Run a command | Execute the script and inspect its output |
| Web search | Find biographies or genealogy records |
| Web fetch / browser | Open a source and examine its contents |
Write Python
Run it
Inspect the result
Choose the next action
A terminal accepts text commands. The shell interprets them and runs programs. Commands operate from a working directory, which determines where relative paths begin.
director_research/
├── directors.csv
├── director_summary.md
├── sources/
├── code/
└── outputs/
sources/biography.md starts inside the working directory. .. refers to its parent directory. Launching an agent here gives it this workspace.
An agent’s command tool can run the same programs as a person at the terminal. It can inspect output, identify a failure, and decide what to do next.
python is the program; the script path is an argument. > saves printed output to a file, replacing its previous contents.
Give the agent the task
Read directors.csv. Write a Python script that counts directors by firm. Run it, inspect the result, and save the script and a summary under code/ and outputs/.
Find the director’s birth date and spouse in the biography. Save the evidence and add a section on unresolved identities.
| Working document | What the agent needs to do |
|---|---|
| Scanned PDF | Recognize text from page images; check names and dates |
| DOCX or PPTX | Extract text from the document structure; check its order |
| Markdown | Read and search the text directly; edit the relevant section |
Plain text exposes the contents directly to file tools. Markdown expresses headings, links, and code within that text. Changes can be inspected line by line.
Convert PDF, DOCX, and PPTX material into Markdown for the project’s working documentation. Check names, dates, tables, and reading order against the original.
Convert the source documents to Markdown with anydoc. Check the passages containing names and dates against the originals. Identify documents requiring OCR and record extraction problems.
Keep originals for verification. Scanned PDFs require OCR; anydoc reports this by default.
Commands checked against local anydoc --help, 30 September 2026.
Start the agent from the project directory. Claude Code and Codex provide interactive sessions in which an agent can inspect files, run commands, and save work.
Enter a task in the session. Read the response, inspect the files it creates, and continue with follow-up instructions.
Read directors.csv. Summarize the directors, firms, and periods represented in the file. Save the summary to outputs/director_summary.md. Report missing information explicitly and list the files created.
A task specifies the input, objective, and required output. Naming a file makes the work available outside the conversation.
Initial instruction
Summarize the director roster and save it to outputs/director_summary.md.
Follow-up
The period column describes service at the firm, not the person’s lifespan. Revise the summary to make that distinction explicit.
Further instruction
Add a section listing the information needed to distinguish directors with similar names. Base it on the columns actually present in the roster.
Follow-up instructions can correct an interpretation, change the task, or request further work. The agent can revise the saved file in the same session.
CLAUDE.md and AGENTS.md provide project instructions across sessions: commands, research conventions, and output locations.
Save this task as prompts/summarize.md
The requested research file and the agent’s final message are separate outputs.
Starting from a director roster, identify each director’s parents, children, and spouse. Research those relatives’ firm affiliations and record the sources.
Worked row from a demonstration roster
| Director | Birth year | Firm |
|---|---|---|
| Frederik Hendrik Fentener van Vlissingen | 1849 | SHV |
Family relationships
Firm affiliations
Supporting sources
Save separate tables with identities, roles, dates, and source links.
Director and family details. Workflow adapted from the genealogical research in my paper.
Director roster
Source records
Relatives
Affiliations
The agent can write Python for repeated retrieval and table construction. It can also inspect the evidence, change a query, choose another source, and assess identities.
| Repeated operation | Decision after inspecting results |
|---|---|
| Query an API for each director | Which name variant should be tried next? |
| Retrieve linked family records | Does this concern the director or his son? |
| Combine affiliation rows | Does the source establish a directorship or ownership? |
Write Python to search OpenArchieven for the director’s full name. Run it and inspect the candidate records.
import requests
def search_records(name: str) -> dict:
response = requests.get(
"https://api.openarchieven.nl/1.1/"
"records/search.json",
params={"name": name, "number_show": 5},
timeout=30,
)
response.raise_for_status()
return response.json()["response"]
result = search_records(
"Frederik Hendrik Fentener van Vlissingen"
)Saved API response: 71 person mentions
| Event year | Role |
|---|---|
| 1962 | Deceased |
| 1962 | Father |
| 1918 | Deceased |
A person mention is not a distinct individual.
OpenArchieven API query, retrieved 30 September 2026.
Distinguish the director born in 1849 from his son. Compare roles, dates, spouse, and parents. Open the records and save the identity decision with its reasons.
Accepted anchor: marriage in 1879; groom born on 21 September 1849.
Join people to their marriage-record roles
Simon Paulus + Anna Maria Veldhuijs
↓ parents
F.H., born 1849 + Lijntje Roosenburg
↓ son
F.H. (Frits), born 1882
Python extracts recorded relationships. The agent checks identities and investigates conflicting or incomplete links before expanding the family.
Research F.H. Fentener van Vlissingen, born in 1882. Try his full name, Frits, and F.H. with company and role terms. Open the sources. Record supported firms, roles, and dates. Use newly found firms for follow-up searches and keep unresolved questions explicit.
"Frits Fentener van Vlissingen" commissaris
"F.H. Fentener van Vlissingen" Hoogovens
"Frederik Hendrik Fentener van Vlissingen" KLM
Biography: paraphrased evidence
Hoogovens: delegated supervisory director, 1918–1945; chairman of the supervisory board, 1945–1953.
A biography supplies firms and roles that guide subsequent searches. The same task repeats for the other identified relatives.
Supported affiliations of the director’s son, born in 1882
| Firm | Role | Period |
|---|---|---|
| Hoogovens | Delegated supervisory director | 1918–1945 |
| Hoogovens | Chairman of the supervisory board | 1945–1953 |
outputs/
├── identities.md
├── family.csv
├── affiliations.csv
└── unresolved.md
Python combines the saved rows. Notes retain identity decisions and sources.
Relatives whose affiliations have not been established remain unresolved.
Both roles: Biografisch Woordenboek van Nederland. Links are retained with the exported rows.
A research worker receives an objective, input information, and an output location. It chooses searches and follow-up actions from the evidence it finds.
Research the firm affiliations of F.H. Fentener van Vlissingen, born in 1882. Use the identified family record to distinguish namesakes. Choose suitable queries and follow source leads. Save firms, roles, periods, and URLs to outputs/people/fhfv-1882/affiliations.csv. Save evidence and unresolved questions alongside it.
Inspect evidence
Choose a search
Read a source
Assess and save
The main agent can delegate separate people to subagents. Each worker conducts its investigation and returns findings to the coordinator.
Spawn two research subagents. Assign one the director’s son, born in 1882, and the other his spouse, Lijntje Roosenburg. Give each the identified person record and affiliation-research task. Each saves files in a separate person folder. Wait for both, then summarize findings and unresolved questions.
Coordinator
Son’s research worker
Spouse’s research worker
Coordinator collects results
Read both workers’ notes and rows. Check the assigned identities and whether sources support the roles and periods. Request further evidence where necessary. Use Python to combine reviewed rows into outputs/affiliations.csv and collect unresolved questions in outputs/unresolved.md.
outputs/
├── people/
│ ├── fhfv-1882/
│ └── roosenburg-1860/
├── affiliations.csv
└── unresolved.md
The coordinator reviews and combines the investigations. The researcher decides whether the evidence is sufficient for the analysis.
Coding agents can produce repeatable code and conduct searches that adapt to results. Saved code, evidence, and decisions make that work inspectable.
Claude Code: macOS, Linux, or WSL
Run the installed agent inside the project. For web research in Codex, use codex --search. Check the installed version’s tool and permission settings before running saved prompts unattended.
Claude setup; Codex CLI. Commands checked 30 September 2026.
Install chatlas and its Anthropic provider dependency:
Offline research replay: from the website repository
Optional API example: from the prepared workspace
The replay needs only Python’s standard library. The optional API example makes model calls; rendering the presentation does not.
Hosted OCR sends the document to the configured service. Set up its API access as described by the installed tool. Check the result against the source images.
| Exit code | Meaning |
|---|---|
| 0 | Conversion completed |
| 1 | Reading or conversion failed |
| 2 | Invalid invocation |
| 3 | PDF pages need OCR under default handling |
Verified with local anydoc --help, 30 September 2026.
GenealogieOnline: director born in 1849
OpenArchieven: 1879 marriage, BHIC record 148
Evidence inspected on 30 September 2026. Geni access failed. The replay uses saved archive responses and curated decisions; it is not an exhaustive affiliation survey.
Coding Agents for Historical Research