news 2026/9/13 7:37:51

Refine useDataGrid Hook 完全指南:为 MUI X DataGrid 集成分页、排序、筛选与行内编辑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Refine useDataGrid Hook 完全指南:为 MUI X DataGrid 集成分页、排序、筛选与行内编辑

Refine useDataGrid Hook 完全指南:为 MUI X DataGrid 集成分页、排序、筛选与行内编辑

【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine

导读

useDataGrid是 Refine v5 中面向 Material UI 生态的核心 Hook,它把 Refine 的useList数据获取能力与 MUI X<DataGrid>组件无缝桥接,让你无需手写状态同步即可获得开箱即用的服务端分页、排序、筛选与行内编辑能力。读完本文,你将掌握useDataGrid的全部配置项、返回值与边界场景处理方式,能够直接在 Refine 项目中搭建功能完整的 Material UI 数据表格页面。

概览:useDataGrid 是什么

通过useDataGrid,你可以直接拿到与 MUI X<DataGrid>组件兼容的 props,排序(sorting)、筛选(filtering)和分页(pagination)等核心功能全部开箱即用。底层数据获取基于 Refine 的useListHook,因此数据请求、缓存与失效逻辑都复用了 Refine 的数据层能力。

以下几点是使用前必须了解的特性:

  • 兼容 MUI X 社区版的<DataGrid>与商业版DataGridPro
  • 该 Hook 从@refinedev/coreuseTable扩展而来,因此useTable的全部特性在useDataGrid中同样可用;
  • 默认从当前路由推断resource,无需显式指定资源名。

从源码实现看,useDataGrid的核心逻辑位于 packages/mui/src/hooks/useDataGrid/index.ts,它内部调用useTableCore(来自@refinedev/coreuseTable),并将 Refine 的CrudSorting/CrudFilters状态与 MUI X 的GridSortModel/GridFilterModel相互转换,最终拼装成dataGridProps返回。转换逻辑集中在 packages/mui/src/definitions/dataGrid/index.ts,下文会深入讲解。

基础用法

在最基本的用法中,useDataGrid会原样返回接口的数据,默认从 URL 读取resource

import { List, useDataGrid } from "@refinedev/mui"; import { DataGrid, type GridColDef } from "@mui/x-data-grid"; const columns: GridColDef[] = [ { field: "id", headerName: "ID", type: "number" }, { field: "title", headerName: "Title" }, { field: "status", headerName: "Status" }, ]; export const PostsList: React.FC = () => { const { dataGridProps } = useDataGrid<IPost>(); return ( <List> <DataGrid {...dataGridProps} columns={columns} /> </List> ); };

只需把dataGridProps展开到<DataGrid>上,分页、排序、筛选即可直接工作。仓库中的完整可运行示例位于 examples/table-material-ui-use-data-grid/src/pages/posts/list.tsx,其中演示了editablesyncWithLocation、初始筛选与初始排序的组合使用。

分页(Pagination)

useDataGrid通过设置与<DataGrid>兼容的paginationModepaginationModelonPaginationModelChange三个 props 来处理分页。启用syncWithLocation后,分页状态还会同步到 URL 查询参数中。

如果你希望在客户端完成分页,可以给useDataGrid传入pagination.mode并设为"client"。默认情况下dataGridProps已经包含分页所需的三件套,你可以像下面这样将它们显式拆分后传给<DataGrid>

