接入成员画像 Dify 工作流并清理旧提取逻辑
- 新增 member_context 专用 DifyClient,统一兼容 completion 与 workflow 两种调用模式 - 将成员画像插件默认切换到 Dify workflow 模式,配置改用新的 workflow 应用与 workflows/run 接口 - 生成可直接导入 Dify 的成员画像工作流 DSL 文件,方便后台一键导入和发布 - 补充 Dify 工作流接入说明文档,明确输入字段、输出字段、发布步骤与插件消费方式 - 清理旧的单成员日摘要提取链路,日级画像统一收敛到群日批量提取路径,减少无效分支和历史残留 - 去除 member_context 内部多处旧 requests 直连调用,统一改为通过 DifyClient 调用 AI 服务 - 优化群日批量结果解析逻辑,只按 wxid 作为唯一主键识别成员,不再依赖昵称做唯一判断 - 新增按 wxid 的结果去重与完整度评分逻辑,遇到重复成员结果时优先保留字段更完整、置信度更高的一条 - 保留现有初始化、增量、周/月聚合与最终画像生成链路,同时剔除 workflow 接入后已无效或低价值的旧逻辑 - 为后续继续收紧 fallback 标记、增强后台质量诊断和优化工作流输出稳定性打下基础
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
# 成员画像 Dify Workflow 设计
|
||||
|
||||
## 当前状态
|
||||
|
||||
- Dify app 信息已确认:
|
||||
- `base_url`: `http://192.168.2.240/v1`
|
||||
- `api_key`: `app-b2cj03DipGCIAmgBfcx7SKsT`
|
||||
- `mode`: `workflow`
|
||||
- 当前接口探测结果:
|
||||
- `GET /info` 正常,说明应用存在
|
||||
- `POST /workflows/run` 返回 `Workflow not published`
|
||||
- 结论:
|
||||
- 插件侧已切为 workflow 调用模式
|
||||
- 你需要在 Dify 后台把工作流发布,发布后插件才能真正调用
|
||||
|
||||
## 可直接导入的 DSL
|
||||
|
||||
仓库里已生成可导入文件:
|
||||
|
||||
- [member_context_workflow.yml](/d:/learn/abot/plugins/member_context/member_context_workflow.yml)
|
||||
|
||||
你可以直接在 Dify 后台导入这个 DSL,再检查模型可用性并发布。
|
||||
|
||||
## 目标
|
||||
|
||||
将“群某一天的成员画像提取”从单大提示词,拆成 Dify 内部轻工作流,减少结果波动:
|
||||
|
||||
1. 按 `wxid` 作为唯一主键
|
||||
2. 不用昵称做唯一识别
|
||||
3. 优先提取稳定的行为信号
|
||||
4. 允许弱信号为空
|
||||
5. 输出严格 JSON 文本,供插件直接落库
|
||||
|
||||
## 建议工作流
|
||||
|
||||
### 1. Start 节点
|
||||
|
||||
输入变量建议如下:
|
||||
|
||||
- `query`:文本,大段提示词正文,插件会直接传入
|
||||
- `chatroom_id`:文本
|
||||
- `digest_date`:文本,格式 `YYYY-MM-DD`
|
||||
- `member_labels`:段落,候选成员列表,格式 `wxid | display_name`
|
||||
- `compressed_chat`:段落,压缩后的群聊天文本
|
||||
|
||||
说明:
|
||||
- 当前插件已按上述字段调用 workflow
|
||||
- 为了兼容未来扩展,`query` 仍会保留
|
||||
|
||||
### 2. LLM 节点:群日画像批量提取
|
||||
|
||||
模型建议:
|
||||
- 上下文长度足够大的模型
|
||||
- 响应稳定、结构化能力强的模型
|
||||
|
||||
系统提示词建议:
|
||||
|
||||
```text
|
||||
你是微信群后台的成员日行为证据提取器。
|
||||
|
||||
任务:
|
||||
根据给定的一天群聊记录,只按 wxid 识别成员,输出每个成员当天的结构化行为观察。
|
||||
|
||||
关键规则:
|
||||
1. wxid 是唯一标识。display_name 仅用于展示,不用于身份判定。
|
||||
2. 每个 wxid 最终只能输出一条记录,严禁重复输出同一个 wxid。
|
||||
3. 请先按 wxid 汇总该成员全天发言,再提取结果。
|
||||
4. 即使成员发言以短句为主,只要样本量足够,也必须尽量提炼:
|
||||
- topics
|
||||
- skill_signals
|
||||
- value_preferences
|
||||
- habit_signals
|
||||
- engagement_traits
|
||||
- social_role
|
||||
- temperament_signal
|
||||
- summary_text
|
||||
5. identity_clues、family_signals、life_stage_signals 没有明确公开证据时允许为空。
|
||||
6. 不允许因为“短句较多”就统一输出空数组和通用摘要。
|
||||
7. 不做心理诊断、不做隐私猜测、不把玩笑当事实。
|
||||
8. 只能输出候选成员列表中的 wxid。
|
||||
|
||||
输出要求:
|
||||
- 只输出严格 JSON,不要 markdown,不要解释。
|
||||
- 输出格式:
|
||||
{
|
||||
"members": [
|
||||
{
|
||||
"wxid": "成员wxid",
|
||||
"display_name": "显示名",
|
||||
"topics": ["主题1"],
|
||||
"identity_clues": ["身份线索1"],
|
||||
"skill_signals": ["技能信号1"],
|
||||
"family_signals": ["家庭线索1"],
|
||||
"life_stage_signals": ["阶段线索1"],
|
||||
"value_preferences": ["价值偏好1"],
|
||||
"interaction_style": "一句中文",
|
||||
"message_pattern": "一句中文",
|
||||
"response_style_hint": "一句中文",
|
||||
"habit_signals": ["习惯1"],
|
||||
"engagement_traits": ["参与特征1"],
|
||||
"decision_style": "一句中文",
|
||||
"social_role": "一句中文",
|
||||
"reply_taboos": ["避坑1"],
|
||||
"temperament_signal": "一句中文",
|
||||
"summary_text": "不超过100字",
|
||||
"representative_messages": ["原话1", "原话2"],
|
||||
"confidence": 0.95
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
用户提示词建议:
|
||||
|
||||
```text
|
||||
群ID: {{chatroom_id}}
|
||||
日期: {{digest_date}}
|
||||
|
||||
候选成员:
|
||||
{{member_labels}}
|
||||
|
||||
压缩后的群聊记录:
|
||||
{{compressed_chat}}
|
||||
```
|
||||
|
||||
### 3. End 节点
|
||||
|
||||
输出变量建议:
|
||||
|
||||
- `text`:直接输出 LLM 节点的文本结果
|
||||
|
||||
说明:
|
||||
- 插件默认读取 workflow outputs 中的 `text`
|
||||
- 如果你在 Dify 里把输出字段换成别的名字,例如 `result_json`,需要同步修改插件配置中的 `workflow_output_key`
|
||||
|
||||
## 插件侧已对接的输入
|
||||
|
||||
当前插件发给 workflow 的 inputs 如下:
|
||||
|
||||
```json
|
||||
{
|
||||
"query": "完整提示词文本",
|
||||
"chatroom_id": "45317011307@chatroom",
|
||||
"digest_date": "2026-04-01",
|
||||
"member_labels": "wxid_a | 张三\nwxid_b | 李四",
|
||||
"compressed_chat": "【09:20】...\n..."
|
||||
}
|
||||
```
|
||||
|
||||
## 插件侧已对接的输出
|
||||
|
||||
插件会优先读取:
|
||||
|
||||
1. `outputs.text`
|
||||
2. `outputs.answer`
|
||||
3. `outputs.result_json`
|
||||
4. `outputs.result`
|
||||
|
||||
如果你的工作流最终输出不是 `text`,请把
|
||||
|
||||
```toml
|
||||
workflow_output_key = "text"
|
||||
```
|
||||
|
||||
改成对应字段名。
|
||||
|
||||
## 为什么建议这样设计
|
||||
|
||||
相较于把所有事情都压进单次 completion:
|
||||
|
||||
- workflow 模式更适合后面继续拆节点
|
||||
- 可以后续增加:
|
||||
- JSON 清洗 Code 节点
|
||||
- wxid 去重 Code 节点
|
||||
- 质量分判断节点
|
||||
- 插件侧已经兼容 workflow 调用,不需要再改主逻辑
|
||||
|
||||
## 你现在要做的最后一步
|
||||
|
||||
在 Dify 后台:
|
||||
|
||||
1. 打开 `member_context`
|
||||
2. 按上面结构补 Start / LLM / End
|
||||
3. 确保 End 输出字段叫 `text`
|
||||
4. 点击 Publish 发布
|
||||
|
||||
发布完成后,插件就能直接调用。
|
||||
Reference in New Issue
Block a user