feedback-roundtrip-smoke.js 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/env node
  2. const fs = require('fs');
  3. const os = require('os');
  4. const path = require('path');
  5. const { runTihaoSourcing } = require('../mcp/src/tools/tihao-brief-sourcing-run');
  6. const { readFeedbackCsv } = require('./import-feedback-memory');
  7. const { readMemory, applyFeedbackRecordsToMemory } = require('../mcp/src/features/tihao-sourcing/preference-memory');
  8. async function main() {
  9. const out = fs.mkdtempSync(path.join(os.tmpdir(), 'tihao-feedback-roundtrip-'));
  10. const memoryPath = path.join(out, 'memory.json');
  11. const feedbackPath = path.join(out, 'feedback.csv');
  12. const blockedNames = [
  13. '618母婴好物清单',
  14. '精致生活小鹿',
  15. '办公室健康零食测评',
  16. '真实家居清洁实验室'
  17. ];
  18. fs.writeFileSync(feedbackPath, [
  19. 'brief编号,平台,博主名称,主页链接,人工复核标签,反馈原因,归因类型,影响范围,是否升级为团队规则,下一轮动作',
  20. 'flower-skincare,小红书,618母婴好物清单,https://www.xiaohongshu.com/user/profile/xhs-dha-003,跑偏,护肤 Brief 不应优先推荐母婴清单号,需求解析,客户品牌级,否,剔除账号',
  21. 'flower-skincare,小红书,精致生活小鹿,https://www.xiaohongshu.com/user/profile/xhs-beauty-002,调性不符,封面下沉且主页质感不符,主页证据,团队规则,是,剔除账号',
  22. 'flower-skincare,小红书,办公室健康零食测评,https://www.xiaohongshu.com/user/profile/xhs-food-001,主页质感不符,封面下沉且主页质感不符,主页证据,团队规则,是,剔除账号',
  23. 'flower-skincare,小红书,真实家居清洁实验室,https://www.xiaohongshu.com/user/profile/xhs-home-001,参考账号不像,封面下沉且主页质感不符,主页证据,团队规则,是,剔除账号',
  24. 'flower-skincare,小红书,下沉硬广一号,https://www.xiaohongshu.com/user/profile/xhs-low-001,主页质感不符,封面下沉且主页质感不符,主页证据,团队规则,是,剔除账号',
  25. 'flower-skincare,小红书,下沉硬广二号,https://www.xiaohongshu.com/user/profile/xhs-low-002,主页质感不符,封面下沉且主页质感不符,主页证据,团队规则,是,剔除账号'
  26. ].join('\n'), 'utf8');
  27. const memory = applyFeedbackRecordsToMemory(readMemory(memoryPath), readFeedbackCsv(feedbackPath));
  28. fs.writeFileSync(memoryPath, JSON.stringify(memory, null, 2), 'utf8');
  29. const result = await runTihaoSourcing({
  30. collectionMode: 'sample',
  31. briefText: [
  32. '客户名称:花漾肌研',
  33. '平台与人数:小红书 6 人,抖音 2 人',
  34. '粉丝量范围:2万-50万',
  35. '预算范围:3000-18000',
  36. '偏好真实体验、素人感、成分拆解、敏感肌修护,不要硬广。'
  37. ].join('\n'),
  38. memory: memoryPath,
  39. output: path.join(out, 'second-round')
  40. });
  41. assert(result.status === 'ok', 'second round sourcing should return ok');
  42. for (const name of blockedNames) {
  43. assert(memory.blockedCreators.includes(name), `${name} should be blocked in memory`);
  44. assert(!result.data.candidates.some(item => item.displayName === name), `${name} should not enter client-ready candidates`);
  45. }
  46. assert(memory.blockedStyles.some(item => item.includes('封面下沉且主页质感不符')), 'tone/homepage feedback should create blocked style memory');
  47. assert(memory.teamRuleSuggestions.length >= 1, 'three repeated team-scope feedback rows should create team rule suggestion');
  48. assert(memory.teamRuleSuggestions[0].count >= 3, 'team rule suggestion should require repeated evidence');
  49. assert(result.data.criteria.memory.feedbackSummary.total === 6, 'second round should carry feedback summary');
  50. console.log(`feedback roundtrip smoke ok: ${out}`);
  51. }
  52. function assert(condition, message) {
  53. if (!condition) throw new Error(message);
  54. }
  55. main().catch(error => {
  56. console.error(error && error.stack ? error.stack : String(error));
  57. process.exit(1);
  58. });