Agent学习

搭建模型

选用DeepSeek-V4-Flash

  • 总参数:284B(超大)实际激活仅 13B(推理成本低、速度快)
  • 上下文窗口:100 万 token(超长对话、超长文档直接喂,LangGraph 多轮记忆无压力)

选这个主要是应该对中文友好一些

Agent例子

简单例子

LangGraph LangGraph - LangChain 教程

为什么要用:普通 LLM 会乱跑、乱回答、乱调用工具。LangGraph 让 AI 严格按流程图走。(而且也没有钱和时间训练,甚至微调大模型。。。)

代码如下:

javascript 复制代码
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

// ======================
// 你的 Azure DeepSeek
// ======================
const llm = new ChatOpenAI({
  model: "DeepSeek-V4-Flash",
  apiKey: "your key",
  configuration: {
    baseURL: "https://mengh-mejox4dy-swedencentral.services.ai.azure.com/openai/v1/",
  },
  temperature: 0.1,
});

// ======================
// 定义工具(超级简单!)
// ======================
const calculator = tool(
  async ({ a, b, op }) => {
    switch (op) {
      case "+": return a + b;
      case "-": return a - b;
      case "*": return a * b;
      case "/": return b !== 0 ? a / b : "除数不能为 0";
      default: return "不支持的操作";
    }
  },
  {
    name: "calculator",
    description: "做加减乘除计算",
    schema: z.object({
      a: z.number(),
      b: z.number(),
      op: z.enum(["+", "-", "*", "/"]),
    }),
  }
);

// ======================
// ✅ 一行创建 Agent(官网标准!)
// ======================
const agent = createReactAgent({
  llm,
  tools: [calculator],
});

// ======================
// 运行
// ======================
const result = await agent.invoke({
  messages: [
    {
      role: "user",
      content: "帮我算 123 * 456",
    },
  ],
});

console.log(result.messages.at(-1).content);

返回结果

多轮对话

核心就是把message都带入每次对话

  • 每次调用都会把历史传给 LLM
  • 自动记忆、自动上下文
  • 工具调用 + 记忆 同时支持
javascript 复制代码
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

// 你的 Azure DeepSeek
const llm = new ChatOpenAI({
  model: "DeepSeek-V4-Flash",
  apiKey: "key",
  configuration: {
    baseURL: "https://mengh-mejox4dy-swedencentral.services.ai.azure.com/openai/v1/",
  },
  temperature: 0.1,
});

// 计算器工具
const calculator = tool(
  async ({ a, b, op }) => {
    switch (op) {
      case "+": return a + b;
      case "-": return a - b;
      case "*": return a * b;
      case "/": return b !== 0 ? a / b : "不能除以0";
    }
  },
  {
    name: "calculator",
    description: "做加减乘除",
    schema: z.object({
      a: z.number(),
      b: z.number(),
      op: z.enum(["+", "-", "*", "/"]),
    }),
  }
);

// 一行创建 Agent
const agent = createReactAgent({
  llm,
  tools: [calculator],
});

// ==============================================
// 👇 这就是 多轮对话(会记住历史消息)
// ==============================================
const messages = []; // 消息历史(核心!)

async function chat(input) {
  messages.push({ role: "user", content: input });

  const result = await agent.invoke({
    messages: messages, // 把历史一起传进去
  });

  const reply = result.messages.at(-1).content;
  messages.push({ role: "assistant", content: reply });

  console.log("Agent:", reply);
}

// 测试多轮
await chat("我想算 10 + 20");
await chat("再乘以 2");
await chat("再减去 15");

做成循环

javascript 复制代码
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import readline from 'readline';

// ======================
// 你的 Azure DeepSeek
// ======================
const llm = new ChatOpenAI({
  model: "DeepSeek-V4-Flash",
  apiKey: "你的API_KEY",
  configuration: {
    baseURL: "https://mengh-mejox4dy-swedencentral.services.ai.azure.com/openai/v1/",
    defaultHeaders: {
      "api-key": "你的API_KEY",
    },
  },
  temperature: 0.1,
});

