从 Tool Calling 到 State 并发控制:一个 Agent 如何安全地连续执行任务

前言

在前一个阶段中,主要学习了:

  • Agent 和 Workflow 的区别;

  • Agent、Java 和人工之间的职责边界;

  • Tool 的粒度;

  • Tool Schema;

  • Tool Result。

这一阶段继续向下深入,重点解决一个问题:

模型选择了一个 Tool 之后,系统到底是怎么执行的?Agent 又是如何连续调用多个 Tool,并保证中断后能够继续、并发时不会执行旧指令的?

本文总结 Agent 学习的内容主要包括:

  1. Tool Calling 的完整执行链路;

  2. 为什么 Tool Call 只是建议,不是命令;

  3. Agent Loop 如何连续调用多个 Tool;

  4. 如何防止 Agent 死循环;

  5. Agent State 应该保存什么;

  6. State 与聊天记录、Memory 的区别;

  7. 并发请求下如何防止旧状态覆盖新状态;

  8. 如何保证 State 和真实业务操作的一致性。


一、Tool Calling 不等于模型直接执行 Java 方法

假设系统中存在一个 Java 方法:

复制代码
public OrderInfo queryOrder(String orderId) {
    return orderService.queryOrder(orderId);
}

用户说:

帮我查询订单 A10086。

很多初学者可能会认为,大模型会直接进入 Java 程序并调用:

复制代码
queryOrder("A10086");

实际上,大模型本身不会执行 Java 方法。

完整链路通常是:

复制代码
用户输入
↓
系统把 Tool 名称、描述和参数 Schema 发送给模型
↓
模型生成 Tool Call
↓
Java 解析 Tool Call
↓
Java 校验 Tool、参数、权限和业务条件
↓
Java 真正执行方法
↓
把 Tool Result 返回给模型
↓
模型继续决策或生成最终回复

模型产生的内容类似:

复制代码
{
  "toolName": "queryOrder",
  "arguments": {
    "orderId": "A10086"
  }
}

这个 JSON 只是在表达:

模型认为下一步应该调用 queryOrder

真正执行方法的仍然是 Java。

因此,一个非常重要的结论是:

Tool Call 是模型提出的行动建议,不是必须执行的系统命令。


二、模型选择了 Tool,Java 仍然可以拒绝

假设用户明确说:

我的订单还没到,你先帮我查一下,不要取消。

模型却返回:

复制代码
{
  "toolName": "cancelOrder",
  "arguments": {
    "orderId": "A10086",
    "reason": "物流时间较长"
  }
}

这里模型发生了 Tool 选择错误。

但系统不能因为 Tool Call 的 JSON 格式正确,就直接执行取消订单。

正确链路应该是:

复制代码
模型提出 cancelOrder
↓
Java 执行前校验
↓
发现当前调用与用户明确意图冲突
↓
拒绝执行
↓
返回结构化拒绝结果
↓
模型重新选择 queryOrder 或 queryLogistics

例如返回:

复制代码
{
  "success": false,
  "errorCode": "USER_INTENT_CONFLICT",
  "retryable": false,
  "message": "用户明确要求不要取消订单",
  "recommendedAction": "QUERY_ORDER_OR_LOGISTICS"
}

这能够告诉模型:

  • 当前 Tool 没有执行;

  • 失败原因不是系统异常;

  • 不要使用相同参数重试;

  • 下一步应该查询订单或物流。

如果只返回:

复制代码
{
  "success": false,
  "message": "失败"
}

模型可能不知道为什么失败,然后再次调用 cancelOrder,最终形成循环。


三、Java 怎么知道模型选错了 Tool?

Java 本身不是大模型,它通常无法直接理解:

"先别真的退。"

这种自然语言背后的全部语义。

因此,不能让 Java 通过大量关键词判断用户意图,例如:

复制代码
if (userMessage.contains("别退")) {
    reject();
}

这种规则非常脆弱。

用户还可能说:

  • 暂时不要操作;

  • 我只是想问问;

  • 先查一下,别动订单;

  • 我还没有决定退款。

更合理的方式是,把模型理解出的关键意图转换成结构化 State:

复制代码
{
  "intent": "CHECK_REFUND_ELIGIBILITY",
  "operationMode": "READ_ONLY",
  "userConfirmedRefund": false
}

然后为写操作设置明确前置条件:

复制代码
applyRefund 必须满足:

1. operationMode = EXECUTE
2. userConfirmedRefund = true
3. 退款资格校验通过
4. 用户拥有订单权限
5. 金额合法
6. 不存在重复退款

