What a file record holds
One record per file, of typelangchain.artifact, linked to the tool step
that produced it. Its promoted metadata is the part a reader can use without
opening the body:
path and content_type join name and byte_length when the tool
supplied them. The hash lives on the record itself, in event.content_hash,
not in this metadata.
From 0.16.0, the record commits to the file’s own bytes (proof#92).
event.content_hash is the file’s SHA-256, and the bytes go to your log
store the same way any other content does: never sent to Sanning, which
receives the signed envelope only. A record written before this release
commits to a descriptor instead, and does not match the file when it is
handed in beside a pack; see Verify at the command line.Return the file from your tool
A tool that saves a file returns where it saved it. That return value is the whole integration.Check a file against its record
Whoever holds the file runs one command and compares the result toevent.content_hash in the record. No Sanning code takes part in that
step:
claims-week-37.csv with the file you are checking. On macOS the
command is shasum -a 256.
A match establishes that this file is the one the record commits to. What that
means for a review is the reader’s conclusion, not ours.
Shapes the SDK recognizes
Three shapes in a tool’s return value are recognized:- LangChain’s own artifact field on a tool message, the first-class channel and what an agent framework hits.
- Raw bytes returned from the tool.
- A path, as the whole return value, which is what a tool that saves a file returns.
{ "name": ..., "path": ... }, counts as
a declaration however it arrived.
A file is recorded only when the tool result says it came back. Never scraped
out of prose, never discovered by watching a folder, never taken from a
configured list. A bare string is treated as a path only when a file exists
there, so an ordinary tool returning ordinary text records nothing and says
nothing.
Show which policy a step applied
A tool that reads a policy file and returns it as its artifact gets a record that commits to the file’s bytes, on that tool’s step. For the example, see Trace a LangChain agent.The read root
Reading is scoped to one folder, and the folder limits reading rather than storing anything. It defaults to the process’s working directory, because a tool result is text a model influenced, and following a path out of one is an untrusted read... and a symlink out of
the root both fail closed. A file above max_bytes is recorded as unreadable
rather than truncated.
A file the SDK cannot read
A file the tool declared and the SDK could not hash becomes its own record,langchain.artifact_unreadable, carrying the reason. Silence is how three
files went unrecorded on a run that reported success.
not_found, outside_root, not_a_regular_file,
too_large, read_failed and path_reading_disabled. A trail that says “I
could not hash this” is evidence. A trail that says nothing is not.
What to read next
Trace a LangChain agent
The handler that produces these records, and the run tree around them.
Keep what you anchored
Where the record bytes live, and why a pack cannot be built without them.