// ======================
// 工具(计算器)
// ======================
const calculator = tool(
  async ({ a, b, op }) => {
    switch (op) {
      case "+": return a + b;
      case "-": return a - b;
      case "*": return a * b;
      case "/": return b !== 0 ? a / b : "不能除以0";
    }
  },
  {
    name: "calculator",
    description: "做加减乘除计算",
    schema: z.object({
      a: z.number(),
      b: z.number(),
      op: z.enum(["+", "-", "*", "/"]),
    }),
  }
);

// ======================
// ✅ 官方 React Agent(最简)
// ======================
const agent = createReactAgent({
  llm,
  tools: [calculator],
});

// ======================
// 🚀 无限循环聊天(像 ChatGPT)
// ======================
const messages = []; // 永久保存上下文

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

console.log("✅ 无限聊天已启动!输入 exit 退出\n");

async function chatLoop() {
  rl.question("你:", async (input) => {
    if (input.toLowerCase() === "exit") {
      console.log("结束聊天");
      rl.close();
      return;
    }

    // 把用户输入加入历史
    messages.push({ role: "user", content: input });

    // 调用 Agent(自带记忆)
    const res = await agent.invoke({ messages });

    // 获取回答
    const reply = res.messages.at(-1).content;
    console.log("Agent:", reply);

    // 把回答也加入历史(实现多轮)
    messages.push({ role: "assistant", content: reply });

    // 继续循环
    chatLoop();
  });
}

// 启动
chatLoop();

文件读写+联网

javascript 复制代码
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import fs from "fs-extra";
import path from "path";
import { SerpAPI } from "@langchain/community/tools/serpapi";

// ========== Azure DeepSeek 鉴权配置(彻底修复ByteString报错) ==========
const llm = new ChatOpenAI({
  model: "DeepSeek-V4-Flash",
  apiKey: "你的纯净Azure API Key",
  configuration: {
    baseURL: "https://mengh-mejox4dy-swedencentral.services.ai.azure.com/openai/v1/",
    authToken: null,
    defaultHeaders: {
      "api-key": "你的纯净Azure API Key",
    },
  },
  temperature: 0.1,
});

// ========== 工具1:联网搜索 ==========
const searchTool = new SerpAPI("你的SerpAPI Key", {
  hl: "zh-cn",
});

// ========== 工具2:读取本地文件 ==========
const readFileTool = tool(
  async ({ filePath }) => {
    const fullPath = path.resolve(filePath);
    return await fs.readFile(fullPath, "utf8");
  },
  {
    name: "read_file",
    description: "读取本地文本文件内容,传入相对路径",
    schema: z.object({
      filePath: z.string().describe("文件路径,如 ./test.txt"),
    }),
  }
);

// ========== 工具3:写入本地文件 ==========
const writeFileTool = tool(
  async ({ filePath, content }) => {
    const fullPath = path.resolve(filePath);
    await fs.writeFile(fullPath, content, "utf8");
    return `✅ 已成功写入文件:${fullPath}`;
  },
  {
    name: "write_file",
    description: "将文本内容写入本地文件,覆盖原有内容",
    schema: z.object({
      filePath: z.string().describe("文件保存路径"),
      content: z.string().describe("要写入的内容"),
    }),
  }
);

// ========== 创建全能 Agent ==========
const agent = createReactAgent({
  llm,
  tools: [searchTool, readFileTool, writeFileTool],
});

// ========== 单次调用示例 ==========
(async () => {
  // 示例指令:联网查2025AI趋势 + 写入本地文件
  const result = await agent.invoke({
    messages: [
      { role: "user", content: "搜索2025年AI最新发展趋势,整理成要点,保存到 ./ai_trend.txt" }
    ],
  });

  console.log("Agent 输出:", result.messages.at(-1).content);
})();

ReAct 机制

ReAct = Reasoning(思考) + Acting(行动)

