Skip to content

Latest commit

 

History

History
394 lines (287 loc) · 13 KB

2. Ollama 在 LangChain 中的使用 - JavaScript 集成.md

File metadata and controls

394 lines (287 loc) · 13 KB

Ollama 在 LangChain 中的使用 - JavaScript 集成

简介

本文档介绍了如何在 JavaScript 环境中使用 Ollama 与 LangChain 集成,以创建强大的 AI 应用。Ollama 是一个开源的大语言模型部署工具,而 LangChain 则是一个用于构建基于语言模型的应用的框架。通过结合这两者,我们可以在本地环境中快速部署和使用先进的 AI 模型。

注: 本文档包含核心代码片段和详细解释。完整代码可在 notebook/c5/ollama_langchain_javascript 中找到。

1. 环境设置

配置Node.js环境

首先,确保你的系统已安装 Node.js。你可以从 Node.js官网 下载并安装最新版本。

创建项目并安装依赖

  1. 切换到运行目录运行:
cd notebook/C5/ollama_langchain_javascript
npm init -y
  1. 安装必要的依赖:
npm install @langchain/ollama @langchain/core @langchain/community zod
  1. package.json 文件中添加 "type": "module" 以启用ES模块支持:
{
  "type": "module",
  // ... 其他配置
}

2. 下载所需模型并初始化 Ollama

下载 llama3.1 模型

  1. 进入官网 https://ollama.com/download 下载并安装 Ollama 到可用的受支持平台。
  2. 查看 https://ollama.ai/library 了解所有可用的模型。
  3. 通过 ollama pull <name-of-model> 命令获取可用 LLM 模型(例如:ollama pull llama3.1)。

命令行执行完毕后如图所示:

Ollama 模型下载

模型存储位置:

  • Mac: ~/.ollama/models/
  • Linux(或 WSL): /usr/share/ollama/.ollama/models
  • Windows: C:\Users\Administrator\.ollama\models

下载完毕后,需要确保 Ollama 服务已经启动:

ollama ps

img.png

3. 基本使用示例

使用 ChatOllama 进行简单对话

可运行 base_chat.js 文件,具体代码如下:

import { Ollama } from "@langchain/community/llms/ollama";

const ollama = new Ollama({
  baseUrl: "http://localhost:11434",  // 确保Ollama服务已经启动
  model: "llama3.1", // 替换为实际使用的模型
});

const stream = await ollama.stream(
  `你比GPT4厉害吗?`
);

const chunks = [];
for await (const chunk of stream) {
  chunks.push(chunk);
}

console.log(chunks.join(""));

运行代码:

node base_chat.js

这段代码做了以下几件事:

  1. 导入 Ollama 类并初始化它,指定模型和基础URL。
  2. 使用 stream 方法发送一个问题给模型,这允许我们逐块接收响应。
  3. 使用 for-await 循环收集所有响应块。
  4. 将所有块组合并打印出完整响应。

多模态模型使用

运行base_multimodal.js文件,具体代码如下:

import { Ollama } from "@langchain/community/llms/ollama";
import * as fs from "node:fs/promises";

const imageData = await fs.readFile("../../../docs/images/C5-1-4.png"); // 可以替换为你想询问的图片
const model = new Ollama({
  model: "llava",
  baseUrl: "http://127.0.0.1:11434",
}).bind({
  images: [imageData.toString("base64")],
});
const res = await model.invoke("图片里是什么动物呀?");

console.log({ res });

运行代码:

node base_multimodal.js

这段代码演示了如何使用多模态模型(如 llava)处理图像和文本输入:

  1. 读取图像文件并将其转换为base64编码。
  2. 初始化 Ollama 模型,并使用 bind 方法将图像数据绑定到模型。
  3. 使用 invoke 方法发送一个关于图像的问题。
  4. 打印模型的响应。

工具调用

运行 base_tool.js 文件,代码如下:

import { tool } from "@langchain/core/tools";
import { ChatOllama } from "@langchain/ollama";
import { z } from "zod";

// 定义简单计算器工具
const simpleCalculatorTool = tool((args) => {
  const { operation, x, y } = args;
  switch (operation) {
    case "add":
      return x + y;
    case "subtract":
      return x - y;
    case "multiply":
      return x * y;
    case "divide":
      if (y !== 0) {
        return x / y;
      } else {
        throw new Error("Cannot divide by zero");
      }
    default:
      throw new Error("Invalid operation");
  }
}, {
  name: "simple_calculator",
  description: "Perform simple arithmetic operations",
  schema: z.object({
    operation: z.enum(["add", "subtract", "multiply", "divide"]),
    x: z.number(),
    y: z.number(),
  }),
});

