
IntentKit 团队计费前端与 API 实战Usage 用量页与光标分页实现解析【免费下载链接】intentkitIntentKit is an open-source, self-hosted cloud agent cluster that manages a collaborative team of AI agents for you.项目地址: https://gitcode.com/GitHub_Trending/int/intentkit本篇技术指南聚焦 IntentKit开源自托管的 AI Agent 云集群中「团队计费前端与 API」这一 P2 里程碑对应任务文档 agent_docs/todo/03-billing-frontend-p2.md完整讲解已落地的三个核心能力团队信用余额展示 APIGET /teams/{team_id}/usage、基于光标cursor分页的消费历史查询、以及 intentcat 控制台/team/usage用量页面。读者阅读后将掌握 IntentKit 团队侧计费端点的请求参数与响应结构、底层信用账户CreditAccount与信用事件CreditEvent的数据模型、光标分页的实现原理并清晰了解 P2 剩余的待办路线图。一、任务背景P2 在整个计费体系中的定位IntentKit 的计费体系分为多个递进的里程碑。P1定价计划与 Stripe 集成见 agent_docs/todo/02-pricing-plans-p1.md已完成了TeamPlan枚举NONE/FREE/PRO/MAX、计划配额分配、月度计划信用发放issue_all_plan_credits()与计划过期跟踪等数据与调度层能力P2 则是在此之上的「计费前端与 API」层目标是让团队用户在控制台中直观地看到自己团队的信用余额与消费流水。从任务文档看P2 当前状态为PARTIALLY COMPLETED部分完成已完成三件事团队信用余额展示GET /teams/{team_id}/usageAPI 端点团队消费历史带光标分页的最近事件列表intentcat 中的用量页面/team/usage包含信用条credit bars与活动日志activity log剩余部分仍为 TBD团队充值/充值流程依赖 P1 的 Stripe、套餐管理 UI、发票/账单历史、按 Agent 拆分的用量分析仪表盘、事件加载更多分页 UI。二、核心 APIGET /teams/{team_id}/usage该端点是整个用量页面的数据来源实现在 app/team/usage.py 中属于team_usage_router标签Billing并被挂载到独立的 Team API 服务上见 app/team/api.py 与include_router(team_usage_router)的注册逻辑。2.1 请求参数参数类型位置默认值说明team_idstr路径必填团队 IDdirectionDirection 枚举query无按资金流向过滤income/expenseevent_typeEventType 枚举query无按事件类型过滤见下方枚举cursorstrquery无分页游标上一页返回的next_cursorlimitintquery50每页事件条数范围ge1, le100参数中的direction与event_type对应 intentkit/models/credit/event.py 中的枚举定义DirectionINCOME income收入、EXPENSE expense支出EventTypememory、message、tool_call、media、knowledge_base、recharge充值、refund退款、adjustment调整、refill免费额度补充、withdraw提现、reward、event_reward、recharge_bonus、plan_credit计划信用其中plan_credit正是 P1 中每月计划信用发放所产生的事件类型与上游issue_all_plan_credits()闭环呼应。2.2 响应结构端点返回UsageResponsePydantic 模型序列化为 JSON{ account: { id: …, owner_type: team, owner_id: …, free_quota: 5000, refill_amount: 5000, free_credits: 1234.5678, reward_credits: 0, credits: 0, income_at: 2026-09-16T06:00:00.000Z, expense_at: 2026-09-16T06:30:00.000Z, last_event_id: …, total_income: 5000, total_expense: 3765.4322 }, events: [ { id: …, account_id: …, event_type: tool_call, team_id: …, upstream_type: executor, upstream_tx_id: …, direction: expense, total_amount: 12.5, credit_type: free, tool_name: search_web, balance_after: 1890.25, note: …, created_at: 2026-09-16T06:25:00.000Z } ], next_cursor: …, has_more: false }字段说明account团队信用账户CreditAccount核心余额字段为free_credits当日可用免费额度、reward_credits奖励积分、credits充值积分代码中还定义了balance属性即三者之和见 intentkit/models/credit/account.py。events按时间倒序的信用事件列表CreditEvent。next_cursor下一页游标即本页最后一条事件的 IDhas_more标记是否还有更多数据。所有金额字段统一保留 4 位小数Decimal(0.0001)ROUND_HALF_UP 四舍五入由round_decimal校验器保证避免浮点误差累积。2.3 边界行为端点实现中有两个值得注意的边界处理见 app/team/usage.py若团队账户不存在CreditAccount.get_in_session抛出IntentKitAPIErroraccount返回nullevents返回空数组、has_morefalse、next_cursornull而不是直接 500 或 404保证前端拿到稳定的空态结构认证使用Depends(verify_team_member)只有团队真实成员才能访问该团队的用量数据非成员会收到 403NotTeamMember见 app/team/auth.py。三、消费历史与光标分页的实现原理GET /teams/{team_id}/usage内部委托给list_credit_events_by_team()实现在 intentkit/core/credit/list_events.py这是整个分页逻辑的核心。3.1 数据模型信用账户与信用事件分页查询依赖两张表credit_accountsintentkit/models/credit/account.py按(owner_type, owner_id)唯一定位账户团队账户的owner_type为team。表中还维护了total_income、total_free_income、total_expense等累计统计字段供用量页顶部的汇总展示直接读取。credit_eventsintentkit/models/credit/event.py记录每笔业务事件关键列包括direction、event_type、total_amount、balance_after、agent_id、tool_name、model、upstream_type/upstream_tx_id等并通过(upstream_type, upstream_tx_id)唯一索引保证幂等check_upstream_tx_id_exists会拒绝重复提交。团队在创建信用账户时其free_quota与refill_amount会自动读取团队当前套餐的PLAN_CONFIGS见 intentkit/models/credit/account.py 中create_in_session对TeamPlan的读取逻辑这正是 P1 与 P2 的衔接点套餐决定额度用量页展示额度消耗。3.2 光标分页算法list_credit_events_by_team的实现要点先按OwnerType.TEAM team_id查出团队账户不存在则返回空结果构造查询WHERE account_id 账户ID按id倒序LIMIT limit 1多取一条用于判断是否还有下一页可选过滤direction精确匹配、event_type精确匹配、cursor使用id cursor因为是倒序下一页取比游标更小的 ID判断has_more len(结果) limit只返回前limit条next_cursor仅在has_more为真时取本页最后一条的 ID否则为null。这种「ID 即游标」的方案相比OFFSET分页的优势是不依赖行号偏移并发写入下也不会出现翻页重复或遗漏且走主键索引性能稳定。同文件中还有面向用户的list_credit_events默认directionEXPENSE、升序、支持created_at时间区间过滤与面向 Agent 分润的list_fee_events_by_agent可作为实现其他计费列表的参考。3.3 上游链路的幂等保证每条消费事件都带有upstream_typeapi/scheduler/executor/initializer与upstream_tx_id并在credit_events表上有唯一索引。这意味着用量页上看到的每条记录都对应一次确凿的上游业务动作一次工具调用、一条消息、一次计划信用发放等既可用于对账也防止重放扣费。这也解释了为什么消费历史能直接作为活动日志展示——事件本身已经携带了tool_name、model、note等业务上下文。四、前端intentcat /team/usage 用量页根据任务文档/team/usage用量页属于 intentcat独立的前端控制台项目不在本仓库的frontend/目录中。该页面已实现两大区块信用条credit bars以可视化条形展示free_credits、reward_credits、credits三种余额的占比数据直接对应UsageResponse.account的余额字段活动日志activity log渲染events列表按时间倒序展示每笔消费/收入包含事件类型、金额与业务上下文。从 API 能力反推页面交互设计要点首次进入调用无cursor的请求拿到第一页 50 条下拉或点击加载更多时携带next_cursor继续请求页面顶部提供方向与事件类型筛选对应direction/event_type查询参数当has_morefalse时隐藏加载入口避免无效请求。五、剩余路线图TBD与扩展建议任务文档明确列出了 P2 尚未完成的部分这也为后续开发者提供了清晰的实现顺序团队充值/充值流程依赖 P1 的 Stripe 集成。落地后充值产生的recharge/recharge_bonus事件会自动进入credit_events无需改动用量 API 即可在活动日志中自然呈现套餐管理 UI展示当前套餐NONE/FREE/PRO/MAX及升级/降级入口可复用TeamTable.plan、plan_expires_at、next_credit_issue_at字段P1 已完成发票 / 账单历史可基于credit_events中的recharge、refund类型事件聚合生成用量分析仪表盘按 Agent 拆分events[].agent_id已就绪、成本趋势events[].created_at按时间聚合所需的数据字段当前都已存在于事件模型中事件加载更多分页 UI后端next_cursor/has_more已完整支持前端只需补交互。从实现角度看TBD 项大多可以复用现有数据基础设施尤其是统一的credit_events事件流这让计费相关功能的横向扩展成本大幅降低。六、快速验证本地启动 Team API 服务后可通过如下方式验证用量端点# 携带团队成员的 Supabase JWT 访问 curl -H Authorization: Bearer JWT \ http://localhost:8000/teams/team_id/usage?limit20 # 带过滤与分页 curl -H Authorization: Bearer JWT \ http://localhost:8000/teams/team_id/usage?directionexpenseevent_typetool_calllimit50响应中的next_cursor可在下一次请求中作为cursor参数传入以翻页。注意本地开发模式config.debugTrue下可先用debugtoken 模拟system用户见 app/team/auth.py便于快速调试。总结IntentKit 的 P2 里程碑已为团队计费打下坚实的前端与 API 基础GET /teams/{team_id}/usage用一处端点同时承载了余额展示与光标分页的消费历史底层有设计严谨的CreditAccount余额模型、带幂等约束的CreditEvent事件流以及 ID 游标分页算法支撑/team/usage用量页则将其转化为信用条与活动日志两个直观视图。剩余的充值、套餐管理、发票与分析仪表盘虽列为 TBD但数据层已为其铺好道路是沿着事件流模型继续扩展的典型增量任务。【免费下载链接】intentkitIntentKit is an open-source, self-hosted cloud agent cluster that manages a collaborative team of AI agents for you.项目地址: https://gitcode.com/GitHub_Trending/int/intentkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考