因此,Java 并不需要完全理解模型为什么选错了。

Java只需要判断:

当前 Tool 所需的执行条件有没有满足。

如果没有满足,就拒绝执行。


四、Tool 执行前应该校验什么?

一个可靠的 Tool 执行器,至少应该检查以下内容。

1. Tool 白名单

模型只能调用系统允许的 Tool。

复制代码
if (!allowedTools.contains(toolName)) {
    throw new ToolRejectedException("TOOL_NOT_ALLOWED");
}

不能因为模型生成了:

复制代码
deleteDatabase
executeShell

系统就尝试执行。


2. 参数 Schema

例如检查:

  • 必填参数是否存在;

  • 参数类型是否正确;

  • 枚举值是否合法;

  • 字符串是否超长;

  • 数值是否超过范围。

即使模型支持结构化输出,Java 也不能完全信任模型传参。


3. 身份和资源归属

例如:

复制代码
当前订单是否属于当前用户?
当前用户是否允许查询这笔订单?
当前用户是否有退款权限?

不能因为模型提供了一个 orderId,就允许查询其他用户的订单。


4. 当前任务状态

例如退款 Tool 只有在以下状态才能执行:

复制代码
WAITING_USER_CONFIRMATION
↓
用户确认
↓
READY_TO_EXECUTE

如果当前仍然处于:

复制代码
READ_ONLY

就应该拒绝执行写操作。


5. 业务前置条件

例如退款需要检查:

  • 订单是否存在;

  • 是否满足退款时间;

  • 是否已经退款;

  • 是否超过可退款金额;

  • 商品类型是否支持退款。

这些都应该由确定性的 Java 规则处理。


6. 风险等级和审批

可以给不同 Tool 设置风险等级:

复制代码
queryOrder             READ
checkRefundEligibility READ
changeAddress          WRITE
applyRefund            HIGH_RISK_WRITE
deleteUser             CRITICAL

低风险查询可以较自由调用。

写操作可能需要用户二次确认。

高风险操作还可能需要人工审批。


7. 幂等性

Agent 可能因为网络超时重复调用同一个 Tool:

复制代码
applyRefund(A10086)
applyRefund(A10086)

Java 必须保证同一个业务请求不会被重复执行。


8. 最新业务状态

模型的判断可能基于几秒前甚至几分钟前的状态。

执行前必须重新读取最新数据,不能只依赖之前的 Tool Result。


9. 审计日志

需要记录:

  • 哪个用户发起;

  • 哪个模型选择了 Tool;

  • Tool 名称和参数;

  • 为什么允许或拒绝;

  • 最终执行结果;

  • traceId 或 requestId。

否则出现事故后,很难还原完整过程。


五、Agent 为什么能够连续调用多个 Tool?

一个真实任务通常无法通过一次 Tool 调用完成。

例如用户说:

支付服务刚才出错了,帮我看看原因。

Agent 第一步可能调用:

复制代码
queryServiceStatus("payment")

返回:

复制代码
{
  "status": "RUNNING",
  "errorRate": 0.32
}

Agent发现服务仍在运行,但错误率很高,于是调用:

复制代码
queryRecentLogs("payment")

返回:

复制代码
{
  "mainError": "DATABASE_CONNECTION_TIMEOUT",
  "occurrences": 128
}

Agent再调用:

复制代码
queryDatabaseStatus()

最后发现数据库连接数已经耗尽。

整个过程是:

复制代码
观察当前信息
↓
决定下一步动作
↓
调用 Tool
↓
获取 Tool Result
↓
更新判断
↓
继续调用或停止

这就是 Agent Loop。

可以简化为:

复制代码
Observe
→ Decide
→ Act
→ Observe

每一次 Tool Result 都会成为下一次决策的新依据。


六、为什么不一开始调用所有 Tool?

假设运维 Agent 可以调用:

复制代码
queryServiceStatus
queryRecentLogs
queryCpuUsage
queryDatabaseStatus
contactEngineer

一种简单做法是把所有 Tool 全部执行。

但这样会产生多个问题。

1. 浪费资源

可能调用了与当前问题无关的接口,增加:

  • Token;

  • 网络请求;

  • 响应时间;

  • 系统负载;

  • 调用成本。

2. 无法根据结果缩小范围

Agent Loop 的价值在于:

复制代码
先获得一个结果
→ 根据结果判断最大的信息缺口
→ 再选择最有价值的 Tool

