LumiBot / agent 权限
LumiBot 的 agent 权限:allow_trading 关掉后,是 5 个工具直接消失
很多「AI 交易」介绍的写法是「给它一个提示词,它就会自己下单」。LumiBot 的实现方式更具体也更笨拙:agent 能做什么,由你创建它时传入的 allow_trading 决定。设成 False,框架会把 5 个会改变账户状态的工具从该 agent 的工具集里整个移除——不是运行时拦截、不是报错提示,而是它根本看不到这些工具。
这一页把分界线逐项列出来:哪些工具被摘掉、哪些只读工具仍然保留、以及即使开了交易权限也不能盲下单的原因(官方要求 agent 在同一轮里先看过账户、持仓和市价,缺一项就只会拿到 ORDER_READINESS_REQUIRED 而不下单)。
最后还列了 6 类真实误用,以及一个最容易混淆的点:LumiBot 自己也有一个叫 skills 的目录,但它和本机技能路线的技能体系是两套完全无关的东西。
权限开关的两侧
示意:同一个 create 参数决定工具集
docs/AI_AGENT_BUILTIN_TOOLS.md,2026-09-22 采集)。工具清单以官方文档与仓库实现为准。一个 create 调用里,哪几个参数真正决定行为?
agent 不是全局对象,而是挂在策略实例上的成员:self.agents.create(...)。它在哪个生命周期方法里被创建、用哪个模型、有没有交易权限,全部由这一次调用决定。
| 参数 / 属性 | 作用 | 取值示例 | 注意点 |
|---|---|---|---|
name | agent 的标识,之后用 self.agents["名字"] 调用 | "researcher" / "trader" | 名字会写进记忆事件与产物,起得有辨识度便于复盘 |
model | 该 agent 使用的模型 | 任意 LiteLLM / ADK 支持的 provider 字符串 | 可逐 agent 指定不同模型;官方文档强调「默认字符串不等于可用性承诺」,能不能调用取决于你的 Key 与配额 |
allow_trading | 是否把变更类订单工具交给这个 agent | True / False | 关掉时被移除的是 5 个具体工具(见下一节),不是「屏蔽提示」 |
system_prompt | 给该 agent 的角色约束 | "只指出风险与反对理由。" | 角色分工靠提示词,权限分工靠参数——两者要一起用,别只靠提示词「请求」它不要下单 |
| 创建位置 | 决定 agent 何时可用 | initialize() / on_trading_iteration() / on_filled_order() | 官方推荐在 initialize() 里创建;在每次循环里重复创建会重复消耗创建与模型调用 |
| 默认模型 | 不显式传 model 时的取值 | gemini-3.5-flash-lite | 默认只影响新建的 agent;官方说明不会在工具循环中静默迁移已有 agent 的模型 |
被摘掉的 5 个工具,与仍然保留的只读工具
下表左边是「会改变账户状态」的工具,右边是「只读取状态」的工具。前者受 allow_trading 控制,后者不受影响。
| 工具 | 它做什么 | allow_trading=False 时 | 注意点 |
|---|---|---|---|
orders_submit_order | 提交单个订单 | 被移除 | 不是「提交时被拒绝」,而是这个工具根本不在该 agent 的工具集里 |
orders_submit_multileg | 原子提交多腿期权 | 被移除 | 官方语义是 fail closed:券商不支持整包提交时,在提交任何一条腿之前就拒绝,绝不拆成子订单 |
orders_cancel_order | 撤销挂单 | 被移除 | 只读 agent 无法「先撤再挂」——这正是它只读的含义 |
orders_modify_order | 修改挂单 | 被移除 | 改价、改量都属变更类操作 |
remember_decision | 写下最终交易决策 | 被移除 | 只读 agent 仍可用 remember / remember_proposal / remember_risk_note,所以「研究员能留笔记、不能拍板」是可实现的 |
orders_get_status | 读订单当前状态 | 保留 | 判断成交要看这里的 is_filled,见下单与成交 |
orders_open_orders | 列出未结订单 | 保留 | 只读 agent 仍能掌握「当前有多少挂单」 |
orders_wait_for_terminal | 有界等待订单进入终态 | 保留 | 上限 120 秒;超时不等于成交 |
account_portfolio / account_positions | 读组合与持仓 | 保留 | 它们同时是下单就绪检查的前置项,见下一节 |
allow_trading=False 理解成「agent 会请求下单、但被拒绝」。实际机制是能力切除——该 agent 的工具集里没有这些工具,所以它连「尝试」这一步都不会发生。反过来说,不要因为「agent 说自己没有下单」就认为它真的没有交易权限:权限由创建参数决定,不由它的自述决定。以官方工具文档为准。即使开了交易权限,agent 也不能盲下单
官方在订单工具上装了一道前置检查:提交订单前,agent 必须在同一次 run 内先读过账户组合、持仓和该标的的市价。缺任何一项,订单工具返回结构化错误 ORDER_READINESS_REQUIRED,而不是把订单发出去。
| 检查项 | 必须在何时做 | 缺少时的行为 | 注意点 |
|---|---|---|---|
account_portfolio | 同一次 agent run 内,提交之前 | 返回 ORDER_READINESS_REQUIRED,订单不提交 | 用途是拿到现金与组合总值,供 agent 自己算仓位 |
account_positions | 同一次 agent run 内,提交之前 | 同上 | 期权持仓会带合约字段、带符号数量、均价、市值与盈亏,便于重建多腿仓位 |
market_last_price | 针对被下单的那个 symbol | 同上 | 单个 symbol 一次调用 |
market_last_prices | 批量扫描时使用;批量里必须包含要下单的 symbol | 同上 | symbols 上限 150,返回里带 symbols_available / symbols_missing,缺失的不要自己编价格 |
| 框架的额外约束一 | — | — | 不静默调整下单量:agent 提交多少就是多少,框架不会替你缩量或补量 |
| 框架的额外约束二 | — | — | 不跨资产类别套用统一保证金规则:股票、期权、期货的保证金逻辑不同,需要 agent 或你的 Python 闸门自行处理 |
这道门解决的是「模型不看账就下单」
大模型很容易在只看到行情的情况下就把「买 10 股」写出来。就绪门强制它在同一轮里先读账户和持仓,让下单量至少建立在「看过现金」这一步之上。它是一个纪律检查,不是一个风控引擎。
这道门不解决「模型算错仓位」
框架只确认「你看过」,不确认「你算对」。仓位上限、单标的最大占比、止损规则仍然要你自己写进系统提示词或确定性 Python 闸门里。官方也提供了 5 份 .rules.json 确定性规则作为混合形态的示例。
内置工具分组清单:能读什么、明确不做什么
agent 的能力边界由工具集决定。下面按官方文档把内置工具分组列出。注意「能读」和「能做」是两件事——期权类工具只负责取数据,不替你选策略或选腿。
| 分组 | 代表工具 | 能读到 / 能做到 | 明确不做什么 | 注意点 |
|---|---|---|---|---|
| 账户与组合 | account_portfolio、account_positions | 现金、组合总值、持仓明细(含期权合约字段与盈亏) | 不替你计算目标仓位 | 是下单就绪门的必查项 |
| 行情与历史 | market_last_price、market_last_prices、market_load_history_table | 最新价与历史表 | 历史表一次只加载一个 symbol | 官方建议用 DuckDB 做时序分析,而不是把大量 K 线塞进提示词 |
| 期权链与希腊值 | options_get_chain、options_get_strikes、options_get_greeks、options_find_strike_for_delta、options_find_expiration、options_evaluate_market、options_calculate_multileg_price、options_check_spread_profit | 链、行权价、希腊值、按 delta 找行权价、按日期找到期、多腿定价与价差收益估算 | 不选策略、不选腿 | 8 个工具全部是取数与计算;策略与腿仍由 agent 或你的规则决定 |
| 时序查询 | DuckDB 工具 | 对历史数据做 SQL 查询 | 不是万能数据库 | 官方把它定位为「不要把原始 K 线灌进提示词」的替代路径 |
| 文档检索 | Lumibot 文档检索工具 | 在官方文档范围内检索 | 不检索互联网 | 适合让 agent 自查 API 用法 |
| 新闻(Alpaca) | alpaca_news | Alpaca 侧新闻 | 两条路都没有时该工具不暴露 | 需要有活跃 Alpaca broker,或配好 ALPACA_NEWS_API_KEY / ALPACA_NEWS_API_SECRET |
| 技术指标 | list_indicators、get_indicator、get_indicators | 按参数与时间窗取指标 | 不保证你自定义函数的时间安全 | 官方单独发了一份指标时间安全说明,见未来函数与时间安全 |
| 基本面与文件(SEC) | SEC 基本面与申报文件工具 | 基本面数据与申报文件 | 不替代你自己读全文做判断 | 数据来源与可用范围以官方文档为准 |
| 宏观(FRED) | list_fred_series、get_fred_series、get_fred_latest、get_fred_snapshot | 官方 FRED / ALFRED 观测值(带 realtime 口径) | 不使用公开 CSV 回退 | 需要 FRED_API_KEY;官方说明公开端点含修订值,对历史模拟不安全 |
| 记忆 | remember、search_memory、remember_lesson、open_thesis 等 | 跨轮次保存与检索提案、风险笔记、决策、教训 | 不改变市场状态 | remember_decision 只属于有交易权限的 agent,见记忆与回放 |
| 通知 | notify_user | 把消息推给你 | 不是交易指令 | 渠道配置以官方文档为准 |
| 订单 | orders_submit_order、orders_get_status、orders_wait_for_terminal 等 | 提交与查询订单 | 不保证成交 | 受 allow_trading 与就绪门双重约束 |
LumiBot 自己也有 skills 目录,但它和本机技能路线的技能是两套东西
LumiBot 把「agent 在做决定前应该先读什么」写成了自己的运行时技能,放在仓库 lumibot/components/agents/skills/ 下,并随 wheel 一起发布。名字和本机技能路线里的技能一样,来源、加载方式、覆盖范围都不一样。
LumiBot 自带的 3 个运行时技能(每个含 SKILL.md 与 agents/*.yaml,其中两个另带 references/):
options-trading— 在涉及期权的研究、选合约、开平仓之前应加载;描述里明确覆盖单腿与多腿结构(价差、铁鹰、蝶式、跨式、日历等),并说明「即使你没提到期权,只要更宽的任务可能用到期权也要先加载」。附带的 references 覆盖常见结构、合约与希腊值流动性、多腿订单、持仓管理。research-data— 在使用 BotSpot 公开的宏观、监管、财政、劳动、经济、资金与持仓、SEC 文件类研究工具之前应加载;描述明确这些工具是只读证据源,不暴露券商账户、实时价格、付费新闻或交易动作。工作流里还特别提醒:先查目录拿到的是元数据,不要当观测值引用。stock-trading— 在涉及股票/ETF 的研究、选标的、开平仓之前应加载;覆盖自主投资、轮动、突破、动量、均值回归、开盘区间突破、VWAP 等形态,核心工作流第一步就是读组合价值、现金、当前持仓与未结订单。
| 术语 | 在 LumiBot 里指什么 | 本机技能路线里有没有对应物 | 注意点 |
|---|---|---|---|
skills | agent 在决策前按需加载的运行时技能(本机实测:3 个,且随 PyPI wheel 一起发布) | 本机技能路线另有自己的技能目录与体系 | 名字相同,来源与加载机制不同;两者之间没有已证实集成 |
agent | 由 self.agents.create 创建、在策略生命周期内被调用的对象 | 本机技能路线是对话式助手,不是策略对象 | 不要因为都叫「智能体」就把两者的能力范围等同 |
tools | agent 可调用的内置工具(账户、行情、期权、记忆、通知、订单…) | 本机技能通过脚本或 MCP 调用外部能力 | 工具名与覆盖范围两边不同,不存在「同名即同能力」 |
memory | 运行期 SQLite 存储,另导出三个 Parquet 产物用于复盘 | 无同类审计产物的通用机制 | 复盘能力是本项目的一个强项,见记忆与回放 |
rules | example_strategies/agent_rules/*.rules.json 共 5 份确定性规则文件 | 无此机制 | 它是「AI 推理 + Python 闸门」混合形态的示例,不是策略有效性证明 |
Strategy | 回测与实盘共用的策略基类 | 无对应物 | 回测与实盘同码的载体,差异见回测与实盘一致性 |
一个能读的最小写法,和 7 类真实误用
下面这段是「研究员 + 反方 + 交易员」的最小结构,重点是权限怎么切。它是结构示意,不是可复制即用的完整策略;模型 Key、券商凭据与参数都需要你按自己的情况配置。
class AITeamStrategy(Strategy):
parameters = {"symbol": "SPY", "max_position_pct": 10}
def initialize(self):
self.sleeptime = "1D"
model = os.environ.get("AI_TEAM_MODEL", "gemini-3.5-flash-lite")
# 只读:能研究、能留笔记,工具集里没有下单类工具
self.agents.create(name="researcher", model=model,
allow_trading=False,
system_prompt="整理证据,给出结论。")
# 只读:只负责反对
self.agents.create(name="bear", model=model,
allow_trading=False,
system_prompt="只指出风险与反对理由。")
# 唯一可交易的 agent
self.agents.create(name="trader", model=model,
allow_trading=True,
system_prompt="在看过的现金与持仓范围内下单。")
def on_trading_iteration(self):
# 禁止 datetime.now();必须用 self.get_datetime()
today = self.get_datetime().date().isoformat()
research = self.agents["researcher"].run(
task_prompt="研究今日标的。", context={"date": today})
bear = self.agents["bear"].run(
task_prompt="反驳上面的结论。",
context={"date": today, "research": research.summary})
self.agents["trader"].run(
task_prompt="根据证据决定是否下单。",
context={"date": today, "research": research.summary,
"bear": bear.summary})
| 现象 | 真实原因 | 怎么确认 | 注意点 |
|---|---|---|---|
| 以为「研究员 agent 也会下单」 | allow_trading=False 时 5 个变更类工具根本不在工具集里 | 检查该 agent 实际可见的工具清单 | 这是能力切除,不是运行时拦截;反之也不要靠 agent 自述判断它有没有权限 |
agent 返回 ORDER_READINESS_REQUIRED | 同一次 run 内没有先读账户组合 / 持仓 / 该标的市价 | 回看该轮的工具调用序列 | 框架拒绝下单而不是自动补量;这属于设计行为 |
| 回测与实盘行为不一致,或提示类型检查异常 | 策略里用了 datetime.now() / datetime.today(),或写了 from __future__ import annotations | 在策略文件里检索这两个模式 | 官方 llms.txt 把这两条列为面向代码生成的硬规则;第一条正是未来函数的常见来源 |
| 批量取价报错,或部分标的没有价格 | market_last_prices 的 symbols 超过 150 个,或用 market_load_history_table 一次传了多个 symbol | 看返回里的 symbols_available / symbols_missing | 缺失的标的不要自己编价格,先缩小标的池或分批扫描 |
找不到 alpaca_news 工具 | 既没有活跃的 Alpaca broker,也没有配置 ALPACA_NEWS_API_KEY / ALPACA_NEWS_API_SECRET | 看该工具是否出现在该 agent 的工具清单里 | 官方说明:两条路都没有时该工具不暴露,不是报错 |
| 以为模型会自己挑好期权腿 | 8 个期权工具只取数据与算价,官方明确不选策略、不选腿 | 读工具说明与输出字段 | 选腿要么写进系统提示词,要么用确定性规则文件约束 |
| 模型调用次数与费用失控 | 没有设置调用上限类环境变量 | 检查 LUMIBOT_AGENT_MAX_MODEL_CALLS、LUMIBOT_AGENT_MAX_RUN_ATTEMPTS 是否配置 | 这两个变量出现在官方环境变量文档里;默认值与生效范围以官方文档为准 |
关于 LumiBot agent 权限的高频问题
以下回答基于 2026-09-22 对官方仓库文档与本机 wheel 内容的核对;涉及具体工具行为的部分以官方 docs/AI_AGENT_BUILTIN_TOOLS.md 与仓库实现为准。本站未实盘下单,不做收益声明。
allow_trading=False 之后,agent 还能干什么?
仍然可以读账户组合与持仓、查行情与历史、取期权链与希腊值、查技术指标、读 SEC 基本面与申报文件、取 FRED 宏观观测值、检索官方文档、跑 DuckDB 查询、写与检索记忆、发通知,以及查询订单状态(orders_get_status、orders_open_orders、orders_wait_for_terminal)。被移除的只有 5 个会改变账户状态的工具。也就是说「只读 agent 只能聊聊天」是错的,它的信息面很宽,只是不能动手。具体清单以官方文档为准。
只靠系统提示词写「不要下单」行不行?
不建议。本站核到的机制里,权限是结构性的:allow_trading=False 直接把工具从工具集里去掉,而系统提示词只是模型层面的约束。两者应该一起用——参数负责「能不能」,提示词负责「该不该」。把关键约束放在结构里,而不是放在希望模型听话上,这也是官方示例把前三个 agent 全部设成只读的原因。
为什么 agent 明明有交易权限,却什么都没买?
先看它有没有过就绪门。提交订单前,agent 必须在同一次 run 内读账户组合、持仓和该标的市价;缺任何一项,订单工具返回 ORDER_READINESS_REQUIRED,订单不会发出。另外还有两种常见原因:模型在系统提示词约束下选择了不下单,或者数据源/券商侧缺少必要凭据导致取价失败。排查顺序建议是「看工具调用序列 → 看错误码 → 再看模型输出」。具体判定以官方实现为准。
它会不会自己决定下单数量?
不会。官方明确写出两条约束:框架不静默调整下单量,也不跨资产类别套用统一保证金规则。这意味着下单量是 agent(或你的代码)算出来的;如果你希望有硬上限,应该写进系统提示词,或用确定性 Python 闸门与 .rules.json 这类规则文件约束。本页的示例里只写了「在看过的现金与持仓范围内下单」这类文字约束,它不构成风控保证。
LumiBot 自带的 3 个技能,和我本机的技能是一回事吗?
不是。LumiBot 的运行时技能在 lumibot/components/agents/skills/ 下(本机实测三个:options-trading、research-data、stock-trading),随 PyPI wheel 一起发布,由 LumiBot 的 agent 运行时按需加载;本机技能路线有自己的技能目录与加载方式。两者名字相同,来源与机制不同,且本站未发现两者之间存在已证明的集成。看到「skill」这个词时,先问它是哪一套体系里的。
agent 支持哪些模型?会不会自动换成别的?
可以逐个 agent 指定模型字符串(官方说明支持 LiteLLM / ADK 支持的 provider 形式)。不显式指定时默认是 gemini-3.5-flash-lite,但这个默认只影响新建的 agent——官方明确不会在工具循环中静默迁移已有 agent 的模型。另外官方也提示:默认字符串不等于可用性承诺,实际能不能调用取决于你的 provider 配置、配额与计费状态。以官方 docs/AGENT_DEFAULT_MODEL.md 与你的 provider 文档为准。
agent 可以在哪些时机运行?会不会拖慢回测?
官方示例与文档给出的运行位置包括 initialize()、on_trading_iteration()、on_filled_order() 等生命周期方法。这一点对回测成本很关键:每次调用都可能产生一次模型调用,回测区间的每一根 K 线都调用 agent 会把费用和耗时同时放大。官方为此提供了把已保存决策回放的机制(缓存回放后不需要再次付费调用),具体效果以官方实现为准,见记忆与回放。