// 定义模型
const llm = new ChatOllama({
  model: "llama3.1",
  temperature: 0,
});

// 将工具绑定到模型
const llmWithTools = llm.bindTools([simpleCalculatorTool]);

// 使用模型进行工具调用
const result = await llmWithTools.invoke(
  "你知道一千万乘二是多少吗?请使用 'simple_calculator' 工具来计算。"
);

console.log(result);

运行代码:

node base_tool.js

这段代码展示了如何定义和使用工具:

  1. 使用 tool 函数定义一个简单的计算器工具,包括操作逻辑和参数schema。
  2. 初始化 ChatOllama 模型。
  3. 使用 bindTools 方法将工具绑定到模型。
  4. 使用 invoke 方法发送一个需要计算的问题,模型会自动调用相应的工具。

4. 进阶用法

自定义提示模板

自定义提示模板不仅提高了内容生成的效率,还确保了输出的一致性和针对性。通过精心设计的模板,我们可以充分利用AI模型的能力,同时保持对输出内容的控制和指导:

import { ChatOllama } from "@langchain/ollama";
import { ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate } from "@langchain/core/prompts";

// 初始化ChatOllama模型
const model = new ChatOllama({
  model: "llama3.1",
  temperature: 0.7,
});

const systemMessageContent = `
你是一位经验丰富的电商文案撰写专家。你的任务是根据给定的产品信息创作吸引人的商品描述。
请确保你的描述简洁、有力,并且突出产品的核心优势。
`;

const humanMessageTemplate = `
请为以下产品创作一段吸引人的商品描述:
产品类型: {product_type}
核心特性: {key_feature}
目标受众: {target_audience}
价格区间: {price_range}
品牌定位: {brand_positioning}

请提供以下三种不同风格的描述,每种大约50字:
1. 理性分析型
2. 情感诉求型
3. 故事化营销型
`;

const prompt = ChatPromptTemplate.fromMessages([
  SystemMessagePromptTemplate.fromTemplate(systemMessageContent),
  HumanMessagePromptTemplate.fromTemplate(humanMessageTemplate),
]);

const chain = prompt.pipe(model);

async function generateProductDescriptions(productInfo) {
  const response = await chain.invoke(productInfo);
  return response.content;
}

// 示例使用
const productInfo = {
  product_type: "智能手表",
  key_feature: "心率监测和睡眠分析",
  target_audience: "注重健康的年轻专业人士",
  price_range: "中高端",
  brand_positioning: "科技与健康的完美结合"
};

generateProductDescriptions(productInfo)
  .then((result) => console.log(result))
  .catch((error) => console.error("Error:", error));

运行代码:

node advanced_prompt.js

这段代码展示了如何创建和使用自定义提示模板:

  1. 定义系统消息和人类消息模板。
  2. 使用 ChatPromptTemplate.fromMessages 创建一个完整的提示模板。
  3. 使用 pipe 方法将提示模板与模型连接起来,创建一个处理链。
  4. 定义一个函数来生成产品描述,该函数使用处理链来处理输入的产品信息。

自定义提示模板在实际应用中有着广泛的用途,尤其是在需要生成特定格式或风格的内容时。以下是一些实际应用场景:

  1. 电子商务产品描述生成:正如本例所示,可以用于自动生成不同风格的产品描述,提高产品页面的吸引力和转化率。

  2. 客户服务回复模板:可以创建各种情景的回复模板,如处理投诉、提供产品信息等,确保客服回复的一致性和专业性。

  3. 新闻报道生成:可以设计模板来生成不同类型的新闻报道,如突发新闻、深度分析等,帮助记者快速起草初稿。

  4. 个性化营销邮件:根据客户数据和营销目标,生成个性化的营销邮件内容,提高邮件营销的效果。

高级JSON输出与知识图谱生成

在这个例子中,我们展示了如何使用 Ollama 和 LangChain 生成结构化的 JSON 输出,特别是用于创建知识图谱。 这种方法与 Microsoft 的开源项目 GraphRAG 有着密切的联系,尤其是在自动化知识提取和三元组生成方面。

