放弃 if-else:学会用 Compose(组合) 将复杂 AI 判别逻辑串成流水线

在处理 AI 业务逻辑时,代码很容易沦为"if-else 地狱"。比如,你需要判断用户输入的安全性、识别意图、计算 Token、注入上下文,最后再格式化。

如果用传统的命令式写法,逻辑会像乱麻一样交织。而 函数组合(Function Composition / Compose) 则是将这些逻辑解耦成一颗颗"逻辑原子",再通过流水线(Pipeline)串联起来。

以下是针对 前端 场景设计的 8 个 Compose 实战案例,让我们彻底告别面条代码。


核心工具:pipe 助手函数

为了符合人类从左到右的阅读习惯,我们通常使用 pipe(左向右组合)而非数学意义上的 compose(右向左)。

JavaScript

javascript 复制代码
const pipe = (...fns) => (initialValue) => 
  fns.reduce((v, f) => f(v), initialValue);

1. 自动化 Prompt 清理流水线

在将用户输入发送给 Gemini 之前,必须进行预处理。

JavaScript

ini 复制代码
const trim = (str) => str.trim();
const removeExtraSpaces = (str) => str.replace(/\s+/g, ' ');
const stripHtml = (str) => str.replace(/<[^>]*>?/gm, '');

const sanitizePrompt = pipe(
  trim,
  stripHtml,
  removeExtraSpaces
);

const rawInput = "  <div>  Hello   AI  </div>  ";
console.log(sanitizePrompt(rawInput)); // "Hello AI"

2. 敏感信息(PII)脱敏网关

在金融或 AI 场景下,保护隐私是红线。

JavaScript

javascript 复制代码
const maskPhone = (s) => s.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
const maskEmail = (s) => s.replace(/(.{3}).*(@.*)/, '$1***$2');

const safetyGate = pipe(
  maskPhone,
  maskEmail
);

console.log(safetyGate("联系人:13812345678,邮箱:gemini@google.com"));
// "联系人:138****5678,邮箱:gem***@google.com"

3. 多级意图识别(Intent Routing)

替代臃肿的 switch-case,根据关键词动态打标签。

JavaScript

ini 复制代码
const checkFinance = (ctx) => ctx.text.includes('汇率') ? { ...ctx, intent: 'FINANCE' } : ctx;
const checkCoding = (ctx) => ctx.text.includes('代码') ? { ...ctx, intent: 'CODING' } : ctx;
const defaultIntent = (ctx) => ctx.intent ? ctx : { ...ctx, intent: 'GENERAL' };

const routeIntent = pipe(
  checkFinance,
  checkCoding,
  defaultIntent
);

console.log(routeIntent({ text: '查询今日汇率' }).intent); // "FINANCE"

4. Token 消耗预估与截断

防止 Prompt 过长导致超支或报错。

JavaScript

ini 复制代码
const countTokens = (ctx) => ({ ...ctx, tokens: ctx.text.length / 4 }); // 简单估算
const checkLimit = (ctx) => ctx.tokens > 100 ? { ...ctx, isOver: true } : ctx;
const truncateIfNeed = (ctx) => ctx.isOver ? { ...ctx, text: ctx.text.slice(0, 400) } : ctx;

const tokenManager = pipe(
  countTokens,
  checkLimit,
  truncateIfNeed
);

5. AI 响应内容的"去幻觉"清洗

AI 经常会说"作为一个 AI 模型...",我们可以用 pipe 自动化剔除这些废话。

JavaScript

javascript 复制代码
const removeApologies = (s) => s.replace(/抱歉,作为一个.*模型/g, '');
const removeAIPreach = (s) => s.replace(/我无法提供.*建议/g, '数据暂不可用');
const formatMarkdown = (s) => s.trim().startsWith('#') ? s : `# 回答\n${s}`;

const polishResponse = pipe(
  removeApologies,
  removeAIPreach,
  formatMarkdown
);

6. 复杂的 Prompt 上下文注入

在你的 AI Prompt Manager 中,构建最终发送给模型的完整指令。

JavaScript

javascript 复制代码
const injectRole = (role) => (input) => `你是${role}。${input}`;
const injectContext = (context) => (input) => `基于背景:${context},回答:${input}`;
const addOutputFormat = (input) => `${input} 请用 JSON 格式返回。`;

const buildPrompt = pipe(
  injectRole('专业前端架构师'),
  injectContext('当前项目使用 Vue3 + Vite'),
  addOutputFormat
);

console.log(buildPrompt('如何优化打包体积?'));

7. 异常熔断与降级策略

当判别逻辑发现异常时,直接返回降级结果。

JavaScript

kotlin 复制代码
const validateSchema = (data) => data.id ? data : { error: 'Invalid Data' };
const handleErrors = (data) => data.error ? { ...data, fallback: true } : data;
const logTelemetry = (data) => { console.log('Tracking:', data); return data; };

const dataPipeline = pipe(
  validateSchema,
  handleErrors,
  logTelemetry
);

8. 实时搜索列表的性能增强

结合我们之前聊过的 scheduler 概念,在 pipe 中嵌入性能控制。

JavaScript

ini 复制代码
const heavyFilter = (list) => list.filter(item => item.priority > 5);
const sortData = (list) => list.sort((a, b) => b.score - a.score);
const limitResults = (list) => list.slice(0, 10);

// 在 AI 建议搜索时调用
const processSearchList = pipe(
  heavyFilter,
  sortData,
  limitResults
);

为什么资深开发必须用 Compose

  1. 高度可测试性 :每一个被组合的小函数(如 trim, maskPhone)都是纯函数,非常容易写单元测试。
  2. 声明式逻辑 :看一眼 pipe(...) 里的函数名,你就知道整个业务流程在干什么,而不是深陷在 if 的嵌套层级里。
  3. 对 AI 友好 :如果你让 Trae 或 Cursor 重构一个 500 行的 if-else 函数,它可能会出错;但如果你让它写一个"处理脱敏逻辑的原子函数",它的准确率是 100%

相关推荐
C澒9 分钟前
微前端容器标准化:公共能力标准化
前端·架构
Setsuna_F_Seiei17 分钟前
AI 对话应用之 JS 的流式接口数据处理
前端·javascript·ai编程
英俊潇洒美少年27 分钟前
react如何实现 vue的$nextTick的效果
javascript·vue.js·react.js
青柠代码录1 小时前
【Vue3】Vue Router 4 路由全解
前端·vue.js
无限大61 小时前
《AI观,观AI》:专栏总结+答疑|吃透核心,解决你用AI的所有困惑
前端·后端
蜡台2 小时前
element-ui 2 el-tree 内容超长滚动条不显示问题
前端·vue.js·elementui·el-tree·v-deep
小小小小宇3 小时前
软键盘常见问题(二)
前端
小小小小宇3 小时前
软键盘常见问题
前端
小小小小宇4 小时前
富文本编辑器知识体系(三)
前端
小小小小宇4 小时前
富文本编辑器知识体系(二)
前端