BondLens
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.
BondLens: evidence-first Chinese bond analysis agent — deterministic tools, optional LLM narration under guardrails, Trust Layer, live/snapshot/static data, Docker/CI. 面向中文债市的证据优先分析智能体。
BondLens: An Evidence-First Bond Analysis Agent for Chinese Market Data
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:
- Resolve data (live AkShare → cached snapshot → local Excel)
- Plan intent (overview / search / ranking / outliers / monitor / composite / bond report)
- Run deterministic tools
- Build structured evidence (market, peer, monitor, quality, maturity coverage)
- Compose a report with risk notes and mandatory limitations
- Optionally polish with an LLM under numeric + language guardrails
- 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
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:
- Trust is process/evidence confidence, not trade confidence.
- Advisory is a policy block (no LLM), not a disclaimer-only soft refuse.
- Numbers come from tools; if the model fails guardrail, the final answer is deterministic.
Older workbench images remain under docs/screenshots/ for history only.
Can answer — market overview 当前债券市场样本概览如何?
|
Can go deep — single-bond report 请对样本中第一只债券生成分析报告
|
Will refuse — advisory policy block 今天该不该买债? → Trust ≤72, no LLM
|
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|enquery wins, thenbondlens_langcookie, elsezh - 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
- Data resolver chooses live / snapshot / static with honest lineage
- Planner classifies multi-intent and selects tools
- Tools run pure Python analytics over the active frame
- Evidence is structured and ledger-backed
- Report is composed from evidence with risks and limitations
- Optional LLM may narrate only after local evidence exists
- Guardrail + judge accept or reject model text
- 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 modeldeepseek-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_numbersreduce 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)
Sign in to leave a review.
Leave a reviewNo results found