这篇 App Showcase 文章是用于评估快速开始候选的 AI 生成测试博客;请把它视为应用指导草稿,而不是最终产品文档或财务建议。
AI 生成测试博客 - HeavenBase Team - 2026 年 6 月 23 日 - 约 1,250 字 - 阅读约 7 分钟
有些有用的应用一开始只是一个简单看板。你有几行数据、几个数字,以及一个不想每次都打开电子表格才能回答的问题。
Portfolio Risk Board 是面向这种模式的小型 HeavenBase 教程。示例使用样例组合数据,但课程更宽泛:存储事实,计算一个有用值,查询需要关注的行,并把看板导出给智能体客户端。
1. 背景和目标
这不是投资模型。目标是展示一个本地计划看板,它有足够结构来回答简单问题。如果你不熟悉组合,可以把“持仓”读作“我持有的一项东西”,把“敞口”读作“这项东西在样例里值多少”。
本教程会构建一个看板,它可以:
- 存储几条持仓
- 从份额和价格计算敞口
- 存储自然语言情景笔记
- 显示需要较高复核关注的持仓
- 生成 MCP JSON,让智能体客户端检查同一个工作区
结果刻意保持克制。第一个有用应用应该先帮助你行动,再尝试成为完整平台。
2. 场景和设定
我们会使用一位虚构用户 Alex。Alex 有三行:现金、一个成长权益持仓和一个债券持仓。Alex 还写了两条情景笔记:如果利率继续偏高该怎么办,以及如果需要现金该怎么办。
| Item | Plain Meaning | Why It Is in the Demo |
|---|
| CASH | A cash bucket. | It keeps the example grounded. |
| GRO | A sample growth holding. | It has the highest review risk. |
| BND | A sample bond holding. | It gives the board a lower-risk comparison. |
应用应该回答两个问题:“什么需要复核?”以及“整个看板当前代表多少规模?”
样例 ticker 和数字都是虚构工作流数据。不要把本教程视为财务建议。
3. Step 1:打开工作区
社区示例使用和其他 App Showcase demo 相同的本地工作区 helper。
import heavenbase as hb
from community_runtime import demo_workspace, parse_reset, print_frame, seed
WS_ID = "community-app-portfolio-risk-board"
ws, _ = demo_workspace(WS_ID, "apps-portfolio-risk-board", parse_reset())
ws.enable_extension("agent")
启用 agent 扩展是因为最后一步会导出面向智能体的配置。应用仍然从普通类型化数据开始。
4. Step 2:定义持仓和情景
先定义一个很小的计算函数。在这个 demo 里,敞口表示 shares * price。
def exposure(shares: float | None, price: float | None) -> float:
return float(shares or 0.0) * float(price or 0.0)
class Position(hb.Entity):
"""Portfolio position."""
ticker = hb.field(hb.ShortText).desc("Ticker")
asset_class = hb.field(hb.ShortText).desc("Asset class")
shares = hb.field(hb.Float).desc("Units")
price = hb.field(hb.Float).desc("Price per unit")
risk = hb.field(hb.Integer).desc("1 is defensive, 5 is speculative")
exposure = hb.field(hb.Float).compute(exposure, inputs=["shares", "price"])
class Scenario(hb.Entity):
"""Stress scenario note."""
name = hb.field(hb.ShortText).desc("Scenario name")
assumption = hb.field(hb.LongText).desc("Assumption")
action = hb.field(hb.LongText).desc("Planned action")
这是本教程里的核心 HeavenBase 思路:一行可以同时包含你输入的事实,以及应用为你计算的事实。
5. Step 3:加入样例行
注册两种卡片类型,并加入三条持仓和两条情景笔记。
ws.register(Position)
ws.register(Scenario)
seed(
ws,
Position,
[
{"object_id": "cash", "ticker": "CASH", "asset_class": "cash", "shares": 12000.0, "price": 1.0, "risk": 1},
{"object_id": "growth", "ticker": "GRO", "asset_class": "equity", "shares": 80.0, "price": 72.0, "risk": 4},
{"object_id": "bond", "ticker": "BND", "asset_class": "bond", "shares": 50.0, "price": 91.0, "risk": 2},
],
)
seed(
ws,
Scenario,
[
{"object_id": "rate-shock", "name": "Rate shock", "assumption": "Rates stay higher for two quarters.", "action": "Do not add duration until allocation review."},
{"object_id": "cash-need", "name": "Cash need", "assumption": "Unexpected 5000 expense.", "action": "Use cash bucket first."},
],
)
你不需要手动输入 exposure。HeavenBase 会在写入行时,根据 shares 和 price 计算它。
6. Step 4:询问什么需要复核
现在查询复核风险为 3 或更高的持仓,并从已存储行计算总敞口。
risky = (
ws.query(Position)
.where(Position.risk >= 3)
.select("ticker", "asset_class", "exposure", "risk")
.execute()
)
total = round(sum(row["exposure"] for row in ws.rows(Position)), 2)
输出小到可以一眼读完:
Higher-risk exposure
object_id | ticker | asset_class | exposure | risk
--------------------------------------------------
'growth' | 'GRO' | 'equity' | 5760.0 | 4
Total exposure: 22310.0
有用的部分不是具体数字。有用的部分是这个模式:计算一次值,然后像查询其他字段一样查询它。
7. Step 5:把看板导出给智能体客户端
最后一步向 HeavenBase 请求 MCP 客户端 JSON。这会给另一个工具,例如智能体 harness,一种连接同一个工作区的方式。
config_json = ws.to_mcp_json(
name="portfolio-board",
profile="agent",
host="127.0.0.1",
port=7040,
)
print(config_json.splitlines()[0])
在真实应用中,你会把它和更窄的 profile 以及谨慎的 prompt 配对。对这个原型来说,重点是看板不需要为智能体访问重新构建。
成功运行后,它会显示较高风险行,打印总敞口,并输出 MCP JSON 配置的第一行。
8. 这篇教程教了什么
Portfolio Risk Board 适合作为快速开始候选,因为它展示了一个非聊天工作流。HeavenBase 不只是用于智能体对话;它也可以保存日常结构化数据和计算字段。
下一个版本可以加入配置目标、复核日期、情景标签,或者一个只读智能体 profile,让它可以解释看板但不能编辑行。
Try It
在社区示例 checkout 中运行:
rtk bash scripts/run.bash apps.portfolio_risk_board
把这些数字视为样例数据。可复用的模式是计算后的运营状态,加上一条受限的智能体访问路径。
Further Exploration