Content
# Tool List
This is a Java-based intelligent underwriting demo for interview explanations and local learning. The project showcases a complete, runnable, and trackable chain of user problem understanding, internal data query, RAG knowledge retrieval, risk analysis, deterministic rule verification, large model suggestions, and result persistence.
Default configuration is completely offline, using fictional data, Hash Embedding, in-memory vector library, and deterministic Mock model, **no API Key** required, no database or external model. All company names, addresses, terms, and policies are fictional examples and do not contain real business data.
## Technology Stack
- Java 21, Maven
- Spring Boot 4.1, Spring MVC, Bean Validation, Actuator
- Spring JDBC, optional H2 file database Profile
- Spring AI 2.0 MCP Server, Streamable HTTP `/mcp`
- OpenAI-compatible `/v1/chat/completions` model adapter
- springdoc OpenAPI / Swagger UI
- JUnit 5, AssertJ, MockMvc, MockWebServer
## What This Demo Can Showcase
- Session management: create/restore sessions, save user and assistant messages by role.
- Agent orchestration: fixed seven-step pipeline, retain step trajectory on success or failure.
- Idempotence and concurrency protection: optional `Idempotency-Key` to fold concurrent repeated submissions into one Agent execution, same key different parameters return conflict explicitly.
- Asynchronous task orchestration: independent task REST API returns `202 Accepted`, background execution seven-step Agent, support status polling, same key replay, bounded thread pool/queue, and safe failure snapshot.
- RAG: Markdown/Text parsing, paragraph splitting, overlapping window, vectorized storage; vector cosine and BM25 word score fusion sorting, return hit words/score composition, and calculate Recall@K, MRR, and quality threshold with golden question set.
- Knowledge release governance: documents go through `DRAFT → PUBLISHED → RETIRED` versions; draft versions cannot be recalled, new versions atomically replace old indexes, and retired versions immediately exit retrieval and retain history.
- Business tools: policy, quote, historical underwriting, survey report, disaster risk, and rule verification six types of tools, sharing a unified registry and audit trail.
- Graded fault strategy: critical business data failure immediately terminates; external disaster data source can safely degrade to unknown, but must be promoted to manual review and retain structured alerts.
- Rule bottom line: models can only explain rule results, cannot downgrade `MANUAL_REVIEW` or `REJECT` to automatic approval.
- Model switching: default Mock; can switch to OpenAI compatible interface or enterprise privatized compatible gateway, support connection/read timeout, limited retries, and explicit downgrade.
- Prompt governance: versioned, activated version, variable declaration check, and preview rendering.
- Decision source snapshot: each evaluation solidifies actual Prompt code/version/template SHA-256, complete rule set version/fingerprint, and writes knowledge version, vector score, word score, retrieval mode, and hit words into evidence.
- Decision replay and drift analysis: historical evaluations can be re-executed with current facts, knowledge, Prompt, rule set, and model; new evaluations retain baseline association and structurally compare conclusion strength, risk score, rules, evidence, and source changes.
- REST + MCP: REST for management and debugging, MCP for Agent tool discovery and invocation, both reuse the same business implementation.
- Chinese interaction demo: no need to copy commands, choose four fictional scenarios, run real underwriting, and read rules, evidence, and seven-step trajectory.
- Chinese underwriting report: save a single evaluation and export it as Markdown, completely retaining conclusions, rules, evidence, seven-step trajectory, tool records, and model metadata.
- Human review closed loop: underwriter can confirm, override, or request supplementary materials; review records are atomically created, non-overwritable, and enter report and feedback export interface.
- Optional restart recovery: `persistent-demo` Profile switches sessions, evaluations, and human reviews to H2 file database, still queryable after process restart; default Profile continues to use in-memory storage.
- Running metrics: Actuator exposes ten groups of Micrometer metrics for evaluation, degradation, human review, asynchronous tasks, and decision replay.
## Quick Start
Prerequisites: Java 21+ and Maven 3.9+ installed.
```bash
mvn clean verify
mvn spring-boot:run
```
Open a new terminal to check the service:
```bash
curl --fail http://localhost:8080/actuator/health
bash scripts/demo.sh
```
To verify client retry safety, add a stable `Idempotency-Key` to the submission request. The first successful return `201`, and `Idempotency-Replayed: false`; same key, same business payload submitted again returns the same evaluation, HTTP `200`, and `Idempotency-Replayed: true`. Same key with different payload returns `409 IDEMPOTENCY_KEY_CONFLICT`.
```bash
curl -i -X POST http://localhost:8080/api/v1/underwriting/evaluations \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: interview-evaluation-001' \
-d '{"policyNo":"P-2001","question":"Can this office building policy be underwritten?"}'
curl --fail http://localhost:8080/actuator/metrics/underwriting.evaluation.submissions
curl --fail http://localhost:8080/actuator/metrics/underwriting.evaluation.duration
curl --fail http://localhost:8080/actuator/metrics/underwriting.evaluation.decisions
```
### Asynchronous Task Orchestration
Synchronous evaluation interface suitable for interactive requests; if the model or internal system response is slow, submit an asynchronous task and poll the status:
```bash
task_json=$(curl -sS --fail-with-body \
-X POST http://localhost:8080/api/v1/underwriting/tasks \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: interview-task-001' \
-d '{"policyNo":"P-1001","question":"Asynchronously analyze this warehouse policy."}')
task_id=$(printf '%s' "$task_json" \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')
curl --fail "http://localhost:8080/api/v1/underwriting/tasks/${task_id}" \
| python3 -m json.tool
```
### Safety Degradation Demo
Default startup will not inject faults. To demonstrate internal disaster platform timeout during an interview, enable the dedicated `degraded-demo` Profile:
```bash
SPRING_PROFILES_ACTIVE=degraded-demo mvn spring-boot:run
```
Then run `P-2001` at `/demo/`, or execute:
```bash
curl -sS -X POST http://localhost:8080/api/v1/underwriting/evaluations \
-H 'Content-Type: application/json' \
-d '{"policyNo":"P-2001","question":"Can it be automatically underwritten when the disaster platform is unavailable?"}' \
| python3 -m json.tool
curl --fail http://localhost:8080/actuator/metrics/underwriting.agent.degradations
```
### Human Review Feedback Closed Loop
After completing any single scenario evaluation, the demo shows a "Human Review Feedback Closed Loop". The underwriter can record approval, rejection, or request supplementary materials. The system will not modify the original Agent suggestion but create a separate, non-overwritable `HumanReview`, and calculate `CONFIRMED`, `OVERRIDDEN`, `RESOLVED_MANUAL_REVIEW`, or `CONTINUED_MANUAL_REVIEW` relationships.
```bash
curl -sS -X POST \
http://localhost:8080/api/v1/underwriting/evaluations/EVAL-replace-with-real-number/review \
-H 'Content-Type: application/json' \
-d '{
"reviewerId":"UW-DEMO-001",
"outcome":"APPROVED",
"comment":"The rectification materials have been verified, and it is agreed to underwrite with conditions.",
"conditions":["Increase deductible","Quarterly review"]
}' | python3 -m json.tool
curl --fail http://localhost:8080/actuator/metrics/underwriting.human.reviews
```
### Optional File Database and Restart Recovery
Default startup still uses the simplest in-memory mode, no database required. To demonstrate "evaluation and human review still exist after application process restart," enable the `persistent-demo` Profile:
```bash
SPRING_PROFILES_ACTIVE=persistent-demo mvn spring-boot:run
```
### Browser Interaction Demo (Recommended)
After starting the application, visit <http://localhost:8080/demo/>.
1. Choose any fictional scenario from `P-1001` to `P-4001`; conclusions can be filtered, or use number keys `1`–`4` for quick switching.
2. Read policy, quote, historical, survey, and disaster facts, and modify questions in "Underwriting Task".
3. Click "Run Intelligent Underwriting" or press `Command/Ctrl + Enter`, observe seven-step Agent orchestration through real-time status area.
4. View end-to-end time consumption, tool availability, rule hits, knowledge evidence, and model routing in the decision metrics area.
5. Use "Decision Overview, Rules & Evidence, Execution & Audit, Human Review" four tabs to layer results.
6. Copy underwriting summary, export complete JSON, or click "Download Chinese Markdown Report" to get deliverables generated from saved results.
7. Click "Replay Current Decision", re-execute with current five types of sources, and view `STABLE`, `SOURCE_DRIFT`, or `DECISION_DRIFT` explanations.
8. Record underwriter's final processing in "Human Review Feedback Closed Loop", observe it listed alongside Agent suggestions.
9. Restore recent underwriting results from "Current Session Records", no need to repeat backend calls; session records saved in browser session storage before page refresh.
10. Click "Compare All Scenarios", let four fictional policies call the same real underwriting interface in sequence.
11. Confirm automatic approval 1, human review 2, rejection 1, risk score range 10–70, and view facts for each scenario.
## 10-Minute Learning Route
1. Run `mvn clean verify`, confirm environment and all tests pass.
2. Run `mvn spring-boot:run` to start offline service.
3. Open `/demo/`, click "Compare All Scenarios" to understand conclusion distribution, then enter one scenario for detailed underwriting.
4. Open `/api/v1/demo/scenarios` to check page data, then run `bash scripts/demo.sh` to observe batch API process.
5. Refer to [Fictional Underwriting Data and 10-Minute Guide](docs/DEMO_DATA_GUIDE.md), track from business facts to rule hits, risk add-ons, and final decisions.
## Four Teaching Demo Scenarios
| Policy No. | Scenario | Key Facts | Deterministic Result |
| --- | --- | --- | --- |
| `P-1001` | High-risk logistics warehouse in Lingang | 20 million yuan insured amount, 2 accidents in the past 3 years, drainage rectification not completed, red risk of rainstorm | Manual Review (`MANUAL_REVIEW`), High Risk (`HIGH`), 70 points |
| `P-2001` | Low-risk tech office building | 5 million yuan insured amount, no historical accidents, no survey leftovers, low disaster risk | Evidence complete automatic approval (`APPROVE`), Low Risk (`LOW`), 10 points |
| `P-3001` | Rainstorm-exposed commercial warehouse | 12 million yuan insured amount, 1 accident, rectification completed, red risk of rainstorm | Manual Review (`MANUAL_REVIEW`), Medium Risk (`MEDIUM`), 40 points |
| `P-4001` | Extreme fire risk manufacturing plant | 8 million yuan insured amount, major fire defects, extreme fire risk | Reject (`REJECT`), High Risk (`HIGH`), 60 points |
If knowledge evidence is missing, even if rules originally allow automatic approval, the system will promote the decision threshold to `MANUAL_REVIEW` to avoid unsubstantiated automatic underwriting.
## Seven-Step Orchestration
```text
QUESTION_UNDERSTANDING
-> BUSINESS_DATA_COLLECTION
-> KNOWLEDGE_RETRIEVAL
-> RISK_ANALYSIS
-> RULE_VALIDATION
-> RECOMMENDATION_GENERATION
-> RESULT_PERSISTENCE
```
A complete evaluation will return: final decision, risk level/score, hit rules, knowledge evidence, model summary, suggested actions, structured degradation alerts, 5 business tool calls + 1 rule tool call, and 7 step trajectories. Normal process steps are `SUCCESS`; allow but incomplete data marked as `DEGRADED`, not pretending to be successful or low risk.
Source Snapshot
Agent obtains both rendering results and `PromptSnapshot` in a single atomic Prompt rendering, ensuring the model's response preserves the Prompt code, active version, and template SHA-256, which corresponds to the actual template fed into the model. The complete rendered Prompt, including fictional policy facts, is used only within this model call and is not written to evaluations, reports, or API responses. The audit saves a version reference and fingerprint without business content.
Each `Evidence` retains knowledge document version, chunk number, fusion score, vector score, lexical score, `RetrievalMode`, and hit terms. The browser demo adds a "Decision Source Snapshot" feature, outputting complete template fingerprints and knowledge retrieval explanations in Markdown reports. This allows tracing back along the "evaluation → Prompt vN → rule set vN/SHA-256 → model routing → knowledge document vN / chunk → rules and tool traces". The rule set fingerprint comes from a normalized list of base and all five rules, not just the ones hit in this case. Old H2 JSON without new fields can still be read but is clearly marked as "historical record unavailable", without guessing or forging sources.
## Decision Replay and Drift Analysis
`POST /api/v1/underwriting/evaluations/{evaluationId}/replays` does not modify the original evaluation but re-executes the seven-step Agent in an isolated new session with the current five sources. The replayed evaluation saves `replayedFromEvaluationId`, and callers can use `Idempotency-Key` to prevent duplicate executions caused by network retries. The response returns baseline, replayed evaluation, and `DecisionDrift`:
- `decisionChange` distinguishes between `UNCHANGED`, `STRENGTHENED`, and `WEAKENED`;
- Compares risk levels/scores, added or removed rule codes;
- Compares new/removed knowledge versions and chunks, as well as common evidence retrieval scores/explanations changes;
- Compares Prompt, complete, and model routing snapshots;
- Finally, categorizes as `STABLE`, `SOURCE_DR or `DECISION_DRIFT generates explanations.
```bash
baseline_id='EVAL-replace-with-real-id'
curl -sS -X POST \
"http:8080/api/vwriting/evaluations/${baseline_id}/replays" \
"Idempotency-Key:baseline_id}" \
3 -m json.tool
```
For saved replayed evaluations, `GET /api/v1/underwriting/evaluations/{replayEvaluationId}/drift` can be used to rebuild comparisons at any time. This "what changes occurred aftervaluating with current dependencies", to reproduce historical model outputs; production environments also require immutable business fact snapshots, addressable model versions, rule/knowledge approval chains, and append-only audit storage.
## Knowledge Versioning and Release Lifecycle
Management APIs no longer allow external uploads to immediately enter Agent retrieval. `POST /api/v1/knowledge/documents` creates a v1 draft; `POST /documents/{id}/versions/{version}/publish` then parses, chunks, embeds, and publishes. Each document can have at most one draft at a time; publishing v2 marks v1 as `RETIRED` and replaces all chunks of the document with an immutable index snapshot, so search threads see either the complete old or new version. `retire` removes the current index, but version content and timestamps remain queryable.
Publishing first builds index; if parsing or embedding fails, the old published version and index remain unchanged, and the new version stays as `DRAFT`. Four classpath demo documents are created and published by the same service at startup, so the default Agent can still run directly. Execute the full eight-step lifecycle demo:
```bash
bash scripts/knowledge-lifecycle-demo.sh
```
This script validates "draft is not retrievable → v1 published → v2 draft does not affect v1 → v2 atomically replaces v1 → v2 is offline and not retrievable". See [API_EXAMPLES.md](docs/API_EXAMPLES.md) for detailed REST commands Explainable Hybrid Retrieval and Offline Evaluation
`POST /api/v1/knowledge/search` calculates both vector cosine scores and BM25 lexical scores, combining them with a fixed weight of `65% vector35% lexical`. Lexical analysis normalizes English/digital generates single and double character words for continuous Chinese, so precise terms like `RULE-RAIN-001`, clause numbers, and "heavy rain red alert" can be recalled even when embedding signals are weak. Each hit returns `score`, `vectorScore`, `lexicalScore`, `mode`, and `matchedTerms`, making it explainable why the item was recalled.
`POST /api/v1/knowledge/evaluations` receives up to 100 golden questions, calculates average `Recall@K` and `MRR` based on expected document IDs, and returns `passed` based on the caller's submitted minimum threshold. `bash scripts/demo.sh` executes two golden questions and demonstrates quality gate checks; see [API_EXAMPLES.md](docs/API_EXAMPLES.md) for the complete request. This is a deterministic teaching evaluation; production environments require versioned annotation sets, real user questions, NDCG, permission filtering, and independent reranking evaluations.
## Model Switching
The default is `LLM_PROVIDER=mock`, which does not access the network. When connecting to OpenAI-compatible or enterprise privatized interfaces:
```bash
export LLM_PROVIDER=openai-compatible
export LLM_BASE_URL=https://your-model-gateway.example.com
export LLM_API_KEY=replace-with-runtime-secret
export LLM_MODEL=your-model-name
export LLM_CONNECT_TIMEOUT=2s
export LLM_READ_TIMEOUT=15s
export LLM_MAX_ATTEMPTS=3
export LLM_RETRY_BACKOFF=100ms
export LLM_FALLBACK_TO_MOCK=false
mvn spring-boot:run
```
Only retries for I/O exceptions, timeouts, HTTP 429, and 5xx; does not retry for common 4xx. By default, silent downgrade is prohibited. Only when explicitly set to `LLM_FALLBACK_TO_MOCK=true` does it fallback and mark `fallbackUsed=true` in the response. API Key is only read from runtime environment variables, not written to logs, responses, or exceptions.
## Docker
```bash
docker build -t insurance-underwriting-agent-demo:local .
docker run --rm -p 8080:8080 insurance-underwriting-agent-demo:local
```
The container uses a Java 21 runtime, non-root users, and health checks. The default is still a mock mode without external dependencies.
## Project Structure
```text
src/main/java/com/hrniux/underwriting
├── agent # Seven-step orchestration, evaluation results, decision replay/drift, and step traces
├── api # REST controllers and request DTOs
├── demo # Structured fictional scenarios, completeness verification, and Chinese directory API
├── model # Mock/OpenAI-compatible/model gateway
├── prompt # Prompt version management, strict rendering, and non-leakable version fingerprint snapshots
├── rag # Knowledge version publishing, atomic indexing, embedding, hybrid retrieval, and offline evaluation
├── report # Chinese Markdown underwriting reports and security escaping
├── review # Manual review relationship classification, atomic repository, and feedback metrics
├── rule Deterministic rules, risk scoring, and decision thresholds
├── session # Sessions and messages
├── task # Asynchronous task state machine, bounded executor, and task submission idempotence
├── tool Fictional internal systems, registries, MCP tools
└── shared # Configuration, unified exceptions, and persistent JSON encoding/decoding
```
For further reading:
- [Fictional Underwriting Data and 10-minute Learning Guide](docs/DEMO_DATA_GUIDE.md)
- [Architecture and Key Design](docs/ARCHITECTURE.md)
- [Complete API/MCP Examples](docs/API_EXAMPLES.md)
- [Interview Demo and Q&A](docs/INTERVIEW_GUIDE.md)
## Production Evolution
This project intentionally separates port and memory/JDBC implementations to illustrate the production transformation route:
| Demo Implementation | Production Replacement Direction |
|---|---|
| Default in-memory storage; optional H2 aggregated JSON storage | + PostgreSQL structured audit and assessment tables, Flyway |
| H2 unique key-protected single record overwrite | PostgreSQL append-only review events, RBAC, electronic signatures, and transactions |
| Hash Embedding | Enterprise embedding models or compliant cloud models |
| In-memory vector + BM25 hybrid retrieval | PostgreSQL + PGVector, Milvus, or Elasticsearch/OpenSearch and reranking |
| JSON scenario repository + graded failure tools | Internal REST/gRPC/MQ adapters with timeouts, circuit breakers, bulkheads, and explicit exception classification |
| Single-machine bounded async tasks + single-instance idempotence | Persistent state machines/workflow engines, message queues, cross-node idempotence, timeout cancellations, and compensations |
| Environment variable secrets | Vault/KMS, short-term credentials, key and exit gateways Micrometer single-instance metrics |, OpenTelemetry Trace,, and recall quality dashboard |
Production environments should also add tenant permissions, field-level masking, operation audits, knowledge publishing approval, Prompt grayscale, desens sample governance, model output evaluation, and disaster recovery strategies.
## Disclaimer
This project is for technical learning and interview demonstrations only and does not constitute real insurance underwriting opinions. Example data, rule and clauses are all.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available