export const PostsList: React.FC = () => { const { dataGridProps } = useDataGrid(); const { // highlight-start paginationMode, paginationModel, onPaginationModelChange, // highlight-end ...restDataGridProps } = dataGridProps; return ( <List> <DataGrid columns={columns} {...restDataGridProps} // highlight-start paginationMode={paginationMode} paginationModel={paginationModel} onPaginationModelChange={onPaginationModelChange} // highlight-end /> </List> ); };

从源码可以看到 packages/mui/src/hooks/useDataGrid/index.ts 中dataGridPaginationValues的实现:MUI X 的page0开始,而 Refine 的currentPage1开始,因此 Hook 在拼接paginationModel时做了page: currentPage - 1的换算;当分页模式为"off"时,则返回paginationMode: "client"并省略分页模型。对应的测试用例在 packages/mui/src/hooks/useDataGrid/index.spec.ts 中验证了client/server模式下的 props 输出,以及off模式下不设置paginationModel的行为。

排序(Sorting)

排序由 Hook 自动处理:它会设置sortingModesortModelonSortModelChange三个与<DataGrid>兼容的 props,并同样支持通过syncWithLocation与 URL 同步。

export const PostsList: React.FC = () => { const { dataGridProps } = useDataGrid(); // highlight-start const { sortingMode, sortModel, onSortModelChange, ...restDataGridProps } = dataGridProps; // highlight-end return ( <List> <DataGrid columns={columns} {...restDataGridProps} // highlight-start sortingMode={sortingMode} sortModel={sortModel} onSortModelChange={onSortModelChange} // highlight-end /> </List> ); };

在 DataGrid 外部控制排序

useDataGrid返回的setSorters函数可以接收CrudSorting类型的排序数组,因此你可以在<DataGrid>之外(例如工具栏按钮)触发排序:

import { useDataGrid, List } from "@refinedev/mui"; import { Button, ButtonGroup } from "@mui/material"; import { DataGrid, GridColDef } from "@mui/x-data-grid"; const columns: GridColDef[] = [ { field: "id", headerName: "ID", type: "number" }, { field: "title", headerName: "Title" }, { field: "status", headerName: "Status" }, ]; export const PostsList: React.FC = () => { const { dataGridProps, setSorters } = useDataGrid(); const handleSorting = (order: "asc" | "desc") => { setSorters([{ field: "title", order }]); }; return ( <List> <ButtonGroup variant="outlined"> <Button onClick={() => handleSorting("asc")}>Asc</Button> <Button onClick={() => handleSorting("desc")}>Desc</Button> </ButtonGroup> <DataGrid {...dataGridProps} columns={columns} /> </List> ); };

多列排序的两种路径

MUI X 社区版一次只按一个条件对行排序;若要使用界面上的多列排序,需要升级到 Pro 计划。但多列排序可以在服务端完成——只要不显式传入sortModel

return <DataGrid {...dataGridProps} sortModel={undefined} />;

不传sortModel时,服务端支持同时按多个条件排序,代价是<DataGrid>的表头无法显示当前哪些字段处于排序状态。

从源码看,handleSortModelChange(packages/mui/src/hooks/useDataGrid/index.ts)调用transformSortModelToCrudSorting把 MUI 的GridSortModel转成 Refine 的CrudSorting,再交给setSorters;反向的transformCrudSortingToSortModel用于把 Refine 排序状态渲染回 MUI 的sortModel。两个转换函数都位于 packages/mui/src/definitions/dataGrid/index.ts,格式即{ field, sort }{ field, order }之间的映射。

筛选(Filtering)

筛选同样由 Hook 自动处理:设置filterModefilterModelonFilterModelChange三个 props,并支持通过syncWithLocation与 URL 同步。

export const PostsList: React.FC = () => { const { dataGridProps } = useDataGrid(); // highlight-start const { filterMode, filterModel, onFilterModelChange, ...restDataGridProps } = dataGridProps; // highlight-end return ( <List> <DataGrid columns={columns} {...restDataGridProps} // highlight-start filterMode={filterMode} filterModel={filterModel} onFilterModelChange={onFilterModelChange} // highlight-end /> </List> ); };

在 DataGrid 外部控制筛选

类似排序,你可以用返回的setFilters在组件外部设置筛选条件,例如用一个复选框控制 "draft" 状态:

import { useDataGrid, List } from "@refinedev/mui"; import { FormControlLabel, Checkbox } from "@mui/material"; import { DataGrid, GridColDef } from "@mui/x-data-grid"; const columns: GridColDef[] = [ { field: "id", headerName: "ID", type: "number" }, { field: "title", headerName: "Title" }, { field: "status", headerName: "Status" }, ]; export const PostsList: React.FC = () => { const { dataGridProps, setFilters } = useDataGrid(); const handleFilter = ( e: React.ChangeEvent<HTMLInputElement>, checked: boolean, ) => { setFilters([ { field: "status", value: checked ? "draft" : undefined, operator: "eq", }, ]); }; return ( <List> <FormControlLabel label="Filter by Draft Status" control={<Checkbox onChange={handleFilter} />} /> <DataGrid {...dataGridProps} columns={columns} /> </List> ); };

多条件筛选的两种路径

与排序同理:MUI X 社区版界面一次只支持一个筛选条件,多条件界面筛选需要 Pro 计划;但服务端多条件筛选无需指定filterModel即可工作:

return <DataGrid {...dataGridProps} filterModel={undefined} />;

不传filterModel时支持同时筛选多个字段,但无法在<DataGrid>表头展示当前生效的筛选条件。

读取当前筛选值:getDefaultFilter

Refine 提供了getDefaultFilter函数(实现在packages/core/src/definitions/table/index.ts中),可以用来读取某个字段当前的筛选值:

import { getDefaultFilter } from "@refinedev/core"; import { useDataGrid } from "@refinedev/mui"; const MyComponent = () => { const { filters } = useDataGrid({ filters: { initial: [ { field: "name", operator: "contains", value: "John Doe", }, ], }, }); const nameFilterValue = getDefaultFilter("name", filters, "contains"); console.log(nameFilterValue); // "John Doe" return { /** ... */ }; };

服务端筛选的防抖处理

值得注意的一个实现细节:源码中定义了DEFAULT_FILTER_DEBOUNCE_MS = 300(packages/mui/src/hooks/useDataGrid/index.ts)。服务端筛选模式下,handleFilterModelChange会先更新本地筛选状态让输入即时响应,再通过 300ms 的防抖延迟发起服务端请求(同文件第 262-274 行),避免每次击键都触发网络请求;同时把filterDebounceMs设为0以禁用 MUI X 自带的防抖,防止输入被重置。

MUI 运算符与 Refine 运算符的映射

在 packages/mui/src/definitions/dataGrid/index.ts 中,Refine 实现了 MUI 运算符(equalscontainsisAnyOfafterbefore等)与 RefineCrudOperatorseqcontainsingtlt等)之间的双向转换,并针对列的typenumbersingleSelectstringdate/dateTime等)选择最合适的运算符表达。这意味着你在<DataGrid>界面上选择的筛选条件会被精确翻译成 data provider 能理解的CrudFilters结构。

实时更新(Realtime Updates)

useDataGrid支持 Refine 的实时(Live)能力,但需要配置LiveProvider才能生效。Hook 挂载时,会以channelresource等参数调用liveProvidersubscribe方法订阅实时事件,适合需要展示实时变化数据的场景。

与实时相关的配置项包括:

  • liveMode:收到相关实时事件后,决定自动更新数据("auto")还是手动处理("manual");
  • onLiveEvent:订阅到新事件时执行的回调;
  • liveParams:传给liveProvider.subscribe方法的额外参数。

行内编辑(Editing)

useDataGrid扩展了 MUI<DataGrid>的编辑能力。要开启列编辑,在列定义上设置editable: true

const columns = React.useMemo<GridColDef<IPost>[]>( () => [ { field: "title", headerName: "Title", minWidth: 400, flex: 1, editable: true, }, ], [], );

编辑背后的 useUpdate 集成

Refine v5 中,useDataGrid借助useUpdate直接与更新操作集成,省去了手动管理表单状态转换的复杂度,性能更好、交互模型更简洁。Hook 通过formProps暴露processRowUpdateformLoading

const { dataGridProps, formProps: { processRowUpdate, formLoading }, } = useDataGrid<IPost>();

默认情况下,单元格编辑开始并完成后,processRowUpdate会被触发,内部调用useUpdatemutate函数提交变更。核心流程如下(源码位于 packages/mui/src/hooks/useDataGrid/index.ts):

const processRowUpdate = async (newRow: TData, oldRow: TData) => { try { await new Promise((resolve, reject) => { mutate( { resource: resourceFromProp as string, id: newRow.id as string, values: newRow, }, { onError: (error) => { reject(error); }, onSuccess: (data) => { resolve(data); }, }, ); }); return newRow; } catch (error) { return oldRow; } };

几个值得留意的细节:

  • 只有editable: trueprocessRowUpdate才会真正执行更新,否则直接resolve(oldRow)
  • 如果identifier无法解析(例如没有配置 resource),会 reject 一个Resource is not defined错误;
  • updateMutationOptions可以透传meta等选项给mutate,测试用例 packages/mui/src/hooks/useDataGrid/index.spec.ts 验证了meta会被正确传递到 data provider 的update方法。

配置项详解(Properties)

下面逐一说明useDataGrid的核心配置项、默认值与使用场景。完整类型定义可见 packages/mui/src/hooks/useDataGrid/index.ts 中的UseDataGridProps

resource

resource默认从当前路由推断;存在多个同名资源时,可以用identifier作为主匹配键(data provider 方法仍使用<Refine/>组件中定义的资源name)。

useDataGrid({ resource: "categories", });

dataProviderName

当项目配置了多个dataProvider时,用dataProviderName指定某个资源使用哪一个:

useDataGrid({ dataProviderName: "second-data-provider", });

pagination.currentPage

设置初始页码,默认值为1

useDataGrid({ pagination: { currentPage: 2, }, });

pagination.pageSize

设置初始每页条数,默认值为25

useDataGrid({ pagination: { pageSize: 10, }, });

pagination.mode

取值"off""server""client",默认"server"

  • "off":禁用分页,获取全部记录;
  • "client":客户端分页,先获取全部记录再在客户端分页;
  • "server":服务端分页,按currentPagepageSize请求数据。
useDataGrid({ pagination: { mode: "client", }, });

sorters.initial

设置排序的初始值。initial不是永久的,用户改变排序后会被清除;如需永久生效,使用sorters.permanent

useDataGrid({ sorters: { initial: [{ field: "name", order: "asc" }], }, });

sorters.permanent

设置永久的、不可变更的排序值。用户改变排序时不会被清除;如需临时值,使用sorters.initial

useDataGrid({ sorters: { permanent: [{ field: "name", order: "asc" }], }, });

sorters.mode

取值"off""server",默认"server"

  • "off":排序值不发送到服务端,可在客户端自行排序;
  • "server":服务端排序,按sorters值请求数据。
useDataGrid({ sorters: { mode: "server", }, });

filters.initial

设置筛选的初始值。同样不是永久的,用户修改筛选后会被清除;如需永久生效,使用filters.permanent

useDataGrid({ filters: { initial: [{ field: "name", operator: "contains", value: "Foo" }], }, });

filters.permanent

设置永久的、不可变更的筛选值:

useDataGrid({ filters: { permanent: [{ field: "name", operator: "contains", value: "Foo" }], }, });

filters.defaultBehavior

筛选行为可以是"merge""replace",默认"merge"

  • "merge":新筛选与已有筛选合并——同字段的新筛选替换旧筛选,不同字段的新筛选追加到已有筛选;
  • "replace":用新筛选整体替换已有筛选。

该默认值也可以通过setFilters的第二个参数按次覆盖。注意一个实现细节:useDataGrid在把filters透传给底层useTableCore时,会强制将defaultBehavior固定为"replace"(见 packages/mui/src/hooks/useDataGrid/index.ts),以保证与 MUI DataGrid 的filterModel行为一致;而setFilters的第二个参数仍可传入"merge""replace"按次覆盖。

useDataGrid({ filters: { defaultBehavior: "replace", }, });

filters.mode

取值"off""server",默认"server"

  • "off":筛选值不发送到服务端,可在客户端自行筛选;
  • "server":服务端筛选,按filters值请求数据。
useDataGrid({ filters: { mode: "off", }, });

syncWithLocation 与 URL 状态同步

启用syncWithLocation后,useDataGrid的状态(排序、筛选、分页)会自动编码进 URL 查询参数;当 URL 变化时,Hook 状态也会自动跟随更新。这使得表格状态可以在不同路由/页面之间共享,用户还可以通过书签或分享链接直达某个特定表格视图。默认值为false

useDataGrid({ syncWithLocation: true, });

(也可以在<Refine/>组件上全局开启该功能。)

queryOptions

useDataGrid底层通过useList获取数据,因此可以直接传入 TanStack Query 的queryOptions

useDataGrid({ queryOptions: { retry: 3, }, });

meta

meta用于向 data provider 方法传递额外信息,典型用途包括:针对特定用例定制 data provider 方法、用纯 JS 对象生成 GraphQL 查询。例如向getList传递自定义请求头:

useDataGrid({ meta: { headers: { "x-meta-data": "true" }, }, }); const myDataProvider = { //... getList: async ({ resource, pagination, sorters, filters, // highlight-next-line meta, }) => { // highlight-next-line const headers = meta?.headers ?? {}; const url = `${apiUrl}/${resource}`; //... //... // highlight-next-line const { data, headers } = await httpClient.get(`${url}`, { headers }); return { data, }; }, //... };

successNotification 与 errorNotification

两者都需要NotificationProvider支持。数据获取成功或失败时,Hook 会调用open函数展示通知,你可以通过这两个 prop 自定义通知内容:

useDataGrid({ successNotification: (data, values, resource) => { return { message: `${data.title} Successfully fetched.`, description: "Success with no errors", type: "success", }; }, }); useDataGrid({ errorNotification: (data, values, resource) => { return { message: `Something went wrong when getting ${data.id}`, description: "Error", type: "error", }; }, });

overtimeOptions

当请求耗时过长时,可用overtimeOptions展示加载提示。interval是毫秒级的时间间隔,onInterval是每个间隔触发的回调;Hook 返回的overtime.elapsedTime是已耗时的毫秒数,请求完成后变为undefined

const { overtime } = useDataGrid({ //... overtimeOptions: { interval: 1000, onInterval(elapsedInterval) { console.log(elapsedInterval); }, }, }); console.log(overtime.elapsedTime); // undefined, 1000, 2000, 3000 4000, ... // 使用示例: { elapsedTime >= 4000 && <div>this takes a bit longer than expected</div>; }

返回值详解(Return Values)

dataGridProps

<DataGrid>组件所需的 props,包含以下字段:

  • sortingMode:是否服务端排序,默认"server"
  • sortModel:当前与<DataGrid>兼容的GridSortModel
  • onSortModelChange:用户排序某列时以新排序模型调用。该函数会自动把GridSortModel转换为CrudSorting并调用setSorters。需要覆盖时可以这样包装:
<DataGrid {...dataGridProps} columns={columns} onSortModelChange={(model, details) => { dataGridProps.onSortModelChange(model, details); // do something else }} />
  • filterMode:是否服务端筛选,默认"server"
  • filterModel:当前与<DataGrid>兼容的GridFilterModel
  • onFilterModelChange:用户筛选某列时以新筛选模型调用。该函数会自动把GridFilterModel转换为CrudFilters并调用setFilters。覆盖方式同理:
<DataGrid {...dataGridProps} columns={columns} onFilterModelChange={(model) => { dataGridProps.onFilterModelChange(model); // do something else }} />
  • onStateChange:用户排序或筛选某列时以新状态调用,useDataGrid内部用它跟踪列类型(columnsTypes),以便把 MUI 运算符按列类型正确转换回 Refine 运算符。覆盖方式:
<DataGrid {...dataGridProps} columns={columns} onStateChange={(state) => { dataGridProps.onStateChange(state); // do something else }} />
  • rows:表格展示的数据,由useList获取;
  • rowCount:数据总数,由useList获取;
  • loading:是否正在获取数据;
  • pagination:分页配置值(pageSizecurrentPagesetCurrentPage等)。

tableQuery

useList的完整返回结果,即 TanStack Query 的useQuery结果。

sorters / setSorters

  • sorters:当前排序状态(CrudSorting);
  • setSorters:设置排序状态的函数,签名(sorters: CrudSorting) => void

filters / setFilters

  • filters:当前筛选状态(CrudFilters);
  • setFilters:设置筛选状态的函数,签名:
((filters: CrudFilters, behavior?: SetFilterBehavior) => void) & ((setter: (prevFilters: CrudFilters) => CrudFilters) => void);

分页相关状态

  • currentPage:当前页码(分页禁用时为undefined);
  • setCurrentPageReact.Dispatch<React.SetStateAction<number>> | undefined
  • pageSize:当前每页条数(分页禁用时为undefined);
  • setPageSize:同上类型;
  • pageCount:总页数(分页禁用时为undefined)。

createLinkForSyncWithLocation

签名(params: SyncWithLocationParams) => string,用于为syncWithLocation生成可访问的链接。

overtime

{ elapsedTime?: number },已耗时毫秒数,请求完成时变为undefined

const { overtime } = useDataGrid(); console.log(overtime.elapsedTime); // undefined, 1000, 2000, 3000 4000, ...

search

search会把接收到的参数发送给onSearch函数:(value: TSearchVariables) => Promise<void>。你传入的onSearch返回CrudFilters,随后这些筛选会被应用并重置到第一页。仓库测试用例 packages/mui/src/hooks/useDataGrid/index.spec.ts 演示了通过onSearch+search实现受控搜索的完整流程。

常见问题(FAQ)

如何处理关联数据(relational data)?

可以使用useSelect获取关联数据,再结合valueOptionsrenderCell<DataGrid>中展示。参考 examples/table-material-ui-use-data-grid/src/pages/posts/list.tsx 中的category.id列:它通过useSelect拉取categories资源,把选项传给valueOptions,并用renderCellcategory.id渲染为分类名称。

如何实现客户端筛选?

设置filters.mode: "off"即可禁用服务端筛选,此时useDataGrid与 MUI<DataGrid>自身的筛选功能完全兼容:

useDataGrid({ filters: { mode: "off", }, });

如何实现客户端排序?

设置sorters.mode: "off"即可禁用服务端排序,useDataGrid与 MUI<DataGrid>的排序功能完全兼容:

useDataGrid({ sorters: { mode: "off", }, });

类型参数(Type Parameters)

参数说明类型默认值
TQueryFnDataquery 函数返回的结果数据类型,继承BaseRecordBaseRecordBaseRecord
TError继承HttpError的自定义错误类型HttpErrorHttpError
TSearchVariables搜索参数的类型{}
TDataselect函数返回的结果数据类型,继承BaseRecord;未指定时默认取TQueryFnData的值BaseRecordTQueryFnData

典型用法:

const { dataGridProps } = useDataGrid<IPost, HttpError, IPostSearch>();

完整示例

仓库中 examples/table-material-ui-use-data-grid 提供了开箱即用的完整示例项目:App.tsx中通过@refinedev/simple-rest指向https://api.fake-rest.refine.dev,注册posts资源并挂载 Material UI 主题;list.tsx中把editablesyncWithLocation、初始分页/筛选/排序组合起来,展示了useDataGrid的典型实战形态。

export const PostList: React.FC = () => { const { dataGridProps } = useDataGrid<IPost>({ editable: true, syncWithLocation: true, pagination: { currentPage: 1, pageSize: 10, }, filters: { initial: [ { field: "status", operator: "eq", value: "draft", }, ], }, sorters: { initial: [ { field: "title", order: "asc", }, ], }, }); return ( <List> <DataGrid {...dataGridProps} columns={columns} pageSizeOptions={[10, 20, 30, 50, 100]} /> </List> ); };

总结

useDataGrid是 Refine v5 中打通"数据层"与"界面层"的桥梁:它把useList的取数能力、useTable的表格状态管理,以及 MUI X<DataGrid>的分页/排序/筛选/编辑交互封装为一套开箱即用的 props。掌握其配置项语义(尤其是pagination.modesorters.modefilters.modesyncWithLocation),并理解 packages/mui/src/definitions/dataGrid/index.ts 中的模型转换机制,你就能在项目中快速构建专业级的 Material UI 数据表格,同时保持 Refine 数据层的灵活性与可扩展性。

【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 7:37:49

Java AI转型实战:用Spring Boot打造完整智能助手应用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 7:37:25

基于LangChain与FastAPI构建AI Agent的技术实践

1. 项目概述&#xff1a;AI Agent的核心价值与应用场景AI Agent&#xff08;人工智能代理&#xff09;正在成为连接大语言模型&#xff08;LLM&#xff09;与实际业务场景的关键桥梁。不同于简单的聊天机器人&#xff0c;一个完整的AI Agent具备自主决策、工具调用、记忆存储等…

作者头像 李华
网站建设 2026/9/13 7:29:32

软件测试中的勒索软件防御与实战策略

1. 勒索软件威胁与软件测试从业者的特殊挑战 2023年全球勒索软件攻击同比增长了37%&#xff0c;平均赎金要求达到惊人的54万美元。作为软件测试从业者&#xff0c;我们既是防御体系的关键构建者&#xff0c;又常常成为攻击者的首要目标——测试环境中的漏洞和弱配置往往成为入侵…

作者头像 李华