BondLens

agent
Security Audit
Warn
Health Warn
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Pass
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

BondLens: evidence-first Chinese bond analysis agent — deterministic tools, optional LLM narration under guardrails, Trust Layer, live/snapshot/static data, Docker/CI. 面向中文债市的证据优先分析智能体。

README.md

BondLens: An Evidence-First Bond Analysis Agent for Chinese Market Data

English | 中文

CI
License: MIT
Python
Flask
Tests
Agent Evals
Red Team
Docker
i18n
Data
LLM
Trust
Pages

BondLens logo

BondLens is a lightweight agent for Chinese bond market analysis.
It focuses on one vertical: turn a natural-language bond question into an auditable run with live/snapshot/static data, deterministic tools, optional LLM narration, and a reviewer-facing Trust Layer.

Not a multi-agent equity research desktop.
A claim-level evidence agent for Chinese bonds.

Unlike broad multi-agent equity research platforms, BondLens does not try to be a full investment desk.
Its design choice is narrower and more honest: numbers come from code, the model may only narrate over evidence, and every answer can be replayed, judged, and red-teamed.

Numbers are code-calculated.
Narratives are LLM-assisted.
Every output is provenance-tracked.

Non-investment advice. For learning, research, portfolio demonstration, and interview discussion only.

Project page: https://phoenix0531-sudo.github.io/BondLens/

Example Runs (no API key — open in browser)

Run What you see Open
Market overview Sample yield / volume board + trust-facing pack demo-market-overview.html
Single-bond report First-bond style report with evidence body demo-bond-report.html
Yield outliers Cross-section outlier monitor pack demo-yield-outliers.html
LLM final-answer matrix Recorded deepseek path (zh/en × overview/bond) llm_matrix_deepseek_v4.md

Raw JSON siblings live under docs/demo_runs/.


Design Principle: Deterministic Compute, LLM Narration

A core design principle of BondLens (shared with platforms such as FinRobot) is the strict separation between deterministic financial computation and LLM-based narration.

Layer What produces it Can invent numbers?
Yield / volume / percentiles / rankings Deterministic tools (bond_agent/tools.py) No
Taxonomy / maturity buckets / peer spread Rule-based classifiers + pure Python stats No
Data lineage (live / snapshot / static) Data resolver No
Evidence ledger claims Built from tool outputs No
Final narrative text Deterministic report, or LLM only if guardrail + judge pass Text only; numbers must match evidence

In short: tools compute, models narrate, trust decides.

Codebase Snapshot

Layer What it includes
Agent core Single path: Planner → Tools → Evidence → Report (not a multi-role equity desk)
Deterministic tools 7 public operators: search_bonds, describe_market, rank_bonds, detect_yield_outliers, compare_bond_to_market, build_market_monitor, generate_bond_report
Trust layer Numeric + language guardrail · answer judge · Trust score · Evidence Pack · replay store · risk profile
Evals ~110 pytest cases · agent evals 10/10 · red-team 3/3 · Docker /healthz in CI
Data AkShare live → cached snapshot → static Excel, with explicit lineage and maturity coverage board
Product surface Flask + Jinja · zh-default / en switch (query+cookie) · SSE soft-render · CI + GitHub Pages
Scale (honest) ~10k lines of project Python across bond_agent/ + app/tests/evals — focused vertical, not a 100k+ multi-agent platform

What BondLens Does

BondLens turns a natural-language bond question into an auditable analysis run:

  1. Resolve data (live AkShare → cached snapshot → local Excel)
  2. Plan intent (overview / search / ranking / outliers / monitor / composite / bond report)
  3. Run deterministic tools
  4. Build structured evidence (market, peer, monitor, quality, maturity coverage)
  5. Compose a report with risk notes and mandatory limitations
  6. Optionally polish with an LLM under numeric + language guardrails
  7. Score trust, export a Bond Evidence Pack, and store a replay summary

Product surfaces (answer-first)

  • Answer Snapshot: 3-sentence headline + key metrics; full body collapsed by default
  • SSE stream + soft final render: tool-step progress, token preview, final summary card without forced full-page reload; share/full board still via result_url
  • Bilingual UI (zh default): query/cookie language memory, explicit zh/en switch, bilingual provenance lines
  • Bond type mix + maturity buckets: conservative name-rule taxonomy (no rating inference)
  • Peer comparison: same type + maturity bucket spread vs peers
  • Cross-section monitor board: high yield / low volume / yield outliers / missing maturity
  • Maturity / residual board: live coverage, cashflow teaching duration/DV01, perpetual dual scenarios (first finite leg + theoretical consol)
  • Trust score + stress view + audit folds: guardrail / judge / risk / ledger behind details

Architecture

