close
杠精派
派聪明
0/512

热门评论 Image

Image
xuxinyi 2026年06月21日 15:34
@派聪明 为什么Message和 ChatResponse要定义成record类型?大模型输出的格式是固定的吗都包含哪些内容?能处理提取成ChatResponse
点赞
回复3 取消回复
Image
派聪明 2026年06月21日 15:35
结合参考资料,这里为您清晰地解答: **1. 为什么 Message 和 ChatResponse 使用 `record` 类型?** `record` 是 Java14 引入的特性,专门用来定义纯数据载体。 * **简洁安全**:参考资料中 `Message`需要包含 `role`、`content`、`toolCalls`等字段。使用 `record` 只需一行代码(如 `public record Message(...)`),编译器就会自动生成构造器、Getter(如 `msg.role()`)、`equals()` 和 `toString()`等方法。 * **不可变性**:`record` 是不可变的(final),这使得它在多步骤的 ReAct循环和上下文历史记录中更加安全,避免了被意外篡改的风险。 **2. 大模型输出的格式是固定的吗?** 大模型的 API输出**并不是完全固定的自然语言**,而是通过 HTTP返回**标准化的 JSON 格式数据**。为了让大模型知道如何输出,Agent程序会在请求时带上定义好的 JSON Schema,约束大模型按规范返回。 **3.输出都包含哪些内容?如何提取成 ChatResponse?** 参考资料提到,Agent 发送 HTTP请求后会拿到一段 JSON 字符串(`responseBody`)。这段 JSON 通常包含以下核心内容: * **content**:普通的文本回复内容。 * **tool_calls**:工具调用请求数组(包含工具调用的 `id`,以及具体调用的函数名 `name` 和参数 `arguments`)。 * **token 使用信息**:如输入/输出的 Token消耗量。 **提取流程:** 程序会使用 JSON 解析库(如参考资料中用到的 Jackson,通过 `mapper.readTree(responseBody)`读取 JSON树),精准提取出 `content` 和 `tool_calls`节点,然后封装映射成 Java中的 `ChatResponse` 对象。这样,Agent核心循环就能方便地调用 `response.hasToolCalls()`判断是否需要执行工具,或者直接获取文本内容。
1
回复 取消回复
展开剩余 2 条回复

60 条评论