import { ChatOllama } from "@langchain/ollama";
import { PromptTemplate } from "@langchain/core/prompts";
import { HumanMessage, SystemMessage } from "@langchain/core/messages";

const systemTemplate = `
你是一位医疗领域的专家,擅长创建知识图谱。请将所有响应格式化为具有以下结构的JSON对象:
{
  "节点": [
    {"id": "string", "标签": "string", "类型": "string"}
  ],
  "关系": [
    {"源": "string", "目标": "string", "关系": "string"}
  ]
}
确保所有节点id都是唯一的,并且关系引用的是已存在的节点id。
`;

const humanTemplate = `
请为医疗主题"{topic}"创建一个知识图谱。包括以下相关概念: {concepts}。
提供至少5个节点和5个关系。请确保使用中文回答。
`;

const systemMessage = new SystemMessage(systemTemplate);

const humanPrompt = PromptTemplate.fromTemplate(humanTemplate);

const llmJsonMode = new ChatOllama({
  baseUrl: "http://localhost:11434", // 默认值
  model: "llama3.1",
  format: "json",
});

async function generateMedicalKnowledgeGraph(topic, concepts) {
  try {
    const humanMessageContent = await humanPrompt.format({
      topic: topic,
      concepts: concepts.join("、"),
    });

    const humanMessage = new HumanMessage(humanMessageContent);

    const messages = [systemMessage, humanMessage];

    const result = await llmJsonMode.call(messages);
    console.log(JSON.stringify(result, null, 2));
    return result;
  } catch (error) {
    console.error("生成知识图谱时出错:", error);
  }
}

// 使用示例
const topic = "糖尿病";
const concepts = ["胰岛素", "血糖", "并发症", "饮食管理", "运动疗法"];

generateMedicalKnowledgeGraph(topic, concepts);

运行代码:

node advanced_json.js

这段代码演示了如何使用 Ollama 生成结构化的 JSON 输出:

  1. 定义系统模板,指定期望的 JSON 结构。
  2. 创建一个人类提示模板,用于生成知识图谱的请求。
  3. 初始化 ChatOllama 模型,设置 format: "json" 以获取JSON输出。
  4. 定义一个函数来生成医疗知识图谱,该函数组合系统消息和人类消息,并调用模型。

我们可以窥见到通过 json 格式的特定输出,可以将其运用到许多方面:

  1. 自动化三元组生成: 在传统方法中,创建知识图谱通常需要大量的人工标注工作。专家需要仔细阅读文档,识别重要概念和它们之间的关系,然后手动创建三元组(主体-关系-客体)。这个过程不仅耗时,而且容易出错,特别是在处理大量文档时。 使用我们的方法,大语言模型可以自动从给定的主题和概念生成相关的节点和关系。这极大地加速了知识图谱的构建过程。

  2. 数据增强: 这种方法不仅可以用于直接生成知识图谱,还可以用于数据增强。例如:

    • 扩展现有的训练数据集:通过让模型基于已有的三元组生成新的相关三元组。
    • 创建多样化的示例:为不同的医疗条件生成知识图谱,增加数据的多样性。
    • 跨语言数据生成:通过调整提示,可以生成不同语言的知识图谱,支持多语言应用。
  3. 提高数据质量: 大语言模型可以利用其广泛的知识基础,生成高质量、连贯的知识图谱。通过精心设计的提示,我们可以确保生成的数据符合特定的质量标准和领域规范。

  4. 灵活性和可扩展性: 这种方法非常灵活,可以轻松适应不同的领域和需求:

    • 通过修改系统提示,我们可以改变输出的JSON结构,以适应不同的知识图谱格式。
    • 可以轻松地将此方法扩展到其他领域,如科技、金融、教育等。

结论

通过这些示例,我们展示了如何使用 Ollama 和 LangChain 在 JavaScript 环境中构建各种 AI 应用,从简单的对话系统到复杂的知识图谱生成。这些工具和技术为开发强大的AI应用提供了坚实的基础。

Ollama 和 LangChain 的结合为开发者提供了极大的灵活性和可能性。你可以根据具体需求,选择合适的模型和组件,构建出适合你的应用场景的 AI 系统。

随着技术的不断发展,我们期待看到更多创新的应用出现。希望这个指南能够帮助你开始你的 AI 开发之旅,并激发你的创造力,去探索 AI 技术的无限可能。