ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用豆包和飞书多维表格搭建盘后巡检自动化系统

用豆包和飞书多维表格搭建盘后巡检自动化系统 收盘了不代表工作结束真正操心的是盘后那一堆事持仓市值要核对、当日盈亏要算、风险指标要看、公告事件要扫一遍。以前我都是手动打开几个系统东凑西拼记下来再写一段文字总结丢到群里。日子久了你会发现这事几乎天天一样但又不敢漏。后来我把这套流程交给了豆包和飞书多维表格让它每个交易日收盘后自动跑一遍巡检。这篇就记录一下我是怎么实现的以及折腾过程中踩过的坑。1. 盘后巡检定时到底要解决什么问题1.1 “盘后巡检”到底检查什么先别急着聊技术得把事情说清楚。盘后巡检在不同场景下内容差异很大。对个人投资者来说可能就是看一眼账户里的基金净值更新了没有今天的整体盈亏是多少对私募或者交易团队来说盘后巡检通常包含几个固定的板块行情数据核对收盘价、结算价、涨跌幅有没有异常尤其是临近收盘几分钟的数据容易出乌龙。持仓与盈亏复核把交易流水对一遍确认成交记录都进来了没有漏单、错单。风险指标检查单标的最大亏损、组合回撤、持仓集中度、强平线距离这类指标每天都要过一眼。事件与公告扫描持仓标的有没有发新的公告、停牌、分红、除权除息提醒。次日计划准备比如是否有需要参与的新股申购、可转债打新或者到期的合约是否要滚动调仓。说白了盘后巡检就是给当天交易状态拍一张结构化的“快照”然后基于这张快照判断正常还是异常。问题是这张快照涉及的字段多、计算杂、还要写总结如果全靠人工不仅慢还容易漏。我以前就有过一次漏掉某只基金折算事件第二天开盘净值对不上慌了半天。1.2 为什么要用豆包和飞书多维表格一开始我也想过自己搭一套带数据库和定时任务的系统后来发现太重了。我需要的是一个能快速落地、数据在团队里看得见、又能让AI帮我写巡检结论的组合。飞书多维表格的定位是轻量数据库加协作工具团队里谁都能打开看不需要额外装客户端权限也能按人分配。豆包在这套系统里干的是“读数据、做判断、生成结论”的活相当于一个不要钱的“巡检分析师”。两个工具配合起来数据归数据分析归分析各干各的。这个组合还有一个实际好处不需要专职开发。哪怕你完全不懂代码靠多维表格自带的自动化流程也能把定时跑起来如果你愿意碰一点点代码自由度还会更高能把AI分析、推送通知、异常告警都串在一起。这篇博文会把这套方案从简到繁拆开讲你可以根据自己的情况选路线。2. 方案选型豆包负责想多维表格负责管2.1 豆包能做和不能做的事很多朋友问过我一个很直接的问题豆包不是能定时吗其实严格来说豆包这类大模型本身不具备“到点自动执行”的能力它是一个文本生成引擎你给它输入它给你输出。所谓“定时”一定得有一个外部触发器把它叫醒。豆包擅长的部分是分析类的活。例如你把当日持仓数据给它让它总结“今日组合整体微亏主要是某某标的大幅回调拖累了净值建议关注其后续走势”或者让它按预设模板输出一份巡检摘要把“是否有异常、是否需要关注”这类判断写清楚。它也能在给出历史数据后输出对比结论省掉你自己组织语言的时间。但豆包不能做的事也很明确它不会主动在下午三点十分去读你的表格也不会自己创建记录、发送群消息。这些都是周边系统要负责的。这里必须分清主次否则你会被各种“AI能不能自动完成”的预期绕晕。2.2 两条主流实现路径我把可行的落地方式总结成了两条路线分别适合不同基础的人。路线触发方式AI介入方式适合谁路线A多维表格原生自动化表格自带的“自动化流程”按时间触发调用多维表格内置AI字段 / 发送HTTP请求到豆包API不想写代码、追求快速落地的人路线B脚本定时器 APIPython脚本由本机计划任务或服务器定时运行SDK调用豆包API再把结果写回多维表格或发飞书消息需要灵活逻辑、已经有一定编程能力的人路线A胜在零代码打开多维表格界面点点点就能配出来。缺点也很明显多维表格的自动化流程目前内置触发器和操作是有限的做不了太复杂的条件判断而且如果每次都让AI生成分析往往需要借助外部请求把数据转发给豆包配置起来反而有点绕。路线B则是我个人推荐的做法。因为它把“取数、判断、分析、回写、通知”都放在一个脚本里逻辑是透明的改动也方便。下面我会先讲路线A因为它能帮你建立“表怎么建、自动化怎么配”的直观认知再重点讲路线B因为真正跑顺的巡检系统基本都走这条路。3. 落地实操多维表格原生自动化方案3.1 字段设计这是所有方案的地基无论走哪条路线第一步都是把飞书多维表格建好。我在实际项目里给持仓巡检表设计的字段大概长这样字段名字段类型说明日期日期巡检日期格式建议用 YYYY-MM-DD标的名称文本基金名称或股票简称标的代码文本用于对接行情或公告数据方向单选多头/空头成本价数字持仓成本保留四位小数收盘价数字当日收盘价或结算价持仓数量数字当前持仓份额或股数当日市值公式收盘价乘持仓数量自动计算当日盈亏公式收盘价-昨结算价乘持仓数量累计收益率公式与成本价比较得出持仓占比公式单标的市值除以组合总市值巡检摘要文本由豆包生成的结论写在这里异常标记复选框判断当日是否需要重点关注细心的朋友会发现公式字段我特意让多维表格自己算而不是让豆包算。原因有两个一是数值计算交给确定性引擎最稳妥AI算数虽然不错但在金融数据上我不接受“大概对”二是让豆包只做语言层面的概括它工作更稳定。表格里的“巡检摘要”和“异常标记”是给豆包输出预留的位置。3.2 建表和录入基础数据多维表格的操作不复杂。首先在飞书文档里新建一个多维表格按上面的字段逐列建立。建立字段的时候注意几个细节日期字段一定要选“日期”而不是“文本”否则后续按时间条件过滤会出问题单选字段“方向”建议预设好“多头”“空头”两个选项以后录入就不会出现“做多”“多单”这种乱七八糟的写法。基础数据怎么进最省事的方式是让行情数据或交易系统每天导出CSV你再粘贴进来或者通过飞书多维表格的“数据同步”能力从Excel源同步。如果你完全没有外部数据源那也得先把当天的持仓数据手录进表里这一步逃不掉。记住一个原则进表的数据越规范AI分析的质量越高。把基础数据建好之后就可以写一条最原始的公式测试一下“当日市值”是否正确计算出来。表达式大概是收盘价 * 持仓数量如果公式返回为空多半是字段名带了“数字”后缀之类的差异检查一下你命名时有没有空格或全角字符。3.3 配置定时自动化的操作过程零代码路线的核心是多维表格右上角的“自动化”功能。我以“每个交易日15:05触发”为例讲一下配置思路。打开多维表格点击右上角的“自动化”新建流程。触发器选择“定时”或“按时间”频率设为每天时间选 15:05。因为自动化不管是不是交易日都会跑所以要在触发后加一个条件判断筛选日期字段等于今天的记录且“当日盈亏”不为空。这样周末没有数据时流程可以直接结束不会白跑。下一步配置操作。如果你只是想要提醒可以直接选择“发送消息到群”把巡检摘要里的文本发出去如果想让豆包分析这里就需要用到“发送HTTP请求”操作把多维表格里的当日持仓数据拼接成一个JSON POST到豆包接口然后再把返回结果写入某个文本字段。配置“发送HTTP请求”时URL填豆包API的调用地址请求体里带上模型名称和消息Header里填API Key。这里对新手来说是一个难点因为多维表格的自定义操作没办法写太长的代码你需要在“请求体”里手写模板把表格字段用{{字段名}}这种形式嵌入进去。我实际测下来这个方案能用但有两个不舒服的地方一是每次请求都要把字段手动拼一遍模板长了很难维护二是如果豆包接口调失败了自动化流程只会显示执行失败不会自动重试。所以后面我转向了方案B。但不得不说对于只是每天发一条固定提醒、不需要豆包深度分析的人来说原生自动化已经够用了。3.4 原生方案的两个限制依赖多维表格原生自动化最大的坑是容错能力差。一次HTTP请求超时、一个字段类型不匹配、API额度不足都会造成静默失败。另外多维表格的自动化流程数量和使用频率有平台限制如果你同时维护多张表、多个流程很快就会碰到瓶颈。其次是“分析深度”不够。多维表格里就算接了AI字段能做的也基本是“摘要提取”“分类”这种单步操作做不了“读取持仓表、结合多日历史趋势、输出风险提示”这种多步推理。真要到那个程度必须把控制权拿到外面去也就是下面要讲的脚本方案。4. 进阶Python定时器 豆包API 飞书API4.1 整体逻辑把巡检当成流水线我把这套实现命名为“盘后巡检流水线”。每天收盘后脚本按预设时间被系统唤起然后执行四个步骤读取飞书多维表格里当天的持仓数据。把持仓数据组装成一段结构化的提示词。调用豆包API生成巡检摘要和异常判断。把摘要写回多维表格并往飞书群发一条格式化通知。这四个步骤串起来就是一个简单的ETL加AI分析流程。好处是每一步都能单独调试出问题知道去哪查日志。4.2 准备获取API密钥开始写代码前先准备三个东西飞书自建应用的 App ID 和 App Secret飞书多维表格的表格ID在表格链接里能提取到豆包模型的 API Key 和接口地址飞书这边我们需要去飞书开放平台创建企业自建应用申请多维表格的读写权限然后在“凭证与基础信息”里拿到 App ID 和 App Secret。豆包那边使用火山引擎方舟提供的OpenAI兼容接口它支持标准的chat/completions模式所以可以直接用OpenAI的Python SDK只需要改一下base_url。我把飞书多维表格的token获取和豆包调用封装成两个模块后面会给出代码。4.3 核心脚本实现先看飞书侧的工具函数。因为飞书API的app_access_token有效期为两小时所以要缓存起来不要每次请求都重新获取。import requests import time APP_ID your_app_id APP_SECRET your_app_secret APP_TOKEN your_app_token # 多维表格的文档token TABLE_ID your_table_id # 表格ID _token_cache {value: None, expire_at: 0} def get_tenant_access_token(): now time.time() if _token_cache[value] and now _token_cache[expire_at]: return _token_cache[value] resp requests.post( https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/, json{app_id: APP_ID, app_secret: APP_SECRET}, timeout10, ) data resp.json() _token_cache[value] data[tenant_access_token] _token_cache[expire_at] now data[expire] - 60 return _token_cache[value] def get_records_by_date(target_date): token get_tenant_access_token() headers {Authorization: fBearer {token}} params {page_size: 100} # 这里需要先按日期过滤飞书API支持filter表达式 filter_expr { conjunction: and, conditions: [ {field_name: 日期, operator: is, value: [target_date]} ], } url ( fhttps://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN} f/tables/{TABLE_ID}/records/search ) resp requests.post( url, headersheaders, paramsparams, json{filter: filter_expr}, timeout15, ) return resp.json().get(data, {}).get(items, [])需要注意飞书多维表格的records/search接口是POST且过滤条件里日期格式必须是YYYY-MM-DD多条件之间用conjunction: and连接。这里如果写成operator: is匹配的是完整日期值。接下来是豆包调用。因为接口兼容OpenAI格式我直接用openaiSDKfrom openai import OpenAI DOUBAO_API_KEY your_doubao_api_key DOUBAO_BASE_URL https://ark.cn-beijing.volces.com/api/v3 DOUBAO_MODEL doubao-pro-32k # 替换成你在方舟创建的接入点ID client OpenAI(api_keyDOUBAO_API_KEY, base_urlDOUBAO_BASE_URL) def generate_inspection_summary(position_text): prompt f 你是一名盘后巡检助理。请根据以下持仓汇总信息输出一段巡检总结。 要求 1. 先给出整体盈亏判断 2. 逐一点出异常项如果存在 3. 给出明日重点关注建议 4. 如果有异常在最后一行输出【异常】标记否则输出【正常】。 持仓信息 {position_text} resp client.chat.completions.create( modelDOUBAO_MODEL, messages[{role: user, content: prompt}], temperature0.3, max_tokens1000, ) return resp.choices[0].message.content这里我把temperature设成0.3目的是让输出尽量稳定减少AI自由发挥的空间。max_tokens设成1000足够覆盖常规巡检结论太长反而容易让后面的回写超限。4.4 组装数据、调用和回写拿到多条记录后需要把字段转换成一个紧凑的文本。多维表格返回的记录结构里字段值都在fields里。有两个坑值得提醒公式字段在通过API读取时有可能不在fields返回里而数字字段会附带value结构取数时要做兼容处理。参考代码def build_position_text(records): lines [] for item in records: fields item.get(fields, {}) name (fields.get(标的名称) or [{text: }]) # 飞书多维表格API返回的文本字段可能是对象数组 if isinstance(name, list): name .join(seg.get(text, ) for seg in name) close_price fields.get(收盘价) # 数字字段可能被包在dict里 if isinstance(close_price, dict): close_price close_price.get(value) qty fields.get(持仓数量) if isinstance(qty, dict): qty qty.get(value) lines.append( f标的{name}收盘价{close_price}持仓数量{qty} ) return \n.join(lines)回写巡检摘要时调用多维表格的更新记录接口。要更新的记录ID和原始记录一一对应所以我在前面读取时就把record_id保留下来def update_inspection_summary(record_id, summary, is_abnormal): token get_tenant_access_token() headers {Authorization: fBearer {token}, Content-Type: application/json} url ( fhttps://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN} f/tables/{TABLE_ID}/records/{record_id} ) body { fields: { 巡检摘要: summary, 异常标记: is_abnormal, } } resp requests.put(url, headersheaders, jsonbody, timeout10) return resp.json()到这里一条巡检记录就完成了从取数、分析到回写的闭环。4.5 定时器交易日判断是关键我最开始直接用了Windows系统的“任务计划程序”每天15:10执行脚本结果周末也跑了一遍把空的持仓数据丢给豆包它居然一本正经地生成了一份“空仓巡检报告”。这事提醒我定时器可以傻但脚本必须聪明。交易日判断很简单维护一个简单的节假日列表import datetime HOLIDAYS_CN { # 每年需要手动补充也可以调用交易所日历接口 2025-01-01, 2025-01-28, 2025-01-29, 2025-01-30, 2025-01-31, 2025-02-03, 2025-02-04, 2025-02-05, 2025-04-04, 2025-05-01, 2025-05-02, 2025-05-05, 2025-10-01, 2025-10-02, 2025-10-03, 2025-10-06, } def is_trading_day(d: datetime.date) - bool: if d.weekday() 5: return False return d.isoformat() not in HOLIDAYS_CN接着把整条流水线放进main()函数。每天执行时先判断今天是不是交易日不是就直接退出然后读取记录记录为空也退出有数据才调用豆包并回写。如果你希望更省心建议把脚本部署到一台长期开机的服务器或NAS里用crontab控制10 15 * * 1-5 cd /path/to/project /usr/bin/python3 daily_check.py logs/check.log 21注意cron里的时间用的是服务器本地时区如果服务器是UTC时间要换算成北京时间减8小时也就是早上7点10分触发。这个细节我实际踩过日志里老是显示在15:10跑结果打开数据库一看数据时间是凌晨。4.6 推送飞书群通知巡检结果写回表格只是第一步团队要看到还得往群聊里推。飞书的“自定义机器人”或者“应用消息”可以二选一。自定义机器人配置最简单在群里添加一个机器人拿到Webhook地址然后发一段富文本消息def send_feishu_notification(summary): webhook https://open.feishu.cn/open-apis/bot/v2/hook/your_webhook data { msg_type: interactive, card: { header: { title: {tag: plain_text, content: 盘后巡检报告}, template: blue, }, elements: [ {tag: markdown, content: summary}, {tag: note, elements: [{tag: plain_text, content: 由豆包与飞书多维表格自动生成}]}, ], }, } resp requests.post(webhook, jsondata, timeout10) return resp.json()自定义机器人的优点是不需要申请应用权限也不依赖app_access_token适合个人和小团队。缺点是Webhook泄露了别人就能往你群里发消息所以保管好。如果你的环境讲究安全还是走应用消息更正规代码里带上tenant_access_token调im/v1/messages接口即可。5. 常见问题与排坑记录这套系统跑了一个多月我把遇到的典型问题整理成一张速查表每个问题后面都附了处理思路。现象可能原因解决办法定时任务到了时间没反应服务器或本机睡眠cron时区不对设置任务计划“唤醒计算机来运行”检查时区偏移多维表格自动化流程执行失败某个字段类型被改了或HTTP请求超时查看流程运行日志定位到具体记录减少请求体大小豆包返回内容格式不稳定提示词不够结构化要求输出JSON或固定模板用temperature调低读取记录时日期过滤结果为空日期字段存了时间戳或格式不一致确认写入时用的是YYYY-MM-DD过滤值保持一致汇总里出现“暂无数据”行情数据源当天没更新在巡检脚本里加“数据缺失”检查一旦为空立刻告警飞书API返回tenant_access_token过期token没有缓存或缓存过期时间太短复用全局缓存预留60秒过期余量脚本重复跑了两遍任务计划里重复触发了同一条任务增加幂等标记比如当天已生成摘要则跳过群里收到空消息豆包返回内容为空字符串判断summary.strip()为空时改用备选文案有一个排坑经历值得重点说一下。我最初把“异常标记”设计成文本字段让豆包返回“是”或“否”结果它有时返回“有风险”有时返回“需要关注”导致后面统计怎么都对不上。后来我只保留两种状态要么“异常”要么“正常”并且在提示词里要求最后一行严格输出【异常】或【正常】然后在脚本里用正则去匹配import re match re.search(r【(异常|正常)】, summary) if match: is_abnormal match.group(1) 异常 else: is_abnormal False这招非常管用。不要指望大模型每次都规规矩矩按你的格式来必须用结构化标记兜底。再补充一个关于飞书多维表格自动化流程的小经验。如果走路线A在配置“发送HTTP请求”给豆包时豆包返回的内容会放在响应体里但你很难把它动态塞回表格字段。因为多维表格自动化的“响应处理”没有脚本语言只能靠简单的变量映射。这时候我建议把AI生成的内容交给机器人发送不要执着于回写。想要完整回写老老实实走路线B的Python方案。6. 我的一点实操体会这套东西从想法到跑通我大概花了两天。最花时间的不是写代码而是把表结构和提示词调到一个两边都舒服的状态。表结构太简单AI拿不到足够信息字段太多请求体臃肿API响应也慢。我最后的经验是让多维表格承担“存数据、算数值、展示结果”的职责让豆包只承担“读汇总、写结论”的职责不要试图让AI替你做计算和存储。另一个对我帮助很大的习惯是给每条巡检记录加了一个“数据版本”字段。我每天会保留最近30天的记录月底复盘时直接筛选看某段时间的异常标记和豆包摘要比翻原始交易记录高效太多。最后分享一个小技巧如果你用的是Python路线建议把巡检脚本每次运行的开始时间、耗时、豆包返回的token数写进一个单独的日志表。这样做的好处是真出问题的时候你能立刻知道是“任务没触发”还是“API调用超时”还是“数据没取到”。这年头做自动化最怕的不是报错而是默默失败。这套方案你完全可以照搬也可以只取一部分。哪怕只是给飞书多维表格加一条定时提醒让豆包每天晚上帮你总结当日持仓变化也能省不少事。先把第一个简单版本跑起来再慢慢加复杂判断。自动化巡检这事做了就回不去了。
返回列表