Data Ops      live / snapshot / static sample + lineage + maturity enrichment
Agent Core    Planner → Tools → Evidence → Report
Trust Layer   Guardrail + Judge + Risk Profile + Trust Score + Replay + Evals
BondLens architecture: Question → Resolver → Planner → Tools → Evidence → Guardrail → Trust
flowchart TD
    A[User Question] --> B[Data Source Resolver]
    B --> C[Planner multi-intent]
    C --> D[Deterministic Tools]
    D --> E[Structured Evidence]
    E --> F[Report + Limitations]
    F --> G{Optional LLM}
    G -->|guardrail pass| H[Narrated answer]
    G -->|fail or disabled| I[Deterministic answer]
    H --> J[Judge + Trust + Pack + Replay]
    I --> J

Inspired by deterministic compute, LLM narration research platforms, BondLens specializes the idea for Chinese bonds with claim-level evidence, answer judging, red-team evals, and reviewer-facing evidence packs — not a multi-role equity research desktop.


Screenshots

Captured on the live agent page (BOND_DATA_MODE=auto, no API key → deterministic final answers).
Narrative: can answer · can go deep · will refuse · can audit.

How to read the shots:

  1. Trust is process/evidence confidence, not trade confidence.
  2. Advisory is a policy block (no LLM), not a disclaimer-only soft refuse.
  3. Numbers come from tools; if the model fails guardrail, the final answer is deterministic.

Older workbench images remain under docs/screenshots/ for history only.

Chinese market overview with trust score and evidence
Can answer — market overview
当前债券市场样本概览如何?
Chinese single-bond report request and trust panel
Can go deep — single-bond report
请对样本中第一只债券生成分析报告
Advisory policy block without LLM
Will refuse — advisory policy block
今天该不该买债? → Trust ≤72, no LLM
Replay dashboard for auditable run history
Can audit — replay / evidence path
Replay dashboard for past runs (traceable output)

English UI (header 中/EN switch) is covered under Language (i18n); historical EN shot: agent-en.png.


Quick Start

0 minutes (no install)

Open a pre-generated Example Run in the browser — no server, no API key:

docs/demo_runs/demo-market-overview.html

Or jump from the Example Runs table above.

5 minutes (offline demo)

pip install -r requirements.txt
# preferred local demo bind
export FLASK_RUN_HOST=[IP]
export PORT=8765
export BOND_DATA_MODE=static
export SECRET_KEY=local-dev
python app.py
# open http://[IP]:8765/agent
# try: 当前样本收益率分布是什么样?

Other packs:

30 minutes (live path + fallback)

export FLASK_RUN_HOST=127.0.0.1
export PORT=8765
export BOND_DATA_MODE=auto   # live first, then snapshot, then static
python app.py
# force live: BOND_DATA_MODE=live
# watch data_source.runtime_mode, maturity board, and trust score when live degrades

Optional LLM polish (never required):

export OPENAI_API_KEY=[密钥]
export OPENAI_BASE_URL=http://[IP]:31876/v1   # example: local OpenAI-compatible gateway (new-api)
export OPENAI_MODEL=deepseek-v4-flash-search  # verified on this host; gpt/grok often unavailable
export OPENAI_API_STYLE=chat
export OPENAI_MODEL_FALLBACKS=gpt-5.4-mini,grok-4.5   # optional; /models probe reorders live ids
# Keys stay in process env only. Do not commit secrets.

Language (i18n)

  • Default UI language: Chinese
  • Explicit switch in the page header (中 / EN)
  • Persistence: ?lang=zh|en query wins, then bondlens_lang cookie, else zh
  • Covers templates, intent/tool labels, deterministic report skeleton, advisory refusal, and flash/error copy
  • LLM system prompts follow the active language; logs stay developer-facing and are not fully bilingual

Tool Catalog (deterministic operators)

Tool Inputs Deterministic outputs
search_bonds name / type / maturity / yield filters match_count, records
describe_market active frame yield/volume summaries, segments, data quality
rank_bonds by, top_n, order ranked records
detect_yield_outliers method, threshold outlier_count, scores
compare_bond_to_market bond / record percentiles, peer comparison
build_market_monitor top_n high-yield / low-volume / outliers / missing maturity
generate_bond_report tool outputs + plan analysis, risk notes, limitations

Numbers in the final answer must come from these tools (or be rejected by the guardrail).


Trust Score & Evidence Pack

Each answer includes trust_score (0–100) built from evidence quality, data freshness/degradation,
ledger coverage, guardrail outcome, judge outcome, and a forced non-advisory penalty.

Every run can export a portable Bond Evidence Pack (JSON + static HTML):

  • question / intent / tools
  • data lineage + maturity coverage
  • trust score + adjustments
  • guardrail + judge + risk profile
  • evidence ledger + final answer
  • mandatory limitations
python scripts/generate_demo_packs.py

Runtime packs: .tmp/evidence_packs/
Committed demos: docs/demo_runs/

Maturity unmatched export

Live/snapshot feeds have no native maturity field. BondLens enriches matched names from the local security master and exposes:

