随着人工智能能力的不断提升,工程师们正在探索构建智能应用的新途径。在本文中,我们将介绍如何使用尖端的开源工具和框架来构建一个AI搜索代理的概念验证。我们将利用LangGraph来编排工作流,使用LangChain来集成大型语言模型,使用Ollama运行开源模型,如Llama3.1,并使用Next.js来构建全栈混合web应用。让我们开始吧!
搭建环境要开始,你需要一个 JavaScript/TypeScript 开发环境。这里提到的是我们将会用到的关键技术。下面是一些我们将用到的关键技术:
- Node.js 和 npm
- TypeScript
- Next.js
- Zod
- LangChain
- LangGraph
- Ollama(用于运行 Llama 3.1)
- LangSmith(用于可观察性)
确保你已经安装了 Node.js(LTS 版本 v20 或更高版本),然后创建一个 Next.js 项目。
npx create-next-app@latest poc-ai
cd poc-ai
npm i
运行以下命令来创建一个新的Next.js项目并安装依赖项.
安装一下必需的依赖项。
npm i @langchain/community @langchain/core @langchain/langgraph @langchain/ollama nanoid zod
// 该命令用于安装指定的npm包,包括@langchain社区、核心、langgraph、ollama、nanoid和zod。
项目结构:poc-ai/
├── src/
│ ├── ai/
│ │ ├── agents/
│ │ │ └── index.ts
│ │ ├── llm-model/
│ │ │ ├── index.ts
│ │ │ └── ollama.ts
│ │ └── tools/
│ │ ├── index.ts
│ │ └── searchTool.ts
│ ├── app/
│ │ └── api/
│ │ └── ai/
│ │ └── route.ts
│ └── ...
├── .env.local
├── .eslintrc.json
├── .gitignore
├── next-env.d.ts
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.js
├── README.md (读我(README))
├── tailwind.config.ts
└── tsconfig.json
实现AI代理程序:
我们来看看关键部分:
LLM模型配置(使用Ollama,与Llama 3.1):
此代码使用Ollama(一个特定的平台或工具)设置我们的语言模型为,并将其与自定义工具集成。
// src/ai/llm-model/ollama.ts
import { ChatOllama } from "@langchain/ollama";
const 模型名称 = "llama3.1";
export const llm = new ChatOllama({
model: 模型名称,
温度: 0,
});
// src/ai/llm-model/index.ts
import { 工具 } from "../tools";
import { llm } from "./ollama";
export const 模型 = llm.bindTools(工具);
LangGraph Agent(Langchain配置):
这建立了我们的LangGraph工作流,定义了智能体的决策方式和工具使用。
// src/ai/index.ts
import { MemorySaver, StateGraph } from "@langchain/langgraph";
import { callModel, shouldContinue, StateAnnotation } from "./agents";
import { toolNode } from "./tools";
import { HumanMessage } from "@langchain/core/messages";
// 定义一个新的图
export const workflow = new StateGraph(StateAnnotation)
.addNode("agent", callModel)
.addNode("tools", toolNode)
.addEdge("__start__", "agent")
.addConditionalEdges("agent", shouldContinue)
.addEdge("tools", "agent");
// 初始化内存以在图运行之间持久化状态
const checkpointer = new MemorySaver();
export const startRunnable = async (query: string, thread_id: string) => {
// 最终,我们编译它,
// 这将它编译成一个 LangChain 可执行对象,同时传递了内存。
// 注意,我们在编译图时(可选)传递了内存。
const app = workflow.compile({ checkpointer });
// 使用这个可执行
const finalState = await app.invoke(
{
messages: [new HumanMessage(query)],
},
{ configurable: { thread_id: thread_id } }
);
// 返回最终状态的最后一条消息的内容。
return finalState.messages[finalState.messages.length - 1].content;
};
// src/ai/agents/index.ts
import {
AIMessage,
BaseMessage,
SystemMessage,
} from "@langchain/core/messages";
import { Annotation } from "@langchain/langgraph";
import { model } from "../llm-model";
export const StateAnnotation = Annotation.Root({
messages: Annotation<BaseMessage[]>({
reducer: (x, y) => x.concat(y),
}),
});
// 定义一个函数来判断是否继续执行
// 我们可以通过 `StateAnnotation.State` 来提取状态类型
export function shouldContinue(state: typeof StateAnnotation.State) {
const messages = state.messages;
const lastMessage = messages[messages.length - 1] as AIMessage;
// 如果LLM调用了一个工具,则转向"tools"节点
if (lastMessage.tool_calls?.length) {
return "tools";
}
// 否则,我们停止(回复给用户)
return "__end__";
}
// 定义一个函数来调用模型
export async function callModel(state: typeof StateAnnotation.State) {
const messages = state.messages;
const response = await model.invoke([
new SystemMessage(`你是一名记者,正在传达新闻信息。
请根据以下请求总结句子。
请求:
1. 用第一句话总结文章,保持在5行或更少。
2. 用项目符号列出主要要点,并使用印地语。
3. 不要翻译任何技术术语。
4. 不要包含任何不必要的信息。
你有工具可以在互联网上搜索和获取数据,然后进行总结。
摘要:
`),
...messages,
]);
// 我们返回一个列表,因为这将被添加到现有的消息列表中
return { messages: [response] };
}
自定义搜索工具(使用Tavily的搜索工具):
我们使用自定义工具Tavily搜索API来获取现实世界数据。
// src/ai/tools/searchTool.ts
import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
// 搜索工具,用于从TavilySearchResults获取最多10条结果
export const searchTool = new TavilySearchResults({
maxResults: 10,
});
// src/ai/工具/index.ts 文件
import { ToolNode } from "@langchain/langgraph/prebuilt";
import { searchTool } from "./searchTool";
export const 工具列表 = [searchTool];
export const toolNode = new ToolNode(工具列表);
API 路由创建 —Next.js (应用路由):
这设置了我们的Next.js API路由,来处理收到的请求,并与我们的AI代理进行互动。
// src/app/api/ai/route.ts
import { startRunnable } from "@/ai";
import { nanoid } from "nanoid";
import { z } from "zod";
const InputBodySchema = z.object({
message: z.string().min(1),
chatId: z.string().optional(),
});
type InputBodyType = z.infer<typeof InputBodySchema>;
export async function POST(req: Request) {
const { message, chatId }: InputBodyType = await req.json();
const result = InputBodySchema.safeParse({ message, chatId });
if (!result.success) {
return Response.json({ data: null, error: result?.error }, { status: 500 });
}
const res = await startRunnable(message, chatId ?? nanoid());
return Response.json({ data: JSON.stringify(res) });
}
配置环境变量设置:在根目录下创建一个 .env.local
文件并在该文件中添加您的 API 密钥:
LANGCHAIN_TRACING_V2=true # 这是语言链跟踪的环境变量 (This is the environment variable for LangChain tracing)
LANGCHAIN_ENDPOINT="https://api.smith.langchain.com"
LANGCHAIN_API_KEY="your_langchain_api_key" # your_langchain_api_key (你的LangChain API密钥)
LANGCHAIN_PROJECT="your_project_name"
TAVILY_API_KEY="our_tavily_api_key"
LANGCHAIN_CALLBACKS_BACKGROUND=true # 背景回调开关 (background callback toggle)
利用LangSmith提升可观测性
LangSmith 提供了强大的追踪和调试能力,以帮助我们追踪和调试 LangChain 应用程序。从这些截图中,我们可以看到 LangSmith 如何可视化我们代理的决策流程、工具使用情况及其整体性能。
这里是一个查看 Langsmith POC 的链接。
使用 LangSmith 的关键优势:- 详细追踪代理的工作流程中的每一步
- 性能数据和延迟分析
- 轻松调试复杂的人工智能流水线
启动应用
使用英文“Ollama”和“Llama”,启动你的 Ollama 服务器,并使用 Llama 3.1 模型
运行一下 llama3.1
-
运行你的 Next.js 开发服务器:
npm run dev
: -
向
http://localhost:3000/api/ai
发送一个 POST 请求到,其中请求体包含一个包含message
字段的 JSON 数据。这里我用的是VS Code中的REST客户端。
有人问:关于西孟加拉的抗议活动,发生了什么事?
回复: {
"data": "\"本文是一句话总结:\n\n在印度西孟加拉邦,一名在公立医院实习的医生遭到强奸并遇害后,数千名抗议者堵塞了铁路轨道,使巴士停止运行,并呼喊口号。\n\n主要要点摘要(印地语):\n\n1. 印度西孟加拉邦公立医院的一名住院医生遭到强奸和杀害。\n2. 数千名抗议者走上街头。\n3. 抗议者堵塞了铁路轨道并使巴士停止运行。\n4. 人们呼喊口号,要求正义。\n5. 这一事件引发了对当地法律和秩序状况的质疑。\""
}
结语
我们尝试使用LangGraph、LangChain和开源LLM来构建AI驱动的搜索代理。我们看到了这些工具可以如何结合来创建强大且灵活的AI应用。通过利用LangSmith的可观测性,我们可以轻松地调试和优化AI工作流程。
概念验证展示了这些技术在创建智能应用和情境理解方面的潜力。在继续探索并使用这些工具时,请记得要考虑到人工智能系统的伦理问题和潜在的偏见。
喜欢这些内容吗?
如果你想支持我,可以请我喝杯咖啡吧!你的支持让我能继续创作更多有用的内容。
在这里请我喝杯咖啡。☕💻
如果你对这个项目感兴趣,或者想讨论人工智能工程的话题,可以在LinkedIn: Manoj Mukherjee上与我联系。
我一直都在寻找机会扩展我的AI职业生涯。如果您有兴趣合作或讨论潜在的机会,请随时联系我。我愿意分享更多关于这个项目的信息,并探讨我们如何一起突破AI技术的界限。
祝大家编码愉快,期待能与各位AI爱好者和专业人士互动!
照片由Hanny Naibaho在Unsplash发布。
共同学习,写下你的评论
评论加载中...
作者其他优质文章