对大语言模型(LLM)应用的理解

为什么LLM记不住历史?

在模型厂商烧显卡训练出LLM的那一刻,LLM的知识和记忆就冻结了,LLM此时就相当于一个无状态的纯函数

type llm = (prompt: string) => string

比如Claude 3.5 Sonnet,prompt长度最大就是200K 200K即200,000,我们可简单理解为文本长度,实际各家计算方式不一致

那上层应用的记忆是怎么实现的?

对于LLM的上层应用,如MCopilot,原理就类似于:

code = llm(`${对话历史} ${文档上下文} ${代码上下文} ${用户问题}`)

具体就是,把各种文本拼起来,然后送入LLM期盼结果。

const 对话历史 = '对话历史:用户:请你帮我设计一个表单组件;系统:好的,先确认需求再开始。'
const 文档上下文 = '检索到的文档:表单组件 文档示例,用以收集、校验或提交数据,主要由输入框、选择器、单选按钮组、复选框等录入项和操作按钮等构成。'
const 代码上下文 = '用户当前代码:<template><div></div></template>'
const 用户问题 = '用户问题:帮我写个包含用户名、密码的登录表单'

const code = llm(`${对话历史} ${文档上下文} ${代码上下文} ${用户问题}`)

因为LLM是无状态的,所以记忆(对话历史)其实也是入参的一部分

每次都拼上历史记忆很难吗,为什么还是一关闭就忘光?

因为钱。

LLM按输入长度算钱。

以Claude 3.5 Sonnet为例,以200K长度输入调一次,输入成本就需**¥1.4**。

所以,所有上层应用都在努力最小化LLM的入参长度

如:

  • 保存全量对话历史,但调用LLM前先裁剪,只将最近的记录拼到入参里:llm(${对话历史**.slice(-500)**} ${用户问题})

  • 保存全量对话历史,但调用LLM前先搜索,只将相关的记录拼到入参里:llm(${**search**(对话历史, 用户问题)} ${用户问题})

够了,我有钱。

image.jpeg

除了成本,也有原因:

所以开发上层应用其实就是一种 在有限的输入长度内 平衡各文本成分 以获取更好结果 的艺术

应用案例

智能客服

// 一般的:直接让大模型回答
回答 = llm(`${用户问题}`)

// 高级点:先常规文本搜索一波,再结合搜索结果和用户问题,送给大模型阅读后回答(RAG)
回答 = llm(`${search(知识库, 用户问题)} ${用户问题}`)

// 再高级点的:在文本搜索前,先让大模型提炼下用户问题里的关键字,提高搜索结果质量(优化RAG召回)
回答 = llm(`${search(知识库, llm(`提炼关键字 ${用户问题}`))} ${用户问题}`)

// 再再高级点的:纯文本关键字匹配还是弱,不如先把句子编码为向量,在高维语义空间检索相关内容(优化RAG召回:引入向量数据库)
回答 = llm(`${search(embedding(知识库), embedding(用户问题)))} ${用户问题}`)

智能代理(AI Agent)

此时,LLM的角色为:

  • 自然语言需求 的任务规划器

  • 自然语言需求 -> 标准命令调用 的解析器

  • 自然语言需求 + 命令调用结果 的总结器

// 穿衣建议 AI Agent 伪代码

function AI穿衣建议() {
  工具函数 = [
    获取今天日期: () => 日期,
    查询某日天气: (日期) => 天气,
  ]

  对话记录 = [
    `系统:你负责根据天气给出穿衣建议,你有这些工具可用:${工具函数},需要使用时请按工具描述回复,给出建议后请以<END>结尾`,
  ]
  do {
    对话记录.push(`用户:${input()}`)
    回答 = llm(`${对话记录}`)

    if (回答是要调用工具) {
      对话记录.push(`调用工具:${回答}`)

      工具结果 = 按回答调用工具函数(回答)
      对话记录.push(`工具结果:${工具结果}`)
      continue;
    }

    // 普通回答
    对话记录.push(回答)
  } while(回答.endWith('<END>'))
  
  return 对话记录[-1] // 返回最后一个大模型的回答
}

AI穿衣建议('明天穿裙子可以吗?') // 预期:获取今日日期 -> 加一天 -> 查询天气 -> 综合总结建议
AI穿衣建议('我准备去跑个10公里') // 预期:获取今日日期 -> 查询天气 -> 综合总结建议
AI穿衣建议('雨天适合穿什么鞋?') // 预期:建议