思考 → 判断要不要调用工具 → 调用工具 → 拿到结果 → 再思考 → 输出答案

javascript 复制代码
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

// Azure 配置(你的 DeepSeek)
const llm = new ChatOpenAI({
  model: "DeepSeek-V4-Flash",
  apiKey: "你的Azure密钥",
  configuration: {
    baseURL: "https://mengh-mejox4dy-swedencentral.services.ai.azure.com/openai/v1/"
  },
  temperature: 0.1,
});

// 工具:获取当前时间
const getTime = tool(async () => new Date().toLocaleString("zh-CN"), {
  name: "get_time",
  description: "获取当前系统时间",
  schema: z.object({}),
});

// 工具:简单加法
const add = tool(async ({ a, b }) => a + b, {
  name: "add",
  description: "两数相加",
  schema: z.object({ a: z.number(), b: z.number() }),
});

// 创建 ReAct Agent
const agent = createReactAgent({ llm, tools: [getTime, add] });

// 测试:触发完整 ReAct 循环
(async () => {
  const res = await agent.invoke({
    messages: [{ role: "user", content: "现在几点?10+20等于多少?" }],
  });

  console.log("最终回答:", res.messages.at(-1).content);
})();

Agent 自动循环,不需要你手动控制,这就是 ReAct 最强大的地方

回答错误的处理

ReAct Agent 出错一般就 4 类:

  1. 工具调用错:选错工具、参数传错(路径不对、搜索关键词不对)
  2. 幻觉:没查工具直接瞎编答案
  3. 推理链错:思考步骤跳步、逻辑错误
  4. 工具返回信息不全 / 过时:搜索不到、文件读不到

ReAct 里加 自我反思

人工反馈修正

实践 查询混凝土强度

写了一个函数,用于查询混凝土强度等级为用户输入的所有实例的总和

javascript 复制代码
import express from "express";
import cors from "cors";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import path from "path";
import { IModelHost, SnapshotDb } from "@itwin/core-backend";
import { fileURLToPath } from "url";

const app = express();
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// 提供静态文件
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
app.use(cors());
app.use(express.json());
const PORT = 5666;

await IModelHost.startup();

// ========== 1. 你的 Azure DeepSeek LLM 配置 ==========
const llm = new ChatOpenAI({
    model: "DeepSeek-V4-Flash",
    apiKey: "your key",
    configuration: {
        baseURL: "https://mengh-mejox4dy-swedencentral.services.ai.azure.com/openai/v1/",
    },
    temperature: 0.1,
});

// ========== 2. 工具集:本地 iModel 文件 ECSQL 查询 ==========
const queryIModelTool = tool(async ({ filePath, propertyDisplayLabel, value }) => {
    const fullPath = path.resolve(filePath);
    const iModel = SnapshotDb.openFile(fullPath);

    try {
        // 第一步:查询所有包含指定属性的 表名 + 真实字段名
        const getClassAndPropSql = `
      SELECT 
        c.Name AS ClassName, 
        p.Name AS PropName
      FROM meta.ECPropertyDef p
      JOIN meta.ECClassDef c ON p.Class.Id = c.EcInstanceId
      WHERE p.DisplayLabel = '${propertyDisplayLabel}'
        AND c.Schema.Id = 21
    `;

        const classPropList = [];
        const reader = iModel.createQueryReader(getClassAndPropSql);
        for await (const row of reader) {
            const data = row.toRow();
            classPropList.push(data);
        }

        if (classPropList.length === 0) {
            return `未找到属性 "${propertyDisplayLabel}" 相关数据`;
        }

        // 第二步:遍历所有表,查询指定值的数据
        const results = [];
        const idList = [];
        for (const item of classPropList) {
            const { ClassName, PropName } = item;
            const tableName = `RevitDynamic.${ClassName}`;

            const querySql = `
        SELECT EcInstanceId, ${PropName} 
        FROM ${tableName}
        WHERE ${PropName} = '${value}'
      `;

            const dataReader = iModel.createQueryReader(querySql);
            for await (const row of dataReader) {
                results.push(row.toRow());              
                idList.push(row.toRow().ECInstanceId);
            }
        }
        console.log(`查询完成,找到 ${results.length} 条数据`);       
        return idList.length > 0 ? idList.length : `未找到数据`;

    } finally {
        iModel.close();
    }
}, {
    name: "query_iModel",
    description: "查询本地 iModel 文件中指定属性的实例数据的总和",
    schema: z.object({
        filePath: z.string().describe("本地 iModel (.bim) 文件路径"),
        propertyDisplayLabel: z.string().describe("属性显示名称,如 '混凝土强度等级'"),
        value: z.string().describe("要查询的属性值,如 'C80'"),
    }),
});