例如如果服务已经完全停止,下一步可能应该检查部署和进程,而不是立刻查询数据库。

3. 可能提前产生副作用

查询类 Tool 风险较低,但:

复制代码
restartService
contactEngineer
cancelOrder
applyRefund

不能一开始全部执行。

不过,并不是所有 Tool 都必须严格串行。

对于彼此独立、低风险、没有副作用的查询,可以并行执行:

复制代码
queryCpuUsage
queryMemoryUsage
queryServiceStatus

因此,更准确的原则是:

有依赖关系的步骤按结果推进;相互独立的低风险查询可以并行。


七、Agent Loop 为什么会陷入死循环?

假设 Agent 调用日志服务:

复制代码
{
  "toolName": "queryRecentLogs",
  "arguments": {
    "serviceName": "payment"
  }
}

Tool 返回:

复制代码
{
  "success": false,
  "errorCode": "LOG_SERVICE_TIMEOUT",
  "retryable": true
}

模型随后反复调用:

复制代码
queryRecentLogs
→ 超时

queryRecentLogs
→ 超时

queryRecentLogs
→ 超时

这就是无效循环。

此外,还有一种不容易发现的循环:

复制代码
queryServiceStatus
→ queryRecentLogs
→ queryServiceStatus
→ queryRecentLogs

虽然没有连续调用同一个 Tool,但系统仍然没有获得新信息。

因此,不能只判断:

是否连续调用了相同 Tool。

系统还需要记录完整执行轨迹。


八、Agent Loop 应该设置哪些停止条件?

一个可靠 Agent 至少需要以下几类限制。

1. 最大步骤数

复制代码
int maxSteps = 10;

防止模型无限规划。


2. 最大 Tool 调用次数

复制代码
int maxToolCalls = 8;

步骤数和 Tool 调用数不一定相同,因为某一步可能直接生成回答。


3. 最大执行时间

复制代码
Duration maxExecutionTime = Duration.ofSeconds(30);

不同任务应设置不同时间预算:

  • 客服对话:通常几秒;

  • 数据查询:可能几十秒;

  • 数据分析:可能几分钟;

  • 长任务 Agent:可能持续更久,但需要持久化和恢复。


4. 最大重试次数

不能把所有错误统一设置为重试 3 次。

应该根据错误类型决定:

复制代码
INVALID_PARAMETER
→ 不重试,修正参数

PERMISSION_DENIED
→ 不重试,申请权限或转人工

ORDER_NOT_FOUND
→ 不使用相同订单号重试,询问用户

DATABASE_TIMEOUT
→ 有限重试

RATE_LIMITED
→ 等待后重试

5. 退避重试

可重试错误也不能立即高频调用。

例如:

复制代码
第 1 次失败 → 等待 1 秒
第 2 次失败 → 等待 2 秒
第 3 次失败 → 等待 4 秒
仍然失败 → 降级或转人工

这种方式可以避免在系统故障时进一步增加压力。


6. 无进展检测

系统需要判断:

这次 Tool 调用是否带来了新信息?

例如:

复制代码
相同 Tool + 相同参数 + 相同返回结果

连续出现时,就应该停止。

也可以检测:

复制代码
A → B → A → B

这种交替循环。


九、什么时候应该停止排查?

Agent 不一定需要百分之百证明根因。

假设已经确认:

复制代码
支付服务仍在运行
错误率为 32%
日志大量出现数据库连接超时
数据库连接数已经满

更可靠的回答不是假装完全确定:

根因就是数据库连接池耗尽。

而是区分:

复制代码
已确认事实
当前推测
缺失信息
建议下一步

例如:

复制代码
已确认:
支付服务错误率较高,日志中大量出现数据库连接超时,同时数据库连接数已达到上限。

当前判断:
连接池耗尽很可能是当前故障的主要原因。

尚未确认:
连接数耗尽是由慢查询、连接泄漏还是突发流量导致。

建议:
进一步检查活跃连接来源、连接池配置和慢查询记录。

这说明:

Agent 的目标不是无限追求绝对确定,而是在证据足够时给出带有不确定性说明的当前结论。


十、什么是 Agent State?

Agent 每调用一次 Tool,都需要记住之前发生了什么。

以退款任务为例:

复制代码
用户目标:检查退款资格
订单号:A10086
用户要求:不要直接退款
订单状态:已签收
退款资格:通过
可退金额:399 元
已调用 Tool:queryOrder、checkRefundEligibility
当前阶段:等待用户确认

