以 sub-linear 时间构建 sub-Linear 应用。
运行工作坊前请设置
OPENROUTER_API_KEY。默认情况下,Sublinear 通过 OpenRouter 同时使用聊天模型(deepseek/deepseek-v4-flash)与嵌入模型(openai/text-embedding-3-small),可能产生少量费用(< $0.01)。1. 初始化
从 import、常量与后端配置开始。为简化起见,我们仅使用 SQLite + 内存后端,你也可以按需换成其他后端或继续扩展。main 后端存储实体并支持 SQL 查询;vec 后端存储议题嵌入并支持向量搜索。
embed preset,默认解析为 OpenRouter 上 OpenAI 兼容的 openai/text-embedding-3-small 路由。你可以改用 embed-local,在 Ollama / LM Studio / vLLM 上本地运行小型嵌入模型。
2. 实体定义
从零构建应用时,先用类似 Pydantic 的声明式方式把数据模型想清楚。 在 Sublinear 的设计中,我们有项目(Project)、里程碑(Milestone)和议题(Issue)。项目用于组织工作并设定目标;里程碑是项目检查点,可用于进度跟踪;议题是具体工作项,可分配、打标签、附加 tags,并嵌入以支持语义搜索。我们还有Label 实体存储允许的标签词汇,以及 View 实体存储已保存的过滤与展示偏好。
Label 实体:
使用
.compute 标注由任意 Python 函数计算得到的字段。该函数以初始化输入作为关键字参数,返回将写入字段的转换结果。这里出现新概念
strategy,用于决定字段在后端上的存储方式。即使同一类型存储在同一后端,不同 strategy 也会形成不同的物理布局。例如 hb.SideTable 会把数组存成独立表,用外键关联主表,每个元素一行。作为对比,
display 也是数组字段,但未指定 strategy,因此使用数组默认的 hb.InlineColumn strategy,即在主表中以内联列存储(具体为 TEXT、JSON/JSONB 或 ARRAY,取决于后端)。这里还有新概念
query_compute,用于转换查询时的参数。例如写查询 emb.near("Hello") 时,参数 "Hello" 会先经 embed_text 处理成向量,再与最近的嵌入匹配。3. 工作区构建
创建工作区、注册实体,并种子化标签词汇。Agent 查询这些行,并在项目与议题上存储标签object_id。标签与 tag 数组路由到 SQLite 侧表,因此 labels.array_contains("debugging") 等分析过滤无需单独搜索后端即可工作。
4. Sublinear Agent
工作区构建完成后,可以直接通过 MCP 暴露给 Agent。 任何 Harness(Claude Code、Codex、Copilot 等)都可用来创建 Agent;这里我们用 HeavenBase 简单的LLMSession。向会话添加 MCP 用 session.add_mcp(...);同时可用简洁的系统提示词引导 Agent。
sublinear 已经是一个 Agent 函数,可以回答问题并对 Sublinear 工作区执行命令。
每个会话中,Agent 只面对一个 MCP 表面:HeavenBase 工作区 toolkit。它可写入记录、查询结构化行,并运行语义 near 搜索,直到会话返回内容或达到 max_tool_turns。以下是 Agent 可用接口列表(与 HeavenBase MCP 页面相同):
其中
upsert 最适合创建与整行替换。对 Agent 编辑,set 更方便:Agent 查询现有行后只补丁修改过的字段。
语义搜索的关键是:模型发送的是文本,不是向量。Issue.emb 上的 query_compute(embed_text) 在 HeavenBase 将 near 操作路由到 vec 之前,会把查询字符串转为向量;随后 HeavenBase 从 SQLite 水合匹配的议题行。
语义搜索查询示例:
5. 动手试试
在 docs 仓库根目录运行python workshops/sublinear/sublinear_app.py 试用 Sublinear Agent。
以下脚本向 Sublinear 发送五条用户请求;每条请求使用新会话,但所有会话共享同一持久 HeavenBase 工作区。请求包括:初始化项目、添加议题、认领议题、统计 debugging 议题,以及对 “launch readiness, debugging, and final polish” 做语义搜索。
5.1. 预期行为
五次调用刻意使用独立的LLMSession 实例,表明 Agent 不依赖聊天记忆;每轮通过 MCP 查询同一 HeavenBase 工作区来恢复上下文。
运行过程中,Agent 应:
- 用
upsert创建HB-GUI项目,省略object_id,由 HeavenBase 对项目name做哈希。 - 查询项目与标签词汇,再创建
S1至S7议题,含截止日期、标签、tags 与计算得到的嵌入。 - 用
set补丁S1,仅改assignee与estimate,计算字段保持一致。 - 根据已存储行回答 debugging 数量问题,通常通过过滤
Issue.labels中的debugging标签 ID。JSON 规范可用array_contains;HeavenBase 也会将数组字段上的contains规范为同一操作。 - 对
Issue.emb做文本near查询回答语义搜索问题,返回最接近的相关议题及分数。
成功运行会创建 HB-GUI 项目、添加七条带推断标签 ID 的议题、用
set 将 S1 分配给 Bob、回答 debugging 工作包含 S3 与 S6,并对向量字段使用 near.query 文本,对 launch/debugging/polish 相关议题(如 S6、S7、S2)排序。5.2. 示例回复
模型措辞可能不同,但成功运行应达到以下具体结果:重点不在于回复的逐字措辞。该应用展示单个 Agent 可操作结构化记录、计算字段、将向量路由到向量后端,并查询同一工作区以得到分析答案。

