Dexter 循环拆解:复刻金融任务分解的 4 个关键点
【免费下载链接】dexterAn autonomous agent for deep financial research项目地址: https://gitcode.com/GitHub_Trending/dexter19/dexter
Dexter 是一款面向深度金融研究的自主智能体,它的任务分解核心,是 src/agent/agent.ts 里一个朴素的循环:问模型、跑工具、把结果塞回上下文,如此往复。本文沿一次完整调用,讲清写一个同类金融 Agent 前必须先想明白的四个决策。
提问前上下文里装了什么:工具注册表与提示词策略
大部分"拆解"不写在代码里,写在提示词里。循环启动前,系统提示词被注入三类内容:
- 工具注册表:src/tools/registry.ts 把全部工具列在一处——
get_financials管财报、get_market_data管价格与新闻、read_filings管 SEC 文件、stock_screener管条件筛选。每条带 1~2 句compactDescription和一个concurrencySafe标记(能否并行)。注册表还按环境变量动态组装:配了 Exa 或 Tavily 的 key 才会出现web_search。 - 工具使用策略:写死在 src/agent/prompts.ts 的系统提示词里,最硬的一条是"调 get_financials 时把完整自然语言问题一次发出,不要拆成多次调用"——它直接决定模型是拆解得当还是狂刷调用。
- 用户规则:
.dexter/RULES.md与SOUL.md存在即注入,个人研究习惯对每次提问生效。
模型选哪个工具并非算法匹配,而是读着工具说明自主决定。想改拆解习惯,从这层下手。
主循环体是 while 不是 for:四个细节
主循环骨架很薄:
while (ctx.iteration < this.maxIterations) { microcompactMessages(messages); // 先做轻量裁剪 const response = await this.callModel(messages); if (!hasToolCalls(response)) { // 无工具调用 = 回答完毕 return this.handleDirectResponse(response); } const { toolMessages } = await this.executeTools(response); // 只读工具并行 toolMessages = enforceResultBudget(toolMessages); // 单轮预算 messages.push(response, ...toolMessages); // 塞回上下文 }四件事容易被忽略:
- 终止条件双保险:模型不再调用工具,或轮数跑满,二者居其一。没有"任务完成"状态机,代码信任模型自己收手——朴素,也是最可能失控的点。
- 工具执行支持并行:只读工具一轮里同时跑,写操作与需审批的工具串行。
- 每轮先过一遍 microcompact,下一节细说。
- 运行期间用户可继续发消息:循环每轮末尾排空队列并入上下文,追问不必等整轮结束。
工具结果回来后,为什么不能原样进上下文
金融工具单次返回可能几百 KB,原始数据直接入上下文,第三轮就爆。代码按代价从低到高分三层处理:
- 大结果落盘:超阈值的工具结果经
persistLargeResult写入磁盘,上下文只留预览和文件路径,模型需要时再用read_file取段落。 - microcompact(src/agent/microcompact.ts):旧工具结果超过 8 条或估算 token 超 8 万时,把较早的替换为占位符,只留最近 4 条。纯字符串操作,不调 LLM,成本接近零。
- 全量 compact(src/agent/compact.ts):仍超阈值才调用快模型,把所有结果归纳为九段式摘要——原始问题、已取数据、全部数字、未完成项、建议下一步。提示词反复强调"别丢任何数字",金融分析里漏一个营收数,后面全错。
先清再总结,按需付费。
⏱️ 为什么默认 10 轮迭代,为什么每工具限 3 次
两个常量配合:DEFAULT_MAX_ITERATIONS = 10和 Scratchpad 的每工具 3 次调用上限。
10 是成本与完整的折中,中等问题通常 4~7 轮收尾。跑满时循环不抛错,而是发出done事件,明说"步数内没做完",并交出全部工具调用记录。
更有意思的是 src/agent/scratchpad.ts。每个 query 开一个 JSONL 文件,init、thinking、tool_result 追加写入,落在.dexter/scratchpad/下。两个用途:调试回放,崩了也能还原全过程;防循环——Scratchpad 记录每个工具的调用次数与查询文本,达到 3 次、或新查询与旧查询的词语相似度超阈值时,不硬拦截,而是把软警告注入下一轮提示词:"已调用 3 次,建议换工具或向用户说明数据缺口。"软警告而非硬封,因为第四次调用也可能合理,模型自己最清楚。
🧮 重放一次提问:ServiceNow 是不是高估了?
拿"NOW 是不是高估了?"走一遍这个循环:
- 第 1 轮:模型并行调
get_market_data与get_financials,各带完整自然语言问题——前者出价格、远期 P/E 与近期新闻,后者出近 4 年收入增速、经营利润率与 FCF。第一节"别拆调用"的策略在这里兑现。 - 第 2 轮:发现需要管理层指引,
read_filings取最新 10-Q 的 "Outlook" 段落,stock_screener拉几个 SaaS 同行对比。 - 第 3 轮:同行差距太大,决定做估值,触发
skill工具走 DCF 流程(步骤在 src/skills/dcf/);子任务重就spawn_subagent交给隔离的子代理,主上下文保持干净。 - 中途:工具结果已触发 microcompact,第 1 轮原始数据被清掉,只剩摘要里的关键数字。
- 第 4 轮:不再调工具,输出结论——远期 P/E 高于五年均值、增速放缓、DCF 合理价低于现价,判定"略高估"。若 RULES.md 写了"引用数据必须标来源",报告里每个数字都带工具调用记录。
全程 4~6 轮,离 10 还远。
想复刻这套循环,先读 src/agent/agent.ts 的 run 方法与 src/agent/prompts.ts 的提示词组装;然后执行git clone https://gitcode.com/GitHub_Trending/dexter19/dexter,按 README 与 env.example 填好模型和数据 API key,就能在 CLI 里提问,并到.dexter/scratchpad/目录回放每一轮。
【免费下载链接】dexterAn autonomous agent for deep financial research项目地址: https://gitcode.com/GitHub_Trending/dexter19/dexter
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考