// ========== 3. 实例化 Agent ==========
const agent = createReactAgent({
    llm,
    tools: [queryIModelTool],
});

// ========== 4. 静态文件服务 ==========
// app.use(express.static(path.join(process.cwd(), 'public')));
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// ========== 5. 生产接口:接收前端输入,调用Agent ==========
app.post("/api/agent/chat", async (req, res) => {
    try {
        const { question, filePath } = req.body;
        if (!question) return res.status(400).json({ error: "问题不能为空" });

        // 解析用户查询,提取属性和值
        const match = question.match(/查询(.+?)为(.+)的所有实例/i);
        if (!match) {
            return res.status(400).json({ error: "查询格式不正确,请使用:查询[属性]为[值]的所有实例" });
        }

        const propertyDisplayLabel = match[1].trim();
        const value = match[2].trim();
        console.log(`用户查询解析结果 - 属性: ${propertyDisplayLabel}, 值: ${value}`);

        // 调用LangGraph Agent
        const result = await agent.invoke({
            messages: [{
                role: "user",
                content: `
调用query_iModel工具,参数:
${filePath}
${propertyDisplayLabel}
${value}

强制规则:
1. 工具返回什么,你就**原封不动直接输出**
2. 禁止总结、禁止只说一句话
3. 不要加任何多余文字,只输出总数
`
//                 content: `
// 直接调用query_iModel工具。
// 参数已给:
// filePath=${filePath}
// propertyDisplayLabel=${propertyDisplayLabel}
// value=${value}
// 不许向用户询问参数,不许解释。
// 查询后只逐行输出ECInstanceId。
// `
            }],
        });

        // 返回Agent最终回答
        res.json({
            answer: result.messages.at(-1).content,
        });
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

// 启动服务
app.listen(PORT, () => {
    console.log(`✅ Agent服务已启动:http://localhost:${PORT}`);
});

最后的输出

总结

1 如果返回值很大,接口反应很慢,我这里本来是想返回所有的实例Id,结果json太多了

2 提示词写的很崩溃~这里再学习下吧

相关推荐
2601_957780842 小时前
Agent记忆系统架构设计与工程实践:从短期暂存到长期持久化
大数据·网络·人工智能·架构·agent
飞哥数智坊11 小时前
我为我的龙虾斩分身:OpenClaw 多智能体实操
人工智能·agent
七牛云行业应用14 小时前
Claude Code10小时限额翻倍后怎么用【2026最新】:/clear、/compact、.claudeignore完整配置
大语言模型·agent·上下文窗口·技术演进·gpt-5.5
Karl_wei17 小时前
AI Agent 对比和选型
openai·agent·ai编程
DigitalOcean17 小时前
既要 LLM 推理性能可预测,又要成本可控?专用推理了解一下
llm·agent
蝎子莱莱爱打怪17 小时前
无废话!源自官网的Codex 命令速查手册!
人工智能·后端·agent
momo0611719 小时前
图文+代码: 轻易搞懂Agent的底层架构-ReAct
openai·agent
行者-全栈开发1 天前
【DeepSeek 实战】打造全能编程助手:DeepSeek V4 Agent 开发与工具调用
agent·智能体·工具调用·functioncalling·自动化编程·多步推理·deepseek v4