这些信息共同组成当前任务的 State。

State 可以理解为:

Agent 继续完成当前任务所需要的结构化事实、进度、约束和授权信息。


十一、State 和聊天记录有什么区别?

聊天记录可能是:

复制代码
用户:帮我看看能不能退款,先不要真的退。
Agent:好的,我先查询订单。
Tool:订单已签收。
Agent:我再检查退款资格。
Tool:退款资格通过,可退 399 元。

而 State 可以是:

复制代码
{
  "taskId": "refund_001",
  "intent": "CHECK_REFUND_ELIGIBILITY",
  "orderId": "A10086",
  "operationMode": "READ_ONLY",
  "userConfirmedRefund": false,
  "refundEligible": true,
  "refundAmount": 399,
  "taskStage": "WAITING_USER_CONFIRMATION"
}

两者区别是:

复制代码
聊天记录:
帮助模型理解发生过什么。

State:
帮助系统确定当前做到哪一步,以及下一步允许做什么。

如果只有聊天记录,Java 每次都需要重新依赖模型理解:

用户是否确认过退款?

而使用 State,可以直接判断:

复制代码
if (!state.isUserConfirmedRefund()) {
    reject("USER_CONFIRMATION_REQUIRED");
}

十二、State 应该保存什么?

可以把 State 分成四类。

1. 任务目标

复制代码
{
  "intent": "CHECK_REFUND",
  "operationMode": "READ_ONLY"
}

表示用户希望完成什么,以及是否允许执行写操作。


2. 业务事实

复制代码
{
  "orderId": "A10086",
  "orderStatus": "DELIVERED",
  "refundEligible": true,
  "refundAmount": 399
}

这些是当前任务已经获得的关键事实。


3. 执行进度

复制代码
{
  "taskStage": "WAITING_USER_CONFIRMATION",
  "toolCallCount": 2,
  "retryCount": 0,
  "completedSteps": [
    "QUERY_ORDER",
    "CHECK_REFUND_ELIGIBILITY"
  ]
}

用于恢复任务和防止重复执行。


4. 约束与授权

复制代码
{
  "userConfirmedRefund": false,
  "approvalStatus": "NOT_REQUIRED",
  "proposedAction": "APPLY_REFUND",
  "executionStatus": "NOT_STARTED"
}

需要注意:

复制代码
proposedAction = APPLY_REFUND

只是表示 Agent 建议退款。

它不等于:

复制代码
已经获得退款授权。

十三、哪些内容不应该直接放进 State?

1. 全部聊天历史

聊天历史可以独立保存,但不能无限塞入当前 State。

State 应提取关键事实和约束。


2. 所有 Tool 原始返回数据

如果 Tool 返回几万行日志,不能全部放进 State。

更合理的是保存:

复制代码
结果摘要
关键业务字段
错误码
requestId
数据版本

完整原始结果放到日志或独立存储中。


3. 密码、密钥和 Token

以下内容绝对不应进入 Agent State 或模型上下文:

复制代码
数据库密码
云服务 Secret
支付私钥
管理员 Token

4. 用户的长期喜好

例如:

复制代码
用户喜欢简洁回答
用户通常选择原路退款
用户偏好某种酒店

这类跨任务信息更接近 Long-term Memory,而不是当前任务 State。

简单区分:

复制代码
State:
当前这件事情做到哪里了?

Memory:
过去有哪些信息可能对未来任务有用?

十四、State 为什么需要持久化?

如果 State 只存在 Java 内存中:

复制代码
Map<String, AgentState> stateMap;

服务器一旦重启,任务状态就会丢失。

对于以下任务,通常需要持久化:

  • 等待用户确认的退款;

  • 等待人工审批的操作;

  • 已经执行了部分写操作的流程;

  • 运行时间较长的数据分析;

  • 需要跨请求继续执行的任务;

  • 涉及资金、订单或生产环境的任务。

可以保存到:

  • Redis;

  • MySQL;

  • PostgreSQL;

  • 专门的任务状态存储。

例如:

复制代码
{
  "taskId": "refund_001",
  "orderId": "A10086",
  "taskStage": "WAITING_USER_CONFIRMATION",
  "refundEligible": true,
  "refundAmount": 399,
  "userConfirmedRefund": false,
  "stateVersion": 3
}

而以下任务通常不一定需要持久化:

  • 普通问答;

  • 几秒内完成的低风险查询;

  • 失败后可以安全重新开始的任务。

是否持久化,主要看:

State 丢失后,重新执行的成本和风险有多大。


十五、用户中途改变要求时,State 怎么更新?

原来的 State:

复制代码
{
  "operationMode": "READ_ONLY",
  "userConfirmedRefund": false
}

用户后来又说:

可以,直接退吧。

系统不需要把所有状态清空重来。

可以保留:

  • 订单号;

  • 已查询的订单信息;

  • 之前的 Tool 调用;

  • 退款资格结果。

只更新:

复制代码
{
  "operationMode": "EXECUTE",
  "userConfirmedRefund": true
}

但真正执行前仍然需要重新检查最新业务状态。

原因是之前的退款资格结果可能已经过期:

复制代码
之前检查允许退款
↓
其他请求已经完成退款
↓
当前 Agent 仍按旧结果执行

正确流程是:

复制代码
更新用户最新意图
↓
保留可复用的任务状态
↓
执行前重新读取最新业务状态
↓
再次校验
↓
满足条件后执行

十六、State 并发:为什么最后写入不一定正确?

假设当前状态:

复制代码
{
  "taskId": "refund_001",
  "operationMode": "READ_ONLY",
  "userConfirmedRefund": false,
  "stateVersion": 3
}

用户先说:

可以退款。

请求 A 读取 version=3,准备更新成:

复制代码
EXECUTE

紧接着用户又说:

等等,先别退。

请求 B 也读取 version=3,准备更新成:

复制代码
READ_ONLY

如果请求 B 先执行,State 已经变成用户最新要求:

复制代码
READ_ONLY

但请求 A 随后才写入:

复制代码
EXECUTE

旧请求就覆盖了用户的新指令。

这是一种典型并发问题。


十七、使用版本号防止旧状态覆盖新状态

State 中可以维护:

复制代码
{
  "stateVersion": 3
}

更新时要求数据库当前版本仍然是 3:

复制代码
UPDATE agent_task
SET operation_mode = 'EXECUTE',
    user_confirmed_refund = TRUE,
    state_version = state_version + 1
WHERE task_id = 'refund_001'
  AND state_version = 3;

如果更新行数为 0,说明当前状态已经被其他请求修改。

Java 应返回:

复制代码
STATE_VERSION_CONFLICT

当前请求不能继续按照旧状态执行。

这类方式通常称为乐观并发控制。

它的核心思想是:

只有在状态从读取到提交期间没有发生变化时,才允许本次更新成功。


十八、发生版本冲突后应该怎么办?

错误做法:

复制代码
状态更新失败
↓
继续执行退款

这可能造成:

复制代码
State 显示用户已经撤销退款
但支付平台已经完成退款

合理流程是:

复制代码
收到 STATE_VERSION_CONFLICT
↓
立即停止当前执行
↓
重新读取最新 State
↓
判断用户最新意图
↓
重新读取最新业务状态
↓
重新规划下一步
↓
满足条件后再更新或执行

不能直接覆盖,也不能让 LLM凭感觉决定使用哪个版本。


十九、两个 Agent 同时操作同一订单怎么办?

假设:

复制代码
Agent A 准备退款
Agent B 准备取消订单

两边一开始查询到的状态都是:

复制代码
PAID

如果两边都因为之前校验通过而执行,就可能产生冲突。

仅仅在执行前重新查询一次还不一定安全。

因为仍可能发生:

复制代码
Agent A 查询:PAID
↓
Agent B 立即取消订单
↓
Agent A 根据刚才的查询继续退款

更可靠的做法是把状态校验和状态修改放到一个原子操作中:

复制代码
UPDATE orders
SET status = 'REFUNDED'
WHERE order_id = 'A10086'
  AND status = 'PAID';

如果成功更新一行,说明当前请求获得了状态修改权。

如果更新零行,说明订单已经被其他请求修改。

因此:

真正执行写操作时,不能只相信之前看到的状态快照。


二十、为什么还要记录状态变化事件?

只保存当前 State,可以知道:

现在是什么状态。

但无法知道:

为什么会变成这个状态。

因此可以记录关键事件:

复制代码
10:00 用户查询退款资格
10:01 退款资格检查通过
10:02 用户确认退款
10:03 用户撤销退款确认
10:04 旧请求尝试执行,被版本冲突拒绝

这些事件主要用于:

  • 审计;

  • 排查事故;

  • 分析并发问题;

  • 恢复中断任务;

  • 还原用户和 Agent 的操作顺序;

  • 判断某次写操作为什么被允许或拒绝。

事件记录不一定要全部发送给模型。

