一、模型调用平台
-
CloeAI:www.closeai-asia.com
二、 安装库
# 安装核心库和 OpenAI 集成(最常用)
npm install @langchain/core @langchain/openai
# 如果你需要使用 LangGraph (构建复杂智能体推荐)
npm install @langchain/langgraph
三、大模型的基本调用
agents.service.ts
import { Injectable } from '@nestjs/common';
import { ChatOpenAI } from '@langchain/openai';
import { HumanMessage } from '@langchain/core/messages';
@Injectable()
export class AgentsService {
private llm: ChatOpenAI;
constructor() {
// 1. 从环境变量获取配置,避免硬编码
// 建议在 .env 文件中定义 VITE_OPENAI_API_KEY 或 OPENAI_API_KEY
const apiKey = process.env.OPENAI_API_KEY; // 生产环境务必使用环境变量
const baseUrl = process.env.OPENAI_BASE_URL;
// 2. 初始化 ChatOpenAI
this.llm = new ChatOpenAI({
modelName: 'ernie-3.5-8k', // 对应 Python 的 model
openAIApiKey: apiKey, // 对应 Python 的 api_key
configuration: {
baseURL: baseUrl, // 对应 Python 的 base_url
},
temperature: 0, // 可选:设置温度
});
}
/**
* 调用 LLM 并返回内容
*/
async explainNeuralNetworks(): Promise<string> {
// 3. 构建消息 (LangChain TS 推荐使用 Message 对象)
const messages = [new HumanMessage('解释神经网络原理')];
// 4. 调用 invoke (异步操作,需 await)
const response = await this.llm.invoke(messages);
// 5. 获取内容
// response.content 可能是字符串或数组,通常直接转为字符串
return response.content as string;
}
}
agents.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AgentsService } from './agents.service';
@Controller('agents')
export class AgentsController {
constructor(private readonly agentsService: AgentsService) {}
@Get('test-llm')
async testLlm() {
const content = await this.agentsService.explainNeuralNetworks();
return {
success: true,
content,
};
}
}
.env文件的配置
OPENAI_API_KEY=XXXXX
OPENAI_BASE_URL=XXXXX
app.module.ts中确保加载了环境变量
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AgentsModule } from './agents/agents.module';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [ConfigModule.forRoot({ isGlobal: true }), AgentsModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
- 接口测试:
四、关于对话模型的Message(消息)
LangChain有一些内置的消息类型:
🔥 SystemMessage :设定AI行为规则或背景信息。比如设定AI的初始状态、行为模式或对话的总体目标。比如“作为一个代码专家”,或者“返回json格式”。通常作为输入消息序列中的第一个传递。
🔥 HumanMessage :表示来自用户输入。比如“实现 一个快速排序方法”
🔥 AIMessage :存储AI回复的内容。这可以是文本,也可以是调用工具的请求
ChatMessage :可以自定义角色的通用消息类型
FunctionMessage/ToolMessage :函数调用/工具消息,用于函数调用结果的消息类型
- 举例:
//agents.service.ts
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
const messages = [
new SystemMessage('你是一位乐于助人的智能小助手'),
new HumanMessage('你好,请你介绍一下你自己'),
];
五、关于模型调用的方法
为了尽可能简化自定义链的创建,我们实现了一个"Runnable"协议。许多LangChain组件实现了 Runnable 协议,包括聊天模型、提示词模板、输出解析器、检索器、代理(智能体)等。
Runnable 定义的公共的调用方法如下:
-
invoke : 处理单条输入,等待LLM完全推理完成后再返回调用结果
-
stream : 流式响应,逐字输出LLM的响应结果
-
batch : 处理批量输入
这些也有相应的异步方法,应该与 asyncio 的 await 语法一起使用以实现并发:
-
astream : 异步流式响应
-
ainvoke : 异步处理单条输入
-
abatch : 异步处理批量输入
-
astream_log : 异步流式返回中间步骤,以及最终响应
-
astream_events : 异步流式返回链中发生的事件
流式输出:
agents.service.ts
import { Injectable } from '@nestjs/common';
import { ChatOpenAI } from '@langchain/openai';
import { HumanMessage } from '@langchain/core/messages';
@Injectable()
export class AgentsService {
private llm: ChatOpenAI;
constructor() {
// 1. 从环境变量获取配置
const apiKey = process.env.OPENAI_API_KEY;
const baseUrl = process.env.OPENAI_BASE_URL;
// 2. 初始化 ChatOpenAI
// 注意:streaming: true 是 ChatOpenAI 的默认行为之一,但显式声明更清晰
this.llm = new ChatOpenAI({
modelName: 'ernie-3.5-8k',
openAIApiKey: apiKey,
configuration: {
baseURL: baseUrl,
},
temperature: 0,
streaming: true, // 启用流式输出
});
}
/**
* 流式调用 LLM
* @returns AsyncIterable<string> 返回一个异步迭代器,每次迭代返回一个内容片段
*/
async streamIntroduction(): Promise<any> {
// 3. 创建消息
const messages = [new HumanMessage('你好,请介绍一下自己')];
// 4. 调用 stream 方法
// stream 返回的是一个 AsyncIterable<AIMessageChunk>
const stream = await this.llm.stream(messages);
return stream;
}
}
agents.controller.ts
import { Controller, Sse } from '@nestjs/common';
import { AgentsService } from './agents.service';
import { from, map } from 'rxjs';
@Controller('agents')
export class AgentsController {
constructor(private readonly agentsService: AgentsService) {}
/**
* 流式对话接口
*/
@Sse('stream')
async streamResponse() {
// 1. 获取 LangChain 流式流
const stream = await this.agentsService.streamIntroduction();
// 2. 转换为 NestJS SSE 支持的格式
return from(stream).pipe(
map(
(chunk: any) =>
({
// SSE 固定格式:data: 内容
data: {
content: chunk.content, // AI 逐字输出内容
done: chunk.done, // 是否结束
},
}) as MessageEvent,
),
);
}
}
输出内容: