做 X 平台(原 Twitter)上的 bot 这件事,我前前后后折腾了小半年。刚开始是真头铁,非要从零开始写,结果光是研究 API 鉴权、回调、限流、防重复发布这些边角料就耗掉了大量时间,真正用来调 Grok 提示词的时间少得可怜。后来我把常用的几套逻辑抽成了 4 个 Grok bot 模板,再建新 bot 基本就是复制、改配置、跑起来的节奏,效率完全不一样。这套模板现在还在持续完善,我打算把这 4 个模板的核心结构、设计思路、以及踩过的真实坑一次说清楚,给打算在 X 平台上构建 Grok 应用的开发者一点参考,也帮那些不太确定从哪下手的人少走点弯路。
1. 从零写 X bot 和套用模板,差别不在代码量而在思路
先说结论:模板能帮你省时间,本质上不是省了“写代码”这一步,而是省掉了“设计边界”这一整层。很多从零开始的 bot 死掉,不是挂在功能实现上,而是挂在边界不清楚。
1.1 你自己写大概率会漏掉这三件事
第一件事是异常处理。X 平台的接口和 Grok 的接口都有各自的超时、限流、错误码,第一次写代码的时候很难想到要统一处理这些。第二件事是状态管理。一个 bot 不是跑一次就完事的,它需要记住上次运行到哪里,否则同一个话题会被重复回复,定时任务也会重复发布,这在生产环境是非常尴尬的。第三件事是可观测性。bot 跑在服务器上,怎么确认它今天到底干活了没有,出了错怎么知道错在哪一步,很多人压根没考虑过。
这三件事单独拎出来每一件都不难,但混在一起,再叠加你自己的业务逻辑,复杂度就上来了。模板的价值在于,这些通用部分已经替你踩过一遍坑,你只需要专注在“这个 bot 要做什么”上,而不是“这个 bot 怎么才能不崩”。
1.2 模板的真正价值:把“怎么接 X API”和“怎么用 Grok”切成两层
我整理模板时最重要的一个决定,就是把代码分成两层。底层是X 平台适配层,负责账号登录、发帖、读评论、私信收发、定时触发这些跟 Grok 模型无关的事情;上层是Grok 提示词与生成层,负责根据不同的业务场景组织 input、调用模型、解析输出。这两层之间只通过几个简单的方法沟通,比如post(text)、reply(comment_id, text)、on_schedule(callback)。
这样切的好处很明显:换成 Grok 模型升级版本的时候,只需要动上层;未来如果要换另一个模型提供商,底层 X 适配层可以基本不动。这也是我把这套东西拿出来分享的一个原因——结构清晰,效率更高。
1.3 四个模板对应的四类高频需求
这 4 个模板分别对应我在社区里观察到的四类最高频需求:
- 内容生成型:定时生成推文、周报、话题帖,交给 Grok 当“写手”;
- 互动回复型:自动回复评论、私信,Grok 当“客服/社交分身”;
- 趋势观察型:定时抓取热点,让 Grok 做摘要和分析,输出简报;
- 知识库问答型:让 Grok 基于你自己的文档、FAQ 回答问题,而不是瞎编。
后面几节我会逐个拆解,把每个模板的目录结构、关键逻辑、调参经验、以及我实测下来的翻车现场都放出来。这些细节是文档里很难完整看到的部分,也是我实际跑了一段时间之后才积累到的。
2. 模板一:定时内容生成器,把“发什么”交给 Grok
这是四个模板里最简单的一个,但也是被问得最多的一个。原因很简单:很多人想做“自动发推的 bot”,但真做出来之后,发现发出来的东西没法看。问题基本都出在提示词太随意,或者调度逻辑太粗暴。
2.1 适用场景与整体结构
这个模板适合的场景是:每天固定时间、固定频率,生成并发布一段内容。比如早报、科技资讯评论、金句、行业观察、甚至纯娱乐性质的段子。它不需要回复任何人,也不解析上下文,本质就是一个“定时任务 + 调用 Grok + 发帖”的三步流水线。
目录结构我习惯拆成这样:
content_bot/ ├── .env # 所有密钥和配置 ├── bot.py # 入口:调度 + 调用生成器 ├── grok_client.py # Grok API 统一封装 ├── x_client.py # X 平台发布封装(含去重) ├── prompts.py # 所有提示词集中管理 └── logs/这个结构看着不起眼,但prompts.py单独拆出来是个很实用的习惯。我见过不少 bot 把提示词写死在代码字符串里,等想调文案风格时,还得翻代码、改代码、重新部署。拆出来之后,调提示词只改一个文件,不碰逻辑,定位问题也快。
2.2 核心代码拆解:单轮生成 + 定时调度
生成部分最核心的就是一段很普通的调用:给 Grok 一个系统提示词,一个用户消息,拿回一段文本。需要注意的坑是,Grok 生成的是完整内容,但你不一定想让它直接发出去,所以输出解析非常关键。我在模板里会让它输出一个 JSON,JSON 里带title和content两个字段,然后由代码决定怎么拼成最终推文。
# grok_client.py 中简化的调用示意 import json, os from openai import OpenAI client = OpenAI( api_key=os.getenv("GROK_API_KEY"), base_url=os.getenv("GROK_BASE_URL"), ) def generate_content(topic: str, style: str) -> dict: resp = client.chat.completions.create( model=os.getenv("GROK_MODEL", "grok-3"), messages=[ { "role": "system", "content": ( "你是一个 X 平台内容创作者。" "根据用户给定的话题生成一条推文。" "推文中不要有 emoji,不要有话题标签。" "必须以 JSON 格式返回,包含 title 和 content。" ), }, {"role": "user", "content": f"话题:{topic},风格:{style}"}, ], temperature=0.8, response_format={"type": "json_object"}, ) return json.loads(resp.choices[0].message.content)调度我用的是系统级 cron 而不是代码里内嵌定时器,因为 cron 足够简单,进程挂了可以被系统拉起来。入口bot.py只做一件事:拿到话题 → 生成 → 调用x_client.post()。发布之前会查一下过去 N 小时内有没有发过相同指纹的内容,防止重复,这个细节后面单独说。
2.3 实测参数:temperature 和 stop 序列怎么定
很多刚开始用 Grok 的人喜欢把temperature调得很高,觉得这样“更有创意”。实际测下来,做定时内容生成器,temperature在 0.7 到 0.9 之间最舒服。太高的话文案会飘,看起来像喝多了,太低的话每一篇都像同一篇,缺少变化。如果目标是相对正式的行业观察、早报类内容,可以把temperature压到 0.5 左右,准确度和可读性更平衡,也不会太无聊。
另外一定要做输出清洗。Grok 返回的内容偶尔会带上 Markdown 符号、多余的换行、甚至忘记把 JSON 收尾。我的做法是加一个很简单的后处理函数:去掉首尾空白,删掉多余的连续空行,强制按\n\n分段,并做个字符长度兜底。这些看似琐碎,但决定了发出来的帖子读起来是“正常”还是“一看就是 AI”。
2.4 这个模板最常见的翻车现场
用了这么久,我总结出这个模板最常见的翻车场景有两个。第一个是生成内容过于空泛,比如提示词写“写一条关于科技新闻的推文”,Grok 就会生成一条“科技的进步总是令人兴奋”这样的废话。解决方式是给足上下文,比方说把抓到的具体新闻标题、摘要直接塞进 user 消息里,而不是让它凭空想象。
第二个是时区问题。这个真的很容易被忽略。cron 和 Bot 所在服务器的时区如果不一致,原本想早上 8 点发的帖子,可能变成凌晨 3 点发。我的模板里会显式配置TZ环境变量,并在日志里打印下一次任务执行时间,方便一眼看出调度是不是符合预期。
3. 模板二:评论区与私信自动回复 bot,核心是“少回错”
内容生成 bot 只是单向输出,互动回复 bot 就要复杂一个量级了,因为它要监听、读取、判断、回复,每一步都可能出岔子。这个模板是我自己用的最多也最谨慎的一个,因为一旦回错,影响的是真实账号的脸面。
3.1 它解决的问题和两种接入方式
在 X 平台上做互动 bot,通常有两种接入姿势。第一种是基于账号流(account activity 风格),实时接收评论和私信事件;第二种是轮询方式,每隔几十秒扫一次最近的通知,再去重处理。第一种实时性好但配置麻烦,第二种实现简单、能扛住不少场景。我的模板默认是轮询方式,因为对大多数个人项目、小规模 bot 来说,秒级延迟完全够用。
这个模板的核心循环逻辑就是:
- 拉取最近的通知或评论列表;
- 过滤掉自己发的、已处理的、粉丝数异常的账号;
- 让 Grok 判断这条评论需不需要回复、以及怎么回复;
- 如果判断为“需要回复”,再调用 X 平台的回复接口。
3.2 鉴权与回调:最容易卡住的地方
说实话 X 平台的 OAuth 流程对新手确实不算友好,尤其是用较新版本的 API 时,权限范围、令牌刷新都是坑。我的建议是,一开始别纠结用完整版的企业级权限,先用个人开发者模式跑通最小闭环,也就是“能发帖、能读评论、能回评论”。在模板里,我封装了一个简单的凭据加载模块,统一从.env读密钥,并负责在令牌即将过期前自动刷新。
回调这块如果做的是实时事件,需要一个公网可访问的地址来接收.但轮询方式完全不需要回调,这也是我推荐轮询作为起步方案的另一个原因。跑通之后再考虑升级到实时事件,避免一开始就被环境问题卡死。
3.3 回复策略:过滤、改写、借用 Grok 判断意图
这里是我花时间最多的地方。直接让 Grok 回复每一条评论肯定不行,因为评论区有大量无效内容,比如表情包式评论、单纯的 @、无意义的“哈哈”。我设计了一套分级策略:
- 第一级:规则过滤,评论长度小于 2 个字、只含 emoji、包含明显的广告链接都直接跳过;
- 第二级:意图判断,把评论交给 Grok,让它回答“这条评论是否需要回复”,需要的话顺便给出回复草稿;
- 第三级:人工兜底,凡是涉及争议、隐私、攻击性内容的,一律不回复。
def decide_reply(comment_text: str) -> dict: judgment = grok_client.judge(comment_text) if judgment["should_reply"] is False: return {"action": "skip"} if judgment["risk_level"] == "high": return {"action": "skip_and_flag"} return {"action": "reply", "draft": judgment["reply_text"]}这样的好处是,Grok 只用在自己擅长的“理解语义 + 生成内容”环节,那些确定性判断交给规则和策略来做,既省钱又稳定。尤其是“风险分级”这个状态我强烈建议保留,它会直接帮你避开很多麻烦。
3.4 我在真实账号上做的噪音抑制
跑了一段时间,我筛选出几个特别容易触发误回的情况。比如很多人会在评论里写“关注你了”“互关吗”,这类评论如果 bot 直接回复就变成了机器人互刷现场。我在过滤规则里加了“关注”“互关”等词,命中就直接跳过。另一个坑是自己 bot 的上一轮回复也会被扫进来,必须在循环开头排除自己的账号 ID,否则会陷入无限自我对话。
这个模板上线后最大的感受是:一个好用的互动 bot,不是能回复得多,而是能忍住不回复的次数多。宁可漏掉一些可回可不回的评论,也别为了活跃度去回那些不适合回的。因为一次失败回复带来的负面影响,可能需要几十条正常回复才能平衡回来。
4. 模板三:趋势观察哨,定时抓热门话题并生成简报
第三个模板很适合做信息聚合号或者内部情报工具。它的任务不是自动发帖聊天,而是定时抓取某个话题下的热门讨论,让 Grok 归纳出趋势、情绪、争议点,然后生成一份简报。
4.1 设计思路:Grok 不只用来聊天,还能当分析引擎
很多人对 Grok 的使用还停留在“聊天、生成文本”,但其实把这套模型当作一个结构化工件生成器,价值会大很多。趋势观察哨就是典型的用途:输入一堆零散的帖子文本,输出一份带观点、带重心、带反方意见的简报。这个任务如果用规则脚本做,写关键词正则匹配会写到怀疑人生,让模型来做概括和归纳就顺手得多。
模板会把采集和归纳解耦。采集部分用 X 平台的关键词搜索或话题流拿到原始数据,经过简单的文本清洗之后,批量丢给 Grok。编 Prompt 的时候我会明确告诉它:你是一个舆情分析助手,输出必须包含“总趋势”“主要观点”“争议点”“代表性帖文角度”四个小节,并且禁止虚构没有出现在输入里的内容。
4.2 数据抓取和 Prompt 的配合方式
抓取的时候最容易犯的错是“贪多”。一次把几百条帖子全部塞进上下文,一是 token 成本高,二是模型会迷失在细节里。我的做法是分两步:先粗筛,选取互动数(点赞、转发、评论)较高的 Top N 条,把文本拼接成一段干净的语料,再交给 Grok。
在模板里,我保留了一个fetch_trending_posts(keyword, max_results=50)函数,专门负责抓取和清洗,去掉 URL、无意义空格、重复文本。实测下来,50 条输入已经能产出比较靠谱的简报,而且刚好在可控的上下文尺寸内。若要压缩成本,可以再减到 20 到 30 条。
4.3 token 预算与长文本输出控制
这里必须说 token 预算的问题。Grok 的基础对话模型上下文比较大,单次可以塞很多文字,但你的成本也会随着输入增大而上升。我的习惯是给这部分单独设置一个较低的温度(比如 0.3),因为分析任务需要的是忠实归纳,不是自由发挥。太高的温度会生成大量“虽然但是”的废话,把简报变得又长又空。
输出长度控制也是同样重要。提示词里直接规定“简报总字数不要超过 400 字”“用简洁的中文短句”,能有效避免模型失控输出巨长段落。另外我会在代码里做一次兜底,如果生成结果超过设定长度,就按小节拆分,而不是整段截断,至少保证内容完整性。
4.4 报告分发:走 DM 还是走公开帖
报告生成之后往哪发,也是一个设计决策。如果是内部观察,我建议直接走私信发送给自己或者某个专属账号,避免刷屏打扰粉丝。如果要做成一个公开的“每日趋势号”,那就要考虑格式化排版,并且在公开帖里注明“内容由 Grok 生成,仅供参考”,这是一个必要且体面的处理方式。
顺带说一个实用细节:报告最好生成两份,一份纯文本用于私信,一份结构化文本用于公开帖。同一份内容在不同载体上的可读性差别很大,公开帖里我会额外加换行和分节符号,这能让阅读体验提升不少。
5. 模板四:知识库问答 bot,让 Grok 拿着你的资料说话
第四个模板和其他三个都不太一样。它不追求自动发什么,而是要做一个“带着你的资料回答问题”的问答 bot。它适合的场景包括产品 FAQ、个人博客内容索引、某个垂直领域的知识库等。
5.1 适用场景:FAQ、产品文档、个人内容库
我最初做这个模板,是为了让一个产品账号能自动回答用户留言里的常见问题——比如价格、功能、申请方式。这些信息如果让模型凭空回答,很容易一本正经地给错答案,因为普通模型的知识库不可能知道你这个产品的细节。解决思路很简单:其实不用模型“记住”,而是让模型“查完再说”。
具体来说,就是这个 bot 接收到问题时,先在自家知识库里检索最相关的片段,然后把片段和问题一起交给 Grok,让模型基于片段作答。这就是现在流行的那种检索增强生成(RAG)的简化版,完全够用,而且实现起来并不复杂。
5.2 简化版 RAG:先检索再生成
模板里的知识库我最初用的是静态优化方式,把 FAQ 文档切分成小块,每块带上标题和标签,然后做一个很轻量的关键词与语义组合检索。不一定非要上向量数据库,对小规模场景反而简洁更好维护。
流程稳定之后,我也试过把文档块做向量化,用了通用的嵌入接口。实测下来,只要是几百条以内的小型知识库,关键词召回已经能覆盖绝大多数场景;向量化真正解决的是“用户措辞和文档措辞差异很大”的模糊查询。所以我的建议是:先上简单方案,跑几天看看漏召回率,再决定要不要补向量检索。不要一开始就给自己加复杂度。
5.3 上下文窗口和引用处理
问答模板的输出质量,取决于你怎么组织 prompt。我习惯让 Grok 严格遵循“先给结论,再给理由,最后给来源”的结构。所谓来源就是知识库片段的标题或 ID,这样用户能看到答案出处,也方便人工验证。如果检索命中的多个片段互相矛盾,我会让模型如实说明“资料中存在不同说法”,而不是自作主张挑一个。
有一个很容易被忽视的细节是:知识库片段本身要带日期或版本号。没有版本信息的话,当你的 FAQ 更新了,模型很可能还在引用旧答案。我后来给每个知识库条目加了一个updated_at字段,在拼 prompt 时一并带上,这样模型才能知道该优先采信新资料。
5.4 成本与延迟的实测观察
问答 bot 的每次请求至少包含“检索 + 一次模型生成”,成本肯定比单纯发推高。而且如果用户连续追问,每次都要重新检索、重新拼上下文,请求量会线性上涨。我的处理是在模板里加了上下文缓存:同一个 session 最近的几轮问答结果会保留,遇到近似追问时先查缓存,命中就不再调用模型。
延迟方面,生成式响应通常在几秒内返回,对私信场景完全没问题,但如果做的是网页端嵌入客服,就得加“正在输入”的状态提示。这也是模板里预留了事件回调钩子的原因,前端可以先收到一个准备信号,再等正文生成。
6. 四个模板通用部分的三个坑:密钥、限流、上下文污染
前四节是按模板拆的,实际上这 4 个模板共用了同一套 X 平台交互逻辑和 Grok 调用逻辑。这套公共部分里藏着三个最常见、也最容易拖垮项目的坑,我单独拎出来讲一下。
6.1 密钥管理:.env 与本地调试
无论是 Grok 的 API 密钥还是 X 平台的令牌,都属于绝对不应该出现在代码仓库里的东西。我的模板从第一天起就统一用.env文件管理所有密钥,并且在gitignore里强制排除。.env.example文件会提交到仓库,里面只留变量名和说明,不给真实值。这样新环境部署只需要复制一份 example 再填值,非常省事。
本地调试时我还会特意打印“当前使用的密钥前缀”,确认加载的是哪一套配置,避免跑着跑着用了生产环境的令牌而不自知。这是一个我踩过的真实坑:本地调试时覆盖了.env,结果 bot 把测试内容发到了真实账号上。那种酸爽不想来第二次,后来我干脆在代码里加了一个运行环境判断,非本地环境默认拒绝执行“仅调试用”的功能。
6.2 限流与重试:别让 429 打崩你的 bot
X 平台接口和 Grok 接口都有速率限制,表现就是返回 429。如果代码里不做重试,用户多的时候 bot 就会一直失败;如果重试策略太激进,又会把限流打得更严重,导致封禁风险。我的模板统一跑了一套指数退避重试:第一次失败等 1 秒,第二次等 2 秒,第三次等 4 秒,最多重试 5 次。同时把每次请求的响应状态码记录到日志,方便事后分析是否撞上了限流。
另外一个细节点是,Grok 的限流按分钟窗口计算,而 X 平台的限流有更细的额度类型,这两者的峰值经常不在同一时间出现。如果同时跑多个 bot,建议给每个 bot 配独立的 API 密钥,或者在公共客户端里加一个简单的并发闸门,把最大并发控制在 2 到 3 个请求,基本不会出问题。
6.3 上下文污染的典型表现和解决办法
最后这个坑,也是最隐蔽的。Grok 聊天模型是有上下文的,如果你的代码复用同一个对话 session,上一轮聊过的内容会影响下一轮生成,但你自认为每次都是“独立请求”。表现就是:生成的内容突然开始引用根本不存在的前文,或者语气突然变得很奇怪。
我的解决办法是,所有模板里的生成调用默认无状态——每次调用都新建一个干净的消息列表,只在确实需要多轮对话的问答模板里才保留 session,并且设一个明确的会话过期时间。另外,如果用户输入里包含过长的文本,我会在拼接前做截断处理,防止上下文被垃圾内容撑爆。这个小习惯救了我好多次,尤其是在跑定时内容生成 bot 的时候,不然你会发现第二天的推文风格莫名跟着前一天的话题跑了。
说回建 bot 这件小事。我最初以为难点在怎么把功能做出来,真正跑起来才发现,难点在怎么让它稳定、安全、不惹麻烦地一直跑下去。这 4 个模板未必适合所有人,但至少提供了一套已经验证过的结构和边界。如果你刚开始做 X 平台上的 Grok 应用,我建议别一次性追求大而全,先挑一个模板跑通,再把另外几个方向逐步加进来。按我的经验,第一个 bot 从启动到稳定运行,中间会有无数的“意外情况”等着你,但只要结构清晰、日志完备,绝大部分问题都能在几分钟内定位。最后再提醒一句:任何时候给 bot 加“自动对外发声”的能力,都要留一个可以随时手动关闭的总开关,这个开关在线上环境意味着主动权。