可以在需要时提取与当前任务有关的摘要。


二十一、一个完整的 Agent 执行框架

可以把当前阶段的知识组合成如下流程:

复制代码
用户发送请求
↓
模型理解意图
↓
更新结构化 State
↓
模型选择 Tool
↓
Java 检查 Tool 白名单
↓
Java 校验参数
↓
Java 校验用户权限
↓
Java 校验当前 State
↓
Java 校验业务前置条件
↓
Java 判断风险和审批要求
↓
执行 Tool
↓
返回结构化 Tool Result
↓
更新 State 和事件记录
↓
模型根据结果继续决策
↓
达到目标、预算上限或无进展条件后停止

如果出现并发更新:

复制代码
发现 State Version Conflict
↓
停止旧执行
↓
读取最新 State
↓
重新判断

二十二、Java 侧可以如何分层?

不必在每个 Tool 中重复编写所有通用校验。

可以设计统一执行层:

复制代码
public ToolResult executeTool(
        ToolCall toolCall,
        AgentContext context,
        AgentState state
) {
    validateToolWhitelist(toolCall);
    validateSchema(toolCall);
    validateAuthentication(context);
    validatePermission(toolCall, context);
    validateStatePreconditions(toolCall, state);
    validateRiskPolicy(toolCall, context);

    return toolRegistry.execute(toolCall);
}

通用能力可以集中处理:

  • Tool 白名单;

  • Schema 校验;

  • 身份认证;

  • 权限控制;

  • 风险等级;

  • 用户确认;

  • 人工审批;

  • 幂等性;

  • 限流;

  • Trace;

  • 审计。

具体业务 Tool 只负责自己的业务规则:

复制代码
public RefundResult applyRefund(RefundCommand command) {
    validateOrderOwnership(command);
    validateRefundEligibility(command);
    validateRefundAmount(command);
    validateIdempotency(command);

    return paymentService.refund(command);
}

这样可以避免在每个 Tool 中重复编写通用逻辑。


总结

这一阶段最重要的认知是:

模型只负责提出下一步行动,系统必须负责判断这个行动能否真正执行。

Tool Calling 的完整链路是:

复制代码
模型选择 Tool
→ Java 校验
→ Java 执行或拒绝
→ Tool Result
→ 模型继续决策

Agent Loop 的本质是:

复制代码
每次根据新结果更新判断

而不是不停调用 Tool。

State 的本质是:

复制代码
当前任务的目标
+ 业务事实
+ 执行进度
+ 约束和授权

并发控制解决的是:

复制代码
防止旧决策覆盖用户的新指令

最终可以把本阶段压缩成几句话:

复制代码
Tool Call 是 proposal,不是 command。

模型可以选错 Tool,
但 Java 必须保证错误 Tool 无法突破安全边界。

Agent Loop 每一步都应该获得新信息或推动状态变化。

聊天记录帮助模型理解过去,
State 帮助系统控制现在和下一步。

Agent 可以基于旧状态作出错误决策,
但系统必须阻止旧决策改变新世界。

一个可靠 Agent 并不是"模型足够聪明"就能实现的。

它需要:

复制代码
模型的动态判断
+ Java 的确定性校验
+ 可恢复的任务 State
+ 并发控制
+ 审计和停止条件

共同组成完整的工程系统。

相关推荐
夫唯不争,故无尤也19 分钟前
On-Policy Distillation(OPD)和reinforcement (RL)结合
llm·agent·强化学习·rl·opd
张忠琳22 分钟前
【deepseek-harness】Cordis 时空可组合性编程范式 — 三段式精读笔记(一)
ai·agent·deepseek·harness·cordis·dsh
Erishen25 分钟前
💡 当 LLM 开始骗自己:用几行正则给 AI 生成的文章上一道可信度闸门
架构·开源·agent
新知图书26 分钟前
14.1 多模态试驾预约Agent系统概述
人工智能·agent·ai agent·智能体
waillyer30 分钟前
企业知识库智能问答 Agent(React + Nest)
javascript·redis·agent
君顾133 分钟前
从0到1课后辅导管理系统开发实战:需求文档、架构设计全复盘
java·开发语言
NeoGressAI外贸数字化39 分钟前
外贸建站:新手怎么自建独立站完整指南
java·人工智能
前端 贾公子40 分钟前
第09章:上下文与记忆 (4)
java·服务器·前端
wjjzhbb1 小时前
中小团队敏捷转型:Scrum还是看板?
java·maven·scrum