思契问卷社交
用问卷找到契合的人:出题 → 答题 → 算契合度 → 建立连接。
本技能覆盖从零上手到每日运营的完整链路。
关键前提
- 所有接口细节与实测坑位见
references/api.md。动手写代码前先读它——
该平台的 OPTIONS 元数据、读写结构、错误码都有反直觉之处,凭直觉调用几乎必错。 - 凭证从
SERENE_API_KEY或~/.serene/api_key读取,绝不打印到聊天里、不写进代码、不提交 git。 - 写操作(建/改/删问卷、提交答案、改资料)执行前必须向用户确认目标和内容;只读查询可直接执行。
- 登录脚本已内置,不再依赖外部
serene-api技能:注册登录用的serene_login.py
已随本技能打包在scripts/下。但该登录步骤需要 Playwright + 系统浏览器(Windows 11 自带
Edge,零下载;无 Edge/Chrome 时才需playwright install chromium)。其余所有 API 调用仅用 Python
标准库(scripts/serene_client.py,基于 urllib),无需任何第三方包。 - 下文
<SKILLDIR>指本技能目录,用户级安装即
C:/Users/<用户名>/.workbuddy/skills/questionnaire-social。
调用脚本一律用绝对路径:Windows 上~会被 Git Bash 展开成/c/...,
Windows Python 无法识别该形式,必须写成C:/Users/...。
判断当前处于哪个阶段
先跑一次只读探测,据此决定走「首次引导」还是「日常运营」:
python <SKILLDIR>/scripts/serene_client.py GET /auth/me/
- 报「未找到 API Key」→ 走 A. 首次引导
- 正常返回 → 走 B. 日常运营
A. 首次引导(第一次安装 / 尚未注册)
完整话术与隐私说明见 references/onboarding.md,按步推进,一次只做一件事,
不要把所有内容一次性倒给用户。顺序:
- 介绍玩法 — 一句话说清问卷社交是什么、四步循环、两种问卷类型的区别。
- 注册取 Key — 微信扫码账号无密码,走本技能自带的
python <SKILLDIR>/scripts/serene_login.py
(用绝对路径;<SKILLDIR>见上文定义,登录脚本已随技能打包,不再依赖外部serene-api)。
前置检查(避免报「找不到文件」/「缺 playwright」):
- 确认serene_login.py存在于本技能scripts/下(打包自带,正常必有);
- 确认已装 Playwright:否则提示用户pip install playwright(浏览器用系统自带 Edge,
无需下载;仅当无 Edge/Chrome 时才需playwright install chromium)。
缺 Playwright 时不要硬跑,先给出上面的安装提示。 - 讲隐私边界 — 在写入任何个人信息之前主动说明。要点:
平台侧只展示昵称、问卷有is_public/opposite_gender_only/allow_anonymous
三个可见性开关、可随时删除;同时如实告知官网没有独立隐私政策页面,
问卷答案明文存储且创建者可见,敏感信息不要填。不要把这段包装成安全承诺。 - 完善资料 —
PATCH /auth/me/必须用平铺字段,嵌套profile写法会返回 200 但静默不写入。改完回读确认。 - 问社交意愿 — 「主要想找对象,还是找兴趣搭子?」
- 找对象 →q_type=friendship(每人限 1 份)
- 兴趣交友 →q_type=general(不限份数) - 创建问卷 — 见下方「创建问卷」。
- 设置定时任务 — 见下方「设置每日定时任务」。
创建问卷
先访谈再出题,不要直接套模板。出题方法、两类模板、计分配置与发布前自查清单见
references/questionnaire-design.md。
把方案写成 JSON,先 dry-run 校验,通过后再创建:
python <SKILLDIR>/scripts/create_questionnaire.py plan.json --dry-run # 本地校验+配额检查,不写线上
python <SKILLDIR>/scripts/create_questionnaire.py plan.json # 创建并回读确认题目写入
脚本会拦截几类高频错误:漏 description/passing_score(服务端强制但元数据谎称可选)、
枚举值非法、选择题缺 options、keyword 计分却没填 keywords(会导致所有人得 0 分)、
friendship 配额已满、passing_score 高于总分。
创建成功后把分享链接给用户:https://serene.uno/questionnaire/{id}/。
B. 日常运营
每日动态摘要
python <SKILLDIR>/scripts/daily_digest.py # 输出摘要并记录状态
python <SKILLDIR>/scripts/daily_digest.py --no-save # 只看不记
python <SKILLDIR>/scripts/daily_digest.py --json # 结构化输出
汇总今日一句、新收到的回答、新匹配、待答系统问卷、我的问卷概况。
状态存 ~/.serene/social_digest_state.json,只报增量,不会天天重复旧内容。
向用户汇报时用自然语言复述重点,不要直接粘脚本原始输出;
有人答了问卷或出现高契合度匹配时要明确点出来并给出下一步建议。
拉取并回答问卷
发现「感兴趣的问卷」有两条路:
- 问卷广场(他人公开的问卷,主要发现源)——
GET /questionnaires/?scope=square,
可叠加type=general|friendship按用户社交意愿过滤:
bash python <SKILLDIR>/scripts/answer_questionnaire.py square # 列出全部他人公开问卷 python <SKILLDIR>/scripts/answer_questionnaire.py square --type general # 只列兴趣类 python <SKILLDIR>/scripts/answer_questionnaire.py square --out sq.json # 存成 JSON 便于挑选
广场响应里没有城市字段,无法按同城二次排序,直接看标题/描述挑主题贴合的即可。
注意:scope=square之外的发现路径(public/discover/feed 等)与?search=均无效,别去找。 - 系统问卷——
GET /system-questionnaires/unanswered/。
挑好目标问卷 id 后,两步走:
# 1) 取题(只读)——同时生成答案骨架 JSON
python <SKILLDIR>/scripts/answer_questionnaire.py show <问卷ID> [--system]
# 2) 填好骨架后提交(写操作,先经用户确认)
python <SKILLDIR>/scripts/answer_questionnaire.py submit <问卷ID> answers.json [--system]
答题内容必须真实反映用户本人的想法:开放题先问用户怎么想,
或用已知的用户信息拟稿后交用户确认/修改再提交。
绝不能替用户编造价值观类答案——答错了会匹配到不合适的人,比不答更糟。
选题优先级:题量适中(≤20 题)、主题贴合用户兴趣的优先;
超长问卷(如 100+ 题)先问用户是否愿意投入。
设置每日定时任务
用 automation 能力创建循环任务(不要写 crontab):
- 先问用户希望几点收到动态,默认建议 9:00
scheduleType: recurring,如每天 9 点:rrule: FREQ=DAILY;BYHOUR=9;BYMINUTE=0- prompt 只描述任务本身,不要写时间和目录,例如:
> 查看我的思契每日动态:运行每日摘要脚本,用自然语言汇报新收到的回答和新匹配;
> 如果有广场新上架的问卷或待答的系统问卷,挑一份主题贴合我兴趣的推荐给我;
> 没有任何新变化就简短说明即可。
其它常用操作
# 任意端点直调(调试用)
python <SKILLDIR>/scripts/serene_client.py GET /questionnaires/
python <SKILLDIR>/scripts/serene_client.py GET /questionnaires/<id>/responses/
python <SKILLDIR>/scripts/serene_client.py PATCH /auth/me/ '{"bio":"新简介"}'
- 看某份问卷收到的回答:
GET /questionnaires/{id}/responses/,再用
GET /responses/{id}/看答案全文。 - 查匹配:友谊匹配
/matches/、系统匹配/system-matches/
(/matches/all/服务端 500,不要调)。 - 限流 300 次/小时,批量答题注意节流。