Agent Architecture
Pactwise uses AI agents in two places: contract intelligence for the contract and vendor management product, and PactWise Source for RFPs and sourcing. This page covers how those agents are built, which parts are model-driven and which are deterministic, and what each one can do today. Capabilities that are built but not yet generally available are kept apart in a clearly labelled section at the end.
The overall system
Pactwise does not run one large autonomous model. It is a set of narrow components, each with a defined job. Most of them are deterministic code. Claude is used where language understanding actually adds something, and only behind tenant scoping, read-only tools and budget controls.
| Component | What it is | How it works | Availability |
|---|---|---|---|
| Contract Assistant | Answers questions about your contract portfolio; answers drawn from contract wording carry citations | Claude tool-use loop over four read-only tools: three scoped to your organization, one over a separate public precedent corpus | Generally available for structured lookups. Wording search covers contracts that have been indexed; automatic indexing of new uploads switches on with the document pipeline (see In development) |
| Agent platform | Ten agent types behind one authenticated API, fed by a tenant-scoped task queue | Rule-based by default: pattern matching, weighted scoring and classical statistics | In development: the API and queue are deployed, but automatic processing is switched off and no product screen uses them yet |
| PactWise Source workflow | Publish gates, deadlines, sealed submissions, audit trail | Deterministic code. No model is involved | Drafting is available today. Publishing, vendor submissions and upload file inspection are built but not yet switched on |
| Prep Studio (Source) | Drafts an RFP package for a buyer to review and approve | Claude inside a state machine with deterministic validators | In development |
These components share one foundation:
- One model policy, Claude Haiku 5.5 only, enforced in code by every integration that calls Claude.
- Voyage AI legal-domain embeddings for retrieval.
- One library of contract checklists.
How work flows
Interactive requests: Contract Assistant
A question to the Contract Assistant is handled within a single request:
- The endpoint authenticates the user, applies rate limits, and validates the message with a schema. Messages have a maximum length.
- The tenant is taken from the authenticated session. It is never taken from the request body or from anything the model says.
- A pre-flight budget check runs against the user's and the organization's AI budgets. If either budget is exhausted, the request is refused with a rate-limit response and no model call is made.
- Claude runs a tool-use loop. On each turn it can call one or more of four permitted tools. Results go back to the model, and errors are returned to it as error results it can react to. The loop ends when the model produces an answer. If it has not answered within a fixed iteration cap, the request fails with an error rather than returning a partial answer.
- Citations are built from the retrieval results that actually ran, not from model-written text. Answers from structured contract lookups name the contracts they draw on, but do not carry separate citations. The session, the messages and the citations are stored.
Each question is answered on its own. Sessions are stored, but earlier turns are not sent back to the model, so the assistant does not rely on conversation memory.
Queued, multi-agent work is not yet switched on for customers. It is described under In development.
The model-driven agent available today: Contract Assistant
The Contract Assistant is the agent where Claude makes decisions in production today. Those decisions are which tools to call and how to put together a grounded answer.
| Tool | Purpose | Scope |
|---|---|---|
rag_search | Find clauses and wording in your own contracts | Your organization only; soft-deleted contracts excluded |
search_contracts | Structured lookups: filter by status, type, vendor or minimum value, returning a bounded list of matching contracts | Your organization only |
get_contract | Details of one contract | Your organization only |
search_precedents | Market-standard wording from a corpus of publicly filed contracts (for example SEC exhibits) and public research datasets | Shared corpus, kept separate from all customer data |
The assistant is not given any other tool. Tools that write data or run arbitrary queries are never offered to it. If a tool name was not offered for the request, the tool executor refuses it, even if the model asks for it by name.
Prompt design
The system prompt is short and does four things:
- Role framing. The assistant answers questions about the user's own portfolio, grounded in contract text.
- Tool-selection policy. It is told which tool to use for which kind of question: wording questions go to retrieval, structured questions go to contract search, and benchmark questions go to the precedent corpus. It may combine tools.
- Grounding rules. It answers only from tool results, never invents terms, parties, dates or values, and attributes every claim about a customer contract to the contract it came from.
- Abstention and labelling. If nothing relevant comes back, it says so instead of guessing. Precedent material must be labelled as a market example and never presented as the customer's own contract.
Tests cover citation correctness and cross-tenant isolation for this endpoint.
Retrieval and grounding
| Aspect | Implementation |
|---|---|
| Embedding model | Voyage AI voyage-law-2, a legal-domain model with 1,024 dimensions |
| Query vs document | Separate embedding input types for indexed contract text and for search queries |
| Index | Contract text is split into chunks and stored with vector embeddings in Postgres (pgvector) |
| Search | Hybrid: vector similarity combined with keyword matching, with scores blended into one ranking |
| Caching | Embeddings are cached by model, input type and text |
Grounding comes from the system as well as from the prompt:
- Tenant scope is server-side. Retrieval always runs for the organization in the authenticated session. If the model asks to search inside a specific contract, the system first checks that the contract belongs to the caller's organization and has not been deleted. Only then does the search run.
- Bounded context. Each search returns a small number of short excerpts. This keeps answers tied to quotable passages rather than whole documents.
- Verifiable citations. Citations come from the retrieval results that actually ran. They are deduplicated and capped per answer. Contract titles are looked up with the same tenant and soft-delete scoping as the search.
- Separate precedents. The public precedent corpus is a fixed, read-only collection of publicly available contracts. It is never mixed into a customer's own results. When it has no relevant match, the assistant says it found no precedent rather than guessing.
Models and how they are chosen
| Use | Model |
|---|---|
| All language-model calls | Claude Haiku 5.5 (Anthropic) |
| Embeddings for retrieval | Voyage AI voyage-law-2 |
Model selection is a fixed policy, not a per-request choice:
- Every backend Claude call goes through one shared client. That client recognises exactly one model, Claude Haiku 5.5. Any other model identifier is mapped back to Haiku 5.5, whether it comes from configuration, a database row, an environment setting or a request field. Prep Studio and a separate contract-intelligence service have their own Anthropic integrations, each pinned to Haiku 5.5 as well.
- The model is resolved again at send time, so an explicit override cannot get around the policy.
- The backend client turns extended thinking off. Prep Studio leaves thinking at the model's default. Sampling parameters stay at the model's defaults everywhere.
- When a backend component needs structured data, the expected JSON Schema is generated from a typed schema and included in the instructions. The reply is parsed and validated against the typed schema before anything downstream uses it. A reply that does not match is rejected.
- Every call uses the same model, and deterministic code handles routing, validation and arithmetic around it. Each request is also bounded by an iteration cap and a budget check.
Reliability and cost controls
Model calls
- Failed calls are retried, up to three attempts, with exponential backoff and jitter.
- The tool-use loop has a fixed iteration cap. Tool failures are returned to the model as errors instead of crashing the request.
Cost
- Every tool-loop request is priced individually from token usage and recorded to a usage ledger. Ledger writes are batched.
- Budgets exist at the organization level and per user, and they are checked before a request reaches the model.
- Backend embedding calls are cost-tracked as well.
Security and tenant isolation
These guarantees hold for the Contract Assistant, the model-driven agent available today:
- Tenant isolation. The assistant requires authentication. The organization comes from the authenticated session, never from request bodies or model output. Every tenant-scoped tool filters to that organization in code, soft-deleted records are excluded, and cross-tenant tests cover the endpoint.
- Least privilege for the model. The model receives only an explicit allowlist of read-only tools. The executor binds itself to that allowlist and refuses anything else.
- Structural defence against prompt injection. Text inside a contract is data, and the controls are designed on that basis. Retrieved text reaches the model only as tool results. If a document contains planted instructions, the model has no write tool to obey them with, and the tenant is fixed server-side, so there is no path into another organization.
- Separate public data. Benchmark material comes from a separate corpus of publicly available contracts, and the assistant is instructed to label it as market material.
- No AI decisions in sourcing. In PactWise Source, publish gates, deadlines, sealed submissions and the audit trail are deterministic code. No model scores, ranks or recommends vendors.
In development
Not yet generally available. Everything in this section is built and tested in the codebase but is not switched on for customers. Details, scope and timing may change before release.
Agent platform and task queue
The agent platform is a single authenticated, rate-limited API with a registry of ten agent types: secretary, financial, legal, analytics, vendor, notifications, manager, workflow, compliance and OCR. The API and queue are deployed, but automatic processing is switched off and no product screen uses them yet. Work is represented as task rows in a Postgres-backed queue:
- Every task belongs to exactly one organization. The agent record it runs against is resolved within that organization.
- Tasks carry a priority and an optional scheduled start time.
- Workers claim tasks atomically. The claim locks rows and skips any that are already locked, picks the highest priority first and then the oldest, and marks claimed tasks as processing in the same statement. Two workers can never claim the same task.
- Only the platform's own service credentials can call the claim operation. The database refuses an unscoped claim from any other caller.
- The secretary, analytics, vendor and notifications agents read schema-validated thresholds with defaults, which can be tuned per organization through configuration rather than code. Document-pipeline thresholds are tunable platform-wide without a deploy.
- A health check flags agent types with a high number of failures in the past hour and queues with a large pending backlog.
The agents' default processing mode is rule-based.
Specialist agents and orchestration
A manager agent routes requests. Orchestration can already be started on demand through the agent API, by a user with the manager role, and runs the manager's plan on the state-graph engine; automated background draining of the queue is not yet switched on. Its routing is deterministic: pattern matching identifies the request type, extracts entities such as contract references, vendors, amounts and dates, and detects urgency and financial or legal signals. It then builds a dependency plan:
- Document extraction runs before legal, financial and vendor review.
- Analytics runs after those data providers.
- Notifications run after analytics.
The plan is compiled into a state graph (see below). A non-critical agent that fails skips the steps that depend on it rather than failing the whole run. Workers process tasks with bounded concurrency and a per-task timeout. Agents can spawn follow-up subtasks, limited to one level of nesting and deduplicated so the same follow-up is never queued twice.
The specialists are almost entirely deterministic:
| Agent | What it does | Method |
|---|---|---|
| Secretary | Input validation and cleanup (including garbled-encoding detection), routing, clause and entity extraction, keyword and legal-phrase extraction, document similarity; can queue OCR | Pattern rules, TF-IDF similarity |
| Legal | Clause detection (liability limits, indemnity, termination and others); six risk patterns such as unlimited liability, one-sided terms, auto-renewal and broad indemnity; missing-clause and red-flag checks; cross-reference and amendment detection; GDPR, CCPA and HIPAA keyword checks | Pattern rules and an additive risk score bucketed into low, medium, high or critical |
| Financial | NPV, IRR, cash-flow projection, ROI, burn-rate forecasting, risk flags such as upfront payment or no exit clause; currency conversion from a public exchange-rate feed with caching | Newton-Raphson IRR with sign-change checks and reporting of multiple roots; Holt-Winters and STL forecasting |
| Vendor | Relationship score, spend concentration, performance trend, issue frequency | Weighted scoring, Herfindahl-Hirschman index |
| Analytics | Spend trends, seasonality, anomalies, 12-month spend forecast with confidence, concentration risk | OLS with R-squared, STL decomposition, z-score anomalies, Holt-Winters |
| Notifications | Severity, recipient, channel and escalation decisions | Database notification routing with a rule-based fallback |
| OCR | Runs the document pipeline below | Text extraction plus Claude for classification and checklist extraction |
| Workflow | Maps workflow requests onto durable state-graph runs | Orchestration only |
Document understanding pipeline
Uploaded contracts will pass through a staged pipeline. Each stage records its own status and queues the next one.
- Text extraction. Native PDFs are parsed directly. Scans and images go through OCR. A confidence score that was estimated rather than measured can never approve a document automatically.
- Classification. One Claude call reads an excerpt of the document and picks one type from a closed list of 34 contract types. The answer is validated against the catalog, so an invented type is rejected. If the model is unavailable or its answer is invalid, a keyword classifier runs instead. Its confidence is deliberately capped low, so the document always goes to a person.
- Checklist extraction. The contract is evaluated against the checklist for its type, one section at a time. The library holds 831 items across the 34 types, each tagged with a risk level and many with market benchmarks, red flags and regulatory references. Every item is marked present, partial or absent, with a confidence and, where available, a supporting quote. Items the model skips are recorded as not evaluated rather than assumed. A section that fails degrades instead of aborting the run.
- Review gate. A single pure function works through an ordered list of reasons a document needs a person. Examples are an OCR failure or low OCR confidence, an unresolved classification, a triggered red flag, a critical item evaluated with low confidence, and too many unevaluated items. The first reason that applies is recorded. Thresholds can be retuned without a deploy. Low-confidence suggestions are kept, so the reviewer confirms a pre-filled answer instead of starting from a blank field.
- Finalize. Human corrections always take precedence. The contract record and its structured extractions (parties, dates, pricing, scope, key terms) are written. The counterparty is identified by excluding the customer's own name. A new vendor record is created automatically only at high confidence; otherwise the match goes to review. A vendor link a person has already set is never overwritten.
Every stage logs its model, token usage, latency, outcome and review reason. A dry-run mode exercises the whole state machine without making any model calls.
Durable state-graph engine
Multi-step agent work runs on a durable orchestrator built natively on Postgres:
- Execution model. Work runs in Pregel-style super-steps over a graph of typed nodes: agent, condition, approval, wait, subgraph and compensate. After every step the shared state is checkpointed, so a run survives a worker crash and resumes from its last checkpoint. Steps that already succeeded are never re-run.
- State and branching. Shared state uses reducer channels (last value, merge, append). Conditional edges skip dead branches.
- Failure handling. Nodes can have retry policies with exponential backoff. Saga-style compensation rolls back completed steps when a run fails.
- Asynchronous nodes. An agent node can hand work to the task queue. The handoff is idempotent, so a crash can never dispatch the same work twice.
- Human approvals. An approval node pauses the run until a person decides. Authorization is enforced by the database, not the API: only an eligible approver in the same organization can resolve a pending approval, and the approver's identity is stamped by the database. An approval that sits too long escalates once with an urgent notification. Escalation never makes the decision.
- Operations.
- Runs are claimed under time-limited leases, and a watchdog recovers expired leases, enforces deadlines and stops runs that keep failing.
- Each run keeps a snapshot of its graph definition, so a redeploy never changes a run that is already in flight.
- The event log and checkpoints are idempotent.
- Cancelling a run also cancels its child tasks and subgraphs.
- Isolation. Each organization can read only its own run tables, and only the platform itself can write to them, except that an eligible approver can resolve a pending approval.
Nine graphs are built in, including contract lifecycle (where high risk routes to executive approval), vendor onboarding, budget planning and invoice processing. Individual nodes can be set up to call Claude. The mode and the prompt come only from the graph definition and never from run input. These calls get the same read-only tool allowlist, budget gate and circuit breaker as other agent calls, and fall back to rule-based processing when no model is available.
Agent memory
Agents will keep two tiers of memory: short-term memory that expires after 24 hours, and longer-term memory. Memories are recalled per user within that user's organization and ranked by importance, recency and relevance. When a recalled memory is included in a prompt, it is marked as untrusted reference data, never as instructions.
PactWise Source publishing and file inspection
Publishing an RFP, sending vendor invitations and accepting sealed submissions are built, and are held off until the remaining vendor-side pieces ship. Files uploaded to Source will pass a default-deny structural inspection before a buyer can open them; until it is switched on, uploaded files stay unavailable rather than opening uninspected. All of this is deterministic code, with no model involved.
Prep Studio for PactWise Source
Prep Studio is a state machine that drafts an RFP package in six artifacts: intake, scope, requirements, evaluation criteria, pricing schedule and milestones.
Division of labour. The model drafts and code checks. Deterministic validators enforce the rules: criteria weights sum to exactly 100, every scored requirement maps to exactly one criterion, requirement codes are unique, scored requirements are measurable, and pricing lines can be priced. Milestone dates are computed in code, and the model writes only the rationale. A pre-check mirrors the database's publish gate rule for rule, and that database gate stays authoritative.
Human control. Approval is bound to the exact content the buyer saw. Any upstream change marks dependent artifacts stale and clears their approval. Only one person can edit a draft at a time. Final writes go through the same API the buyer uses, under the buyer's own credentials.
Self-review. A red-team critic reviews the full draft from the point of view of a vendor bid manager and a protest lawyer, for up to three cycles. Its findings are advisory. Blocker and major findings automatically re-run the artifact they target and everything downstream of it. Minor findings wait for the buyer.
Prompt engineering:
- Seven prompt modules, versioned and reviewed like code. Each carries a content hash that is stamped on every trace and artifact.
- Shared house rules. The AI never scores, ranks or recommends vendors.
- All buyer input and retrieved text is fenced as untrusted.
- Structured output through a forced tool call with schema validation. A schema failure gets at most two corrective re-asks that list the exact validation errors.
- Refusals and truncated answers are handled explicitly and never become partial drafts.
- The system prompt is cached across retries.
- Per-draft token and cost budgets, plus a per-run time budget, pause the run rather than overspending.
Grounding. Prep Studio draws on the contract checklist library and the public precedent corpus. Retrieval that fails is surfaced to the buyer as a warning instead of being hidden. Competitors' released bid text is always excluded from retrieval.
Evaluation. Automated evaluations replay complete drafting runs against hand-authored golden fixtures and check gate pass rate, critic convergence, cost ceilings and draft-quality metrics. Recordings of live model runs have not been made yet.