GET/POST /api/maturity/unmatched?format=csv&data_mode=static
GET/POST /api/maturity/unmatched?format=json&data_mode=static

The UI maturity board links to the same export for unmatched bond names.


Example Questions

当前样本收益率分布是什么样?
搜索23附息国债26并给出收益率分析
打开今日市场监控面板:高收益、低成交与异常
按收益率列出最高的前5只债券
有没有收益率异常的债券?
筛选国债收益率大于 2.5 的债券
今天该不该买债?   # advisory policy block; no LLM

API

POST /api/agent/query
Content-Type: application/json

{
  "question": "搜索23附息国债26并给出收益率分析",
  "data_mode": "auto"
}

Streaming (SSE):

POST /api/agent/stream
Content-Type: application/json

{
  "question": "当前债券市场样本概览如何?",
  "data_mode": "static"
}

Events include status (tool steps), token (partial text), and final (soft-render view + result_url).

Operational endpoints:

GET  /healthz
GET  /api/agent/schema
GET  /replay
GET  /packs/<pack_id>.html
GET  /packs/<pack_id>.json
GET  /api/maturity/unmatched

Deployment notes: docs/deployment.md


Data Source Boundary

Primary:        ChinaMoney / AkShare-style spot deal fetch (direct preferred)
Snapshot:       .tmp/bond_spot_deal_snapshot.csv
Final fallback: data/testdata.xlsx
  • Live fields used include bond name, clean price, yield, BP change, weighted yield, volume, and native residual maturity when present (termToMaturity)
  • Residual maturity may still be incomplete → coverage board + trust penalty on weak coverage
  • Cashflow duration / DV01 are teaching-level level-coupon estimates, not OAS / full call-tree valuation
  • Perpetual-style residuals expose dual scenarios (first finite leg + theoretical perpetual), not a multi-century fake tenor
  • No issuer ratings, financial statements, guarantees, or credit events
  • Yield is a risk signal, not a trade instruction

Modes:

auto   -> live first, cached snapshot second, local fallback third
live   -> live source requested; fallback reason shown if it degrades
static -> local Excel only

Why This Is An Agent, Not A Chatbot

  1. Data resolver chooses live / snapshot / static with honest lineage
  2. Planner classifies multi-intent and selects tools
  3. Tools run pure Python analytics over the active frame
  4. Evidence is structured and ledger-backed
  5. Report is composed from evidence with risks and limitations
  6. Optional LLM may narrate only after local evidence exists
  7. Guardrail + judge accept or reject model text
  8. Trust score + Evidence Pack + replay make the run reviewable without dumping raw JSON

If OPENAI_API_KEY is not set, the project still runs with deterministic fallback output.


Appendix: LLM final-answer matrix (recorded)

Current working path (2026-07)

Recorded against local new-api (http://127.0.0.1:31876/v1) with model
deepseek-v4-flash-search, BOND_DATA_MODE=static, temperature=0, one-shot
numeric repair when guardrail fails.
Stable first bond for report questions: 06国开24 (bond-name ascending, mergesort).

Full table: docs/demo_runs/llm_matrix_deepseek_v4.md
· raw: llm_matrix_deepseek_v4.json

Scenario Lang Threshold Result Notes
overview zh 3/3 final LLM 3/3 direct pass
bond report zh 3/3 final LLM 3/3 direct pass
overview en >=2/3 2/3 1 residual invented 5%; repair may recover
bond report en >=2/3 3/3 residual duration%/percentile invents caught by guardrail + repair

Historical grok-4.5 matrix (same thresholds, earlier channel):
docs/demo_runs/llm_matrix_grok45.md.
On this host, gpt-5.4* / grok-4.5 channels are often unavailable or timeout;
deepseek-v4-flash-search is the currently verified chat model.

Honest residuals:

  • Provider channel churn still forces deterministic fallback when models vanish
  • Guardrails stay on; unsupported numbers never become final
  • English overviews may still invent bare shares like 5% under channel noise; prompt + market_focus_numbers reduce this, guardrail still fails closed
  • One-shot repair rewrites only after a failed numeric check; not a free pass
  • End-to-end latency often 8–25s on deepseek; repair path can exceed 40s
  • Soft-render shows a summary card; full dashboard tables remain on result_url
  • Not implemented: WebSocket tick feed, true OAS / full call-tree perpetual pricing, desktop GUI/CLI

This matrix is evidence of a working path, not a zero-bug claim.


Background

This project started as a 2024 undergraduate thesis: a Flask-based bond data analysis system.
The original thesis version is preserved and should not be rewritten:

  • Original thesis branch: undergraduate-thesis-2024
  • Current branch: main

License

MIT

Disclaimer

BondLens is an engineering and research demonstration. It does not provide investment advice,
does not claim complete market coverage, and does not replace professional fixed-income research tools.

Reviews (0)

No results found