|
1 |
| -import { AgentExecutor, createOpenAIToolsAgent } from 'langchain/agents' |
2 | 1 | import type { PagerDto } from '~/shared/dto/pager.dto'
|
3 | 2 |
|
4 | 3 | import { JsonOutputToolsParser } from '@langchain/core/output_parsers/openai_tools'
|
5 |
| -import { |
6 |
| - ChatPromptTemplate, |
7 |
| - MessagesPlaceholder, |
8 |
| - SystemMessagePromptTemplate, |
9 |
| -} from '@langchain/core/prompts' |
10 | 4 | import { DynamicStructuredTool } from '@langchain/core/tools'
|
| 5 | +import { GraphRecursionError } from '@langchain/langgraph' |
| 6 | +import { createReactAgent } from '@langchain/langgraph/prebuilt' |
11 | 7 | import { z } from '@mx-space/compiled/zod'
|
12 | 8 | import { Injectable, Logger } from '@nestjs/common'
|
13 | 9 | import { OnEvent } from '@nestjs/event-emitter'
|
@@ -152,45 +148,39 @@ export class AiDeepReadingService {
|
152 | 148 | }),
|
153 | 149 | ]
|
154 | 150 |
|
155 |
| - // 创建Agent提示模板 |
156 |
| - const prompt = ChatPromptTemplate.fromMessages([ |
157 |
| - SystemMessagePromptTemplate.fromTemplate( |
158 |
| - `你是一个专门进行文章深度阅读的AI助手,需要分析文章并提供详细的解读。 |
| 151 | + // 创建系统提示模板 |
| 152 | + const systemPrompt = `你是一个专门进行文章深度阅读的AI助手,需要分析文章并提供详细的解读。 |
159 | 153 | 分析过程:
|
160 | 154 | 1. 首先提取文章关键点,然后使用 save_key_points 保存到数据库
|
161 | 155 | 2. 然后进行批判性分析,包括文章的优点、缺点和改进建议,然后使用 save_critical_analysis 保存到数据库
|
162 | 156 | 3. 最后使用 deep_reading 生成完整的深度阅读内容
|
163 |
| -4. 返回完整结果,包括关键点、批判性分析和深度阅读内容 |
164 |
| -`, |
165 |
| - ), |
166 |
| - new MessagesPlaceholder('chat_history'), |
167 |
| - ['human', '文章标题: {article_title}\n文章内容: {article_content}'], |
168 |
| - new MessagesPlaceholder('agent_scratchpad'), |
169 |
| - ]) |
170 |
| - |
171 |
| - // 创建Agent |
172 |
| - const agent = await createOpenAIToolsAgent({ |
173 |
| - llm, |
174 |
| - tools, |
175 |
| - prompt, |
176 |
| - }) |
177 |
| - |
178 |
| - // 创建Agent执行器 |
179 |
| - const executor = new AgentExecutor({ |
180 |
| - agent, |
181 |
| - tools, |
182 |
| - verbose: false, |
183 |
| - }) |
| 157 | +4. 返回完整结果,包括关键点、批判性分析和深度阅读内容` |
184 | 158 |
|
185 | 159 | try {
|
186 |
| - // 执行Agent |
187 |
| - await executor.invoke({ |
188 |
| - article_title: article.document.title, |
189 |
| - article_content: article.document.text, |
190 |
| - chat_history: [], |
| 160 | + // 创建LangGraph React Agent |
| 161 | + const agent = createReactAgent({ |
| 162 | + llm, |
| 163 | + tools, |
191 | 164 | })
|
192 | 165 |
|
193 |
| - // 返回结果 |
| 166 | + await agent.invoke( |
| 167 | + { |
| 168 | + messages: [ |
| 169 | + { |
| 170 | + role: 'system', |
| 171 | + content: systemPrompt, |
| 172 | + }, |
| 173 | + { |
| 174 | + role: 'user', |
| 175 | + content: `文章标题: ${article.document.title}\n文章内容: ${article.document.text}`, |
| 176 | + }, |
| 177 | + ], |
| 178 | + }, |
| 179 | + { |
| 180 | + recursionLimit: 10, // 相当于以前的maxIterations |
| 181 | + }, |
| 182 | + ) |
| 183 | + |
194 | 184 | return {
|
195 | 185 | keyPoints: dataModel.keyPoints,
|
196 | 186 | criticalAnalysis: dataModel.criticalAnalysis,
|
@@ -270,6 +260,18 @@ export class AiDeepReadingService {
|
270 | 260 | }
|
271 | 261 | } catch (error) {
|
272 | 262 | console.error(error)
|
| 263 | + |
| 264 | + if (error instanceof GraphRecursionError) { |
| 265 | + this.logger.error( |
| 266 | + `LangGraph recursion limit reached for article ${articleId}: ${error.message}`, |
| 267 | + ) |
| 268 | + throw new BizException( |
| 269 | + ErrorCodeEnum.AIException, |
| 270 | + 'AI处理迭代次数超过限制', |
| 271 | + error.stack, |
| 272 | + ) |
| 273 | + } |
| 274 | + |
273 | 275 | this.logger.error(
|
274 | 276 | `OpenAI encountered an error processing article ${articleId}: ${error.message}`,
|
275 | 277 | )
|
|
0 commit comments