Image
勤恳的冬瓜 2026年08月23日 15:55
引用原文:个 JSON Schema
JSON Schema 是一种用 JSON 来描述"别的 JSON 数据长什么样"的格式——本质是给数据写"类型说明书 / 格式说明书"。
点赞
回复 取消回复
Image
安和 2026年08月07日 07:03
引用原文:我一直很好奇这玩意儿到底是怎么实现的。
@派聪明,最新版本的paicli和claude code相比呢。
点赞
回复1 取消回复
Image
派聪明 2026年08月07日 07:03
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
Image
A.Mars(水准) 2026年08月06日 01:10
引用原文:我们的简化版用简单列表,但原理是一样的。
我们的简化版和Claude Code的原理是什么@派聪明
点赞
回复1 取消回复
Image
派聪明 2026年08月06日 01:10
小派正在努力回答中, 耐心等待一下吧...
1
回复 取消回复
Image
克莱因蓝 2026年08月04日 10:41
引用原文:描述和参数定义会传给 LLM,让 LLM 知道什么时候该用这个工具、需要什么参数。执行逻辑是实际的 Java 代码,负责完成任务。
@派聪明llm传回要执行的工具和参数后,代码是怎么接收到参数的,工具执行的入口在哪里
点赞
回复1 取消回复
Image
派聪明 2026年08月04日 10:41
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
Image
过时的草莓 2026年07月31日 22:29
引用原文: JSON Schema
@派聪明,这个是什么
点赞
回复1 取消回复
Image
派聪明 2026年07月31日 22:29
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
Image
mwdb996 2026年07月23日 19:59
引用原文:工具定义格式 要让 LLM 知道有哪些工具可用,需要按照特定格式定义工具: public record Tool(String name, String description, JsonNode parameters) {} 复制代码 parameters 是一个 JSON Schema,描述工具需要哪些参数、参数类型是什么。比如 write_file 工具的参数定义: { "type": "object", "properties": { "path": { "type": "string", "description": "文件路径" }, "content": { "type": "string", "description": "文件内容" } }, "required": ["path", "content"] } 复制代码 LLM 会根据这个定义,在需要时生成正确的参数。
@派聪明 这个应该放在哪个文件里面?
点赞
回复1 取消回复
Image
派聪明 2026年07月23日 19:59
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
Image
绿蜥蜴 2026年07月22日 22:22
引用原文:这个循环的关键点是:只要 LLM 还在请求工具调用,循环就继续。只有当 LLM 直接回复内容(没有 tool_calls)时,才认为任务完成。
感觉这里不太合理,很多场景下不需要调用工具,只是waiting_user状态,比如讨论设计方案。这种情况下直接判断是否有工具调用来结束对话比较局限
1
回复 取消回复
Image
迷路的大白 2026年07月14日 22:54
引用原文:检测循环是否陷入重复模式
@派聪明 怎么判断是否陷入重复模式
点赞
回复1 取消回复
Image
派聪明 2026年07月14日 22:54
判断 Agent 是否陷入重复模式(即死循环),通常有以下几种技术手段: --- ## 1. 检测重复的 Tool Call 最直接的方法:**记录每次工具调用的(工具名, 参数摘要, 结果摘要)**,如果连续 N 次(比如 3 次)的调用完全相同,大概率是死循环。 ```java // 存储最近几次工具调用的签名 List<String> recentCallSignatures = new ArrayList<>(); String signature = toolName + ":" + hash(args) + ":" + hash(result); recentCallSignatures.add(signature); if (recentCallSignatures.size() >= 3) { Set<String> unique = new HashSet<>(recentCallSignatures); if (unique.size() == 1) { // 连续 3 次工具调用完全一样 → 陷入重复模式 break; } } ``` ## 2. 文本相似度检测 LLM 的回复内容可能不完全相同但高度相似。可以用 **余弦相似度** 或 **编辑距离** 来判断: ```java // 比较最近两次 LLM 输出的相似度 double similarity = cosineSimilarity( response1.getContent(), response2.getContent() ); if (similarity > 0.95) { // 输出内容高度重复 → 陷入重复 } ``` 简单的实现可以用 Levenshtein 距离或者直接比较文本哈希。 ## 3. 无进展检测 记录 Agent 执行过程中是否产生了实质性变化: | 指标 | 检测方式 | |------|---------| | 文件变更 | 记录被写入的文件路径,如果一直没有新文件或文件不变 | | 命令输出 | 执行命令的 stdout/stderr 是否每次相同 | | 状态变化 | 比如当前工作目录、项目结构有无变化 | 如果连续 N 次迭代**没有任何状态发生变化**,强制中断。 ## 4. 模式匹配 更高级的:检测 Agent 是否在 **A→B→A→B** 来回跳转。 ```java // 检测交替模式:toolA → toolB → toolA → toolB for (int i = 0; i < history.size() - 3; i++) { if (history.get(i).equals(history.get(i+2)) && history.get(i+1).equals(history.get(i+3))) { // 发现交替循环 break; } } ``` ## 5. 结合时间维度 如果 Agent **在某个步骤停留时间过长**,或者 **总迭代数超限也没完成**,也可以判定为异常: ```java if (System.currentTimeMillis() - stepStartTime > 30_000) { // 某一步耗时超过 30s → 可能卡住 } if (iterationCount > MAX_ITERATIONS) { // 超出最大迭代次数 } ``` --- ## 实际建议 简单项目中,**检测重复 Tool Call + 检测无进展** 这两个就够了。伪代码: ```java if (连续3次调用相同工具 && 连续3次参数相同 && 连续3次结果相同) { log.warn("检测到重复模式,强制终止循环"); return "任务执行陷入循环,已终止。"; } ``` 在生产环境中(如 Claude Code),还会结合 **语义相似度** 和 **向量化嵌入** 来做更精确的检测,但成本较高。
点赞
回复 取消回复
Image
迷路的大白 2026年07月14日 22:46
引用原文:我们设置了 MAX_ITERATIONS = 10
@派聪明 这个10是怎么来的,有什么依据吗
点赞
回复1 取消回复
Image
派聪明 2026年07月14日 22:46
根据参考资料原文,这个 **10** 并没有什么复杂公式或权威标准作为依据,它的核心定位就是一个 **安全阈值(经验值)**。 文章中明确解释了原因: > *“循环必须有终止条件,否则可能陷入死循环。我们设置了 `MAX_ITERATIONS = 10`,超过就强制退出。”* 也就是说,作者在实现这个简化版 Agent CLI 时,为了防止 ReAct 循环无限执行下去(例如 LLM 反复调用工具无法完成),随手设置了一个 **合理的上限**。10 次迭代对于大多数编程任务(创建项目、读写文件、执行命令等)来说已经足够完成,同时也不会因为循环次数过多而浪费 Token 或时间。 此外,文章也指出,**在实际生产级产品中**,仅仅靠一个迭代次数限制是不够的,还需要配合更多保护机制: - **时间限制**:单次任务最多执行 N 秒 - **Token 限制**:总消耗不超过上限 - **用户确认**:危险操作前询问用户 - **状态检测**:检测循环是否陷入重复模式 所以结论很简单:**10 是作者随手选的一个安全经验值,目的是防止死循环,而非基于某个严谨的数学推导或行业标准。** 如果你想用在真正的产品中,可以根据任务复杂度、API 成本和用户体验来调整这个值(比如 5、15、20 等)。
点赞
回复 取消回复
Image
ꪗꪖꪀᧁ 2026年07月13日 13:49
@派聪明 为什么不使用框架去写agent
点赞
回复1 取消回复
Image
派聪明 2026年07月13日 13:49
这是一个非常好的问题。从参考资料中二哥的文章里,我们可以提炼出几个核心原因,他的做法其实是一种**刻意的学习选择**,而非对框架的否定。 ## 核心原因:为了理解原理,而不是方便生产 二哥在文章中明确提到了两个关键点: 1. **好奇心的驱动**:文章开头就说:“我一直很好奇这玩意儿到底是怎么实现的。” 他用了 Claude Code、Qoder CLI 一段时间后,想知道背后的机制,而不是满足于“会用”。 2. **不依赖任何第三方 Agent 框架**:在项目结构部分特别标注了这一点。他选择用 Java 17 + Maven + Jackson + OkHttp 这些最基础的库,完全手写 ReAct 循环。 ## 手写的核心价值 **理解 Agent 的本质**:Agent 的核心就是**推理(Reasoning)→ 行动(Acting)→ 观察(Observing)** 的 ReAct 循环。用框架固然方便,但框架会封装掉这些细节,让你变成一个“配置工程师”而不是“理解者”。 二哥写道:**“理解原理比会用工具更重要。”** 当你明白 Agent 是怎么工作的,再用 Claude Code、Qoder CLI 时,就能更好地理解它们的行为,也能更好地控制它们。 ## 什么时候该手写,什么时候该用框架 | 场景 | 推荐方式 | 原因 | |------|---------|------| | **学习原理、教学演示** | 手写(如本文) | 暴露核心循环,理解本质 | | **快速验证、原型开发** | 手写或轻量框架 | 400行就能跑起来,灵活可控 | | **生产级产品** | 框架(LangChain、Spring AI等) | 需要完善的错误处理、重试、上下文管理、可观测性 | **总结:二哥不是“反对框架”,而是先用“手写”搞懂原理。** 他文章的结尾也说得很清楚——这个基础的400行代码可以往很多方向扩展,包括增加工具、改进上下文、多Agent协作。当原理理解透彻后,再使用框架时,你就知道框架在背后做了什么,出了问题也能快速定位。
点赞
回复 取消回复

目录