MoreRSS

site iconsugar | 粥里有勺糖修改

99年,西南石油大学,热爱开源。前端,美团,阿里。运营视野修炼周刊。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

sugar | 粥里有勺糖的 RSS 预览

Harness 学习笔记分享(Part 1)

2026-08-10 10:26:33

Harness 学习笔记分享(Part 1)

本文仅代表作者个人观点,如果内容有错误或和你理解上有所出入,欢迎交流与指正。

学习过程参考了 Pi Agent 的源码。按照其分层思路和一些实现方案,笔者自行实现了一个 MVP 版本的 Harness。

本文主要分享一下整个过程中的一些学习心得和个人的一些想法。

前言

“Agent” 从最开始文本对话式,到多模态(语音/图片/视频)智能体,再到现在的 Agent(能够辅助办公、开发、生成完整项目等),不同阶段 Agent 的定义也不一样。

最近的一阶段是 "Model + Harness = Agent"。

之前是高频使用各种智能体辅助写文档,改项目代码。

最近一段时间准备做一些带 Agent 能力的 AI 应用,所以先学习一下 Harness 相关的知识,知己知彼😋。

开局先来一张图

Model + Harness

Harness 算是模型的运行时,各家 Agent 的差异也就在这部分,模型都是可以随时切换的。

所以没有 Harness 的「Agent」,大部分就是纯聊天。

先小小总结一下几个主要模块

各个模块 作用
Model 读 Context,产出文本或结构化 tool_calls
Context 本轮真正送进模型的内容,不单单是「用户输入的那一句话」
Tools 实际做外部调用,真正改文件、跑命令
Harness 负责 循环、校验、执行、上下文组装、回写、权限、资源控制等行为
Agent 模型跑在 Harness 上、冲着目标多步往前推进,直到完成或达到终止条件

Tools

Tools 是模型和外部沟通的桥:模型只负责发出结构化调用,真正去改文件、跑命令、调 API 的是具体 Tool 实现;调度和校验则由 Harness 来做。

先说 Function Calling

Function Calling(现在大部分时候也叫 Tool Calling)解决的问题是:

避免模型用自然语言描述去说明要调用的工具,而是让它输出可解析的调用结构。

没有这套约定时,模型可能写

我需要调用 get_weather(上海) 来获取天气信息

应用侧很难可靠地解析。有了 Function Calling:

  1. 先把工具的 schema 交给模型(能调什么、参数长什么样)
  2. 模型需要时返回 tool_calls(调用谁、参数是什么、本次调用的 id)
  3. Harness 解析调用工具执行,把结果以 tool 消息写回
  4. Harness 再请求模型,基于工具执行结果继续做推理

贴一张官方的图:function-calling#how-it-works

下面是我画的一版 Model / Harness / Tools 怎么流转起来的(对应上面 1→4 步):

Function Calling 交互释义

调用示例

下面来个最简 demo(OpenAI Chat Completions,非流式),看一下调用结构

ts
// 1)准备工具声明(schema)——只描述能力,不含实现
const tools = [
  {
    type: 'function',
    function: {
      name: 'get_weather',
      description: '查询某城市当前天气',
      parameters: {
        type: 'object',
        properties: {
          city: { type: 'string', description: '城市名,如上海' },
        },
        required: ['city'],
        additionalProperties: false,
      },
    },
  },
]

const messages = [
  { role: 'user', content: '上海今天天气怎么样?' },
]

// 2)一次请求:messages + tools
const res = await fetch(`${OPENAI_API_BASE_URL}/v1/chat/completions`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${OPENAI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'gpt-5.6', // 模型 id
    messages,
    tools,
    tool_choice: 'auto', // 模型自己决定是否调用工具,也可设为 none / required / 指定某个工具
  }),
})

const data = await res.json()
const message = data.choices[0].message
// ↓ 输出释义见下方示例

一次成功响应(需要调工具时)大致长这样:

ts
// data 示意(省略 usage 等)
{
  id: "chatcmpl-xxx",
  choices: [
    {
      index: 0,
      finish_reason: "tool_calls", // 因工具调用结束本轮;最终文本常见 "stop"
      message: {
        role: "assistant",
        content: null, // 也可能是一段说明;有 tool_calls 时经常为 null
        tool_calls: [
          {
            id: "call_abc123",
            type: "function",
            function: {
              name: "get_weather",
              arguments: '{"city":"上海"}', // 注意:是字符串,不是对象
            },
          },
        ],
      },
    },
  ],
}

返回结果里,重点关注这几个:

  • message.tool_calls:决定是否需要执行工具
  • tool_calls[].id:回写结果时需要一一对应上id
  • tool_calls[].function.name / arguments:工具名和参数
  • finish_reason"tool_calls" 表示「需要执行工具」;"stop" 表示本轮结束

解析执行示例

Harness 处理工具调用的核心逻辑是:校验 → 执行 → 回写 → 再请求。

ts
// 1)先把本轮 assistant(含 tool_calls)写入 messages,下一轮还要带上
// 保持 OpenAI 原始结构即可
messages.push({
  role: 'assistant',
  content: message.content,
  tool_calls: message.tool_calls,
})

// 2)解析参数 → 校验 → 执行 → 回写
for (const tc of message.tool_calls) {
  // 格式化一下参数
  const call = {
    id: tc.id,
    name: tc.function.name,
    arguments: JSON.parse(tc.function.arguments || '{}'), // 字符串 → 对象
  }

  // 按 schema 校验;不合法则回写错误
  if (isInvalid(call)) {
    messages.push({
      role: 'tool',
      tool_call_id: call.id,
      content: '参数不合法',
    })
    continue
  }

  // 执行工具
  const result = await executeTool(call)

  // 回写结果到上下文中
  messages.push({
    role: 'tool',
    tool_call_id: call.id,
    content: result.content, // 字符串
  })
}

// 3)带着更新后的 messages 再请求模型
const res = await fetch(`${OPENAI_API_BASE_URL}/v1/chat/completions`, {
  // ... 其他参数
  body: JSON.stringify({ messages, tools, tool_choice: 'auto' }),
})

const data = await res.json()
// 模型再次回复,可能包含 tool_calls 或继续自然语言回复
const message = data.choices[0].message

下面是第二次请求模型的 messages 示例,包含了工具调用结果:

json
[
  { "role": "user", "content": "上海今天天气怎么样?" },
  {
    "role": "assistant",
    "content": null,
    "tool_calls": [
      {
        "id": "call_abc123",
        "type": "function",
        "function": {
          "name": "get_weather",
          "arguments": "{\"city\":\"上海\"}"
        }
      }
    ]
  },
  {
    "role": "tool",
    "tool_call_id": "call_abc123",
    "content": "{\"temp\":28,\"unit\":\"C\"}"
  }
]

小结

  1. Function Calling 让模型输出可解析的 tool_calls 参数
  2. Tool:由声明(schema)与实现(handler)组成;声明给到模型,实现留在 Harness 里
  3. Harness 负责校验 → 执行 → 按 tool_call_id 回写 → 再请求

Tools 声明与实现

Agent Loop

真正办事的 Agent,需要把上面的流程自动循环起来:组装上下文 → 请求模型 → 有调用就执行回写 → 再请求,直到给出最终答复,或被约束条件强制停掉。

当然我这里只是一个最简单的实现(用「有没有 tool_calls」来决定要不要自动推进),实际的循环推进条件可能还有其它的策略。

最简 Agent Loop

精简的循环示意

ts
async function runAgent(state) {
  while (true) {
    // 1)组装本轮真正进模型的 Context
    const messages = assembleContext(state)

    // 2)请求模型
    const assistant = await adapter.stream({ messages, tools: state.tools })

    // 3)判断有没有 tool_calls
    if (!assistant.tool_calls?.length) {
      return assistant.content
    }

    // 4)有调用:校验 → 执行 → 回写
    state.messages.push({
      role: 'assistant',
      content: assistant.content,
      tool_calls: assistant.tool_calls,
    })

    for (const call of assistant.tool_calls) {
      const result = await executeTool(call)
      state.messages.push({
        role: 'tool',
        tool_call_id: call.id,
        content: result.content,
      })
    }
    // 5)带着工具结果进入下一轮 while
  }

  return assistant.content
}

和纯对话的差别就在第 4 步:模型输出调用指令,Harness 调度 Tools,用执行结果继续推进。

其它条件

Pi: agent-loop 为例,默认仍是「本轮有没有工具调用」驱动自动续跑,同时还会看下面这些条件:

1)工具结果不一定需要回传

  • 工具执行结果包含一个 terminate: true 字段来决定是否回传
  • 有时最终答案已经在工具结果里了(比如结构化输出工具),不必再花一轮 LLM 把结果「复述」一遍
  • 如果本轮工具调用全部带 terminate: true,就不需要再请求模型
ts
// 示意:结构化输出工具跑完就结束本轮自动续跑
async execute(_id, params) {
  return {
    content: [{ type: "text", text: "已保存结构化结果" }],
    details: params,
    terminate: true,
  };
}

2)shouldStopAfterTurn(回合结束后可选停)

内置钩子:回合结束后由调用方决定是否继续;也可在这里选择性地压缩上下文。

3)steering / follow-up

这两个都是「往 Loop 里塞用户消息」,时机不同:

名词 白话 典型时机
steering Agent 还在跑时,用户可以临时插一句进来,改变执行方向 当前回合工具跑完后、下一次请求模型前注入
follow-up Agent 准备结束了,队列里还有一句比如「顺便再总结一下」 内层循环要退出前从队列里取出;有则继续跑

相关 loop 代码大概就 100 来行,比较容易理解。

小结

  1. Loop 最小模型 = 组装上下文 → 调模型 →(有 tool_calls 则)执行工具 → 再请求进行下一轮
  2. Trace 可以在 Loop 里记录,通过事件将相关信息暴露出来,在 Loop 外监听,方便后续进一步的分析。

运行时约束

Loop 能跑起来之后,接着就是:怎么让它停得住。

Prompt 只能做一些软约束:不可逆操作、调用死循环、反复执行等,需要在 Harness 代码里做硬约束。

运行时约束

常见约束

ts
const controller = new AbortController()

await runAgent({
  maxSteps: 8, // 最大执行回合数
  timeoutMs: 60_000, // 整次 Run 的超时时间
  stopOnToolError: false, // false:错误写回,模型来纠正
  signal: controller.signal,
  onConfirm: async (call) => {
    // 高危工具执行前二次确认;拒绝则写成错误 tool 结果,不调真实 handler
    if (call.name === 'rm' || call.name === 'bash') {
      return window.confirm(`允许执行 ${call.name}?`)
    }
    return true
  },
})

// controller.abort(); 主动取消

校验

执行工具调用前加一层执行前校验:校验 schema,工具是否存在,参数是否合法等。

异常情况可以回写错误的 Tool 消息,让模型可以自主的重试,用户也能感知到。

小结

循环的终止与工具调用安全边界,靠 Harness 代码硬约束。

执行沙箱等下来仔细研究一下,后面再单开文章。

Context Engineering

上下文组装也是 Context Engineering 在 Harness 里的应用。

每次给模型推送的,不只是「用户刚输入的那一句」,而是 Harness 组装出来的完整上下文,常见包括:

  1. 系统提示词:角色、全局行为;项目 Rules 也常并进这一层
  2. 历史对话:全文,或先对历史对话内容进行摘要,再保留最近若干轮
  3. tool schemas:工具声明(本地 + MCP 统一成同一套 schema)
  4. 工具调用结果:上一轮 / 本轮 Loop 写回的 role: "tool" 消息
  5. 本轮用户输入:当前意图
  6. 按需材料:Memory(跨会话的记忆)、RAG(检索的内容片段)、SKILL(SOP 说明)等,相关时才注入

构造上下文

示意代码

ts
const context = assembleContext({
  system: [identity, ...rules], // ① 系统提示 + Rules
  tools: toolDefs, // ③ schemas(含 MCP 归一后的)
  history: messages, // ②④ 历史里已含 tool 结果;或先摘要
  user: currentUserMessage, // ⑤ 本轮输入
  // skillCatalog / skillBody     // ⑥ SKILL:SKILL 目录和相关SKILL 描述,全文按需注入
  // memoryHits / ragChunks       // ⑥ Memory / RAG:外置命中 → 注入
})

小结

  1. 常驻内容:系统提示词 / 历史摘要 / tool schemas / tool 结果 / 本轮 user;
  2. 按需内容:Memory、RAG、SKILL等,相关时才注入

这块的细节实现,待我下去再多研究几个项目,单独出一期文章。

SKILL

可以看成是解决某类问题或完成某项任务的流程规范文档(SOP)。

SKILL 不是 Tool,可以看做是一大段提示词,实际执行仍是通过内部的指令描述调用 Tool 来完成任务。

SKILL 结构

常见就是一份 Markdown(可带 frontmatter),大致三块:

部分 内容
元数据 namedescription(何时该用);可选权限(允许的工具) / 依赖说明
正文 步骤、约束、输出格式、决策规则(真正的 SOP)
其它 (可选) references/、模板、脚本、workflow 等,这块一般是渐进式披露的
md
---
name: weather-brief
description: 用户要天气简报时使用
---

1. 先调 get_weather …
2. 再按固定结构输出 …

怎么进 Context

学到的几种方式:

方式 谁决定加载全文 全文怎么进
手工 / 显式 用户指定(如 /skill:name 直接写入 Context
Harness 匹配 按 SKILL 描述与用户输入做简单的关键词匹配 匹配到的正文写入 Context
模型决定 模型自己选要加载哪个 先把SKILL目录里的(name + description)给模型,模型决策后,再调工具 load_skill,SKILL 正文以 tool 结果回写

三种方式的逐步流程(同一例子 weather-brief):

SKILL 三种进 Context 流程

小结

SKILL 可以由 Harness 发现并注入上下文,也可以给模型披露一些基本信息让模型自己决定加载哪个。

MCP

MCP(Model Context Protocol)是一套开放协议,用来标准化 AI 应用怎么连接外部系统(数据、工具等)。

本文先只看 Tools 部分:统一发现与调用。

收到 tool_calls 后的执行路径:

Harness → 选则 Client → Server → 返回的结果回写 Context。

MCP 构成与调用

角色 职责
MCP Host 创建/管理多个 Client,这里就是 Harness 去负责管理
MCP Client 与单个 Server 的会话连接:提供listToolscallTool 等常用方法
MCP Server 暴露 Tools 并执行(本地进程或远程服务;另有 Resources / Prompts,本文不展开)

传输:本地多用 stdio,远程多用 Streamable HTTP;数据传输协议使用 JSON-RPC

MCP Server(Tools)

ts
// mcp-server.mjs —— Host spawn 的就是这个进程
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { z } from 'zod'

const server = new McpServer({ name: 'demo', version: '1.0.0' })

server.registerTool(
  'add',
  {
    description: '计算两个数字之和',
    inputSchema: {
      a: z.number().describe('加数 a'),
      b: z.number().describe('加数 b'),
    },
  },
  async ({ a, b }) => ({
    content: [{ type: 'text', text: String(a + b) }],
  }),
)

const transport = new StdioServerTransport()
await server.connect(transport) // stdout 专给 JSON-RPC;日志用 console.error

接入到 Harness 中

下面提到的 registry 可以看做是 Harness 里负责管理工具注册和发现的模块

包含本地 Tools + MCP Tools 的管理

ts
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'

// 连接 MCP Server
const transport = new StdioClientTransport({
  command: 'node',
  args: ['./mcp-server.mjs'],
})
const client = new Client({ name: 'my-harness', version: '0.1.0' })
await client.connect(transport) // spawn + initialize

const { tools } = await client.listTools()
for (const t of tools) {
  // 写入 Harness 工具表
  registry.register({
    name: t.name,
    description: t.description ?? '',
    parameters: t.inputSchema ?? { type: 'object', properties: {} },
    source: { kind: 'mcp', client },
  })
}

async function executeTool(call: ToolCall): Promise<ToolResult> {
  const meta = registry.get(call.name)
  if (meta?.source.kind === 'mcp') {
    const res = await meta.source.client.callTool({
      name: call.name,
      arguments: call.arguments,
    })
    return {
      toolCallId: call.id,
      content: JSON.stringify(res.content),
      isError: Boolean(res.isError),
    }
  }
  return localHandlers[call.name](call)
}

CLient 连接是长生命周期的:

  • 启动时 new ClientconnectlistTools 注册一次工具;
  • 之后多轮 Agent Loop 里反复 callTool,复用之前的连接;
  • 一般只有 Harness 退出或用户主动停止该 Server 时才 close()

MCP 还包含 Resources 和 Prompt 能力,这块还要再下来研究一下与 Harness 的联动机制

最后

到这里 0-1 搞一个 MVP 版可跑的 Agent 应该是妥妥的了

下一篇(Part 2)大概会是以下的内容:

  1. Memory / RAG:怎么检索、何时注入、怎么裁切;准备看一下各大 Agent 框架的实现细节,和一些业界开源库对比一下效果
  2. 执行沙箱和权限管控:部分工具执行时怎么与用户项目环境隔离;工具白名单,执行权限控制等
  3. MCP 其它内容:Resources / Prompts

相关链接

润了

2026-08-01 20:56:52

润了

如题 😄 嘿嘿,7月底从 美团 离职了。

下一步

前端基本已经不需要古法手搓了,准备转 Agent 方向研究了!

顺便搞点 Agent/AI 相关项目练练手。

家人们有合适的机会也可以推一推。🫶

之前都在干什么

VitePress 产品卡片展示插件介绍

2026-07-29 17:55:45

VitePress 产品卡片展示插件介绍

笔者维护的 VitePress 博客主题 中包含一个「作品/产品卡片」的能力,可以在 markdown 里通过简单的 ::: card 容器语法快速展示项目。为便于在主题之外复用,将其抽离为独立插件 vitepress-plugin-product-card

如何使用

3 步接入:

  1. 安装
bash
pnpm add vitepress-plugin-product-card
  1. .vitepress/config.ts 中注册 markdown 容器插件
ts
import { defineConfig } from 'vitepress'
import { productCardMarkdownPlugin } from 'vitepress-plugin-product-card'

export default defineConfig({
  markdown: {
    config(md) {
      md.use(productCardMarkdownPlugin, {
        showCreated: true, // 默认 true
        showUpdated: true // 默认 true
      })
    }
  }
})
  1. .vitepress/theme/index.ts 中注册 Vue 组件
ts
import DefaultTheme from 'vitepress/theme'
import { registerProductCard } from 'vitepress-plugin-product-card/client'

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    registerProductCard(app)
  }
}

在 Markdown 中使用

md
::: card 我的产品
- title: sugar-blog
  desc: 简约风的 VitePress 博客主题
  icon: 📝
  iconColor: '#42b883'
  link: https://theme.sugarat.top
  github: https://github.com/ATQQ/sugar-blog
  tags: [VitePress, Vue3, TypeScript]
----
- title: 另一个项目
  desc: 单卡覆盖全局默认
  github: https://github.com/some/repo
  showCreated: false
:::
  • 顶部标题(::: card 我的产品)可选,不写则不渲染分组标题
  • 多张卡片之间使用 ---- 分隔
  • 每张卡片以 - title: xxx 开头

支持的字段

字段 类型 说明
title string 卡片标题(必填)
desc string 卡片描述,支持行内 markdown
icon string 图标:URL / 相对路径 → 渲染 <img>;否则渲染为字符
iconColor string 字符 icon 的背景色
link string 点击标题跳转的地址
github string GitHub 仓库地址,自动拉取创建/更新时间
tags string[] 标签数组
showCreated boolean 覆盖全局,是否展示创建时间
showUpdated boolean 覆盖全局,是否展示最后更新时间

插件参数

参数 类型 默认值 说明
showCreated boolean true 全局默认,是否展示创建时间
showUpdated boolean true 全局默认,是否展示最后更新时间
componentName string ProductCard 输出 html_block 使用的组件名,与 registerProductCard(app, name) 配合使用

@sugarat/theme 中使用

主题内置该插件,直接在文章里用 ::: card 即可。

分享一下最近 VibeCoding 的项目部署工具:Kite

2026-06-14 19:00:00

分享一下最近 VibeCoding 的项目部署工具:Kite

前言

我服务器上有几十个 Web 站点,因为服务器配置较低,都是在本地完成构建后通过 scp 推到服务器,每个项目里就维护了一个 shell 脚本。

大概下面这样:(zx 脚本)

mjs
await $`scp ${compressPkgName} ${user}@${fullOrigin}:./`

await $`ssh -p22 ${user}@${fullOrigin} "tar -xf ${compressPkgName} -C ${destDir}"`

这个样子持续了差不多好多年,但始终感觉不优雅,最近刚好 AI 够强,就把一直想实现的一个部署的 CLI 实现了。

服务器只管收 + 解压 + 重启(如果带后端服务)。

于是有了 Kite —— 装一个 CLI 就能跑起 Web 管理端 + Server 后端 + 一键上传。

快速开始

bash
npm install -g @kitecd/cli
kite serve

启动后浏览器打开 http://127.0.0.1:5431 就是管理后台。

sh
Starting Kite Server...
  Runtime: bun v1.3.12
  Host: 127.0.0.1
  Port: 5431
  Web Dir: /Users/sugar/Documents/fe/Kite/packages/cli/dist/web
  DB Dir: /Users/sugar/.kite
  Admin Token: admin_fb3635137

🦊 Server is running on bun at http://127.0.0.1:5431
🔑 Login Token: admin_fb3635137

线上部署可以通过 pm2,使用 NG 反向代理站点。

sh
kite serve --pm2

新建项目

只需要录入项目名和部署目即可

部署

项目概览页提供了部署的指令复制即可。

本地项目里执行初始化指令,生成 kite.config.json

bash
kite init --project proj_669571accfa5 --out ./dist --server http://127.0.0.1:5431 --token kt_a6029f276c354caca86b65960804d22c
sh
{
  "projectId": "proj_669571accfa5",
  "serverUrl": "http://127.0.0.1:5431",
  "outputDir": "./dist",
  "files": [
    "**/*"
  ]
}

部署,执行 kite push 即可。

kite push 会自动完成:合并配置 → 打包 outputDir → 上传到 Server → 依次执行 preDeploy / 解压 / postDeploy

bash
kite push

多环境支持

如果一个项目需要推到多个服务器或者不同项目目录。

会自动扫描符合 kite.config.xx.json 的配置。 kite push --env xx 即可,或者交互式选择。

使用的技术栈

  • 前端:Vue 3 + Vite + Pinia + Vue Router
  • 后端:Bun / Node + Elysia + libSQL(Drizzle ORM)
  • CLI: cac + ora + chalk

GPT + MiMo 一起写出来的

MiMo 完成了大概 80% 的代码,15% 是 GPT。

这个CLI服务端 支持 Bun 和 Node两个运行时,部分适配靠 GPT 搞定

流程:先使用 plan 模式把需求和实现的核心功能确定下来。

然后拆好 step ,让它挨着执行,然后配合给到的测试用例,验收一下。

然后就是 case by case 的修复问题。

最后

下一个 VibeCoding 的新坑也开好了,猛猛的蹬。

欢迎评论区交流 & 拍砖。

分享一下笔者的 Mac 装机必备软件

2026-05-06 17:04:53

分享一下笔者的 Mac 装机必备软件

碎碎念...

本周上班干活的时候,笔记本屏幕直接黑了 GG。最开始我还以为是没电了,结果插上电,重启大法试了一下,屏幕也就只会亮1s。

不过外接显示器能正常用,庆幸核心没搞坏,那 8 成是屏幕相关的问题了,就拿去维修(2周左右要),换了一台旧电脑临时用一下。(公司电脑 💻 (#^.^#))

又得从头来一遍"装机",趁此机会搞个清单,下次就不用对着旧电脑搞了。

看合集直接划到最后😋

装机必备

1. Itsycal

状态栏 日历/时间 小组件。平时排期就拿这个看时间。

还有复古的整点报时。

2. Bartender

状态栏图标管理工具。

Mac 软件装多了,顶部状态栏里 各种杂七杂八的软件图标,有些不会用到,但占用着很烦。

用这个能方便的管理哪些展示哪些不展示。

都给我去装上 (^▽^)!

3. Snipaste

简单但强大的截图工具,用了都说好!

支持剪贴板内容转图,截图钉在屏幕上,截图历史回溯,这几个我最常用的功能,。

4. Alfred

比较老牌的一个聚合工具平台。

笔者主要就用它内置的 剪贴板 功能,足够简洁,切性能比试用过的其它的专门的剪贴板软件要好。

5. Arc

Arc 浏览器,用习惯了非常方便,支持多端数据同步(不支持插件),支持多身份的设计。竖向的标签排列。

只可惜主创团队,现在不更新功能了,只更新 Chrome 内核版本,转向 Dia 的 AI 浏览器了

不过同事推荐说公司出的这个 AI浏览器也挺好用 Tabbit 浏览器,感兴趣的可以试试

6. BetterDisplay

调节显示器亮度,分辨率等非常方便。

7. Tencent Lemon

日常拿来清理一下垃圾。不然过几天 500G 的盘又满了。

办公搭子

1. BongoCat

”可爱互动的桌面宠物应用“,基于 Tauri 制作,支持三端!

鼠标和键盘的动作,猫猫都会同步。

赶紧装上,敲键盘又多了一点乐趣

2. HealthTick

久坐提醒工具。

3. Shui

全屏展示的提醒喝水的软件!。

上班安排起来,给尿喝清亮!

4. drawio

画图神器,工作中拿来画流程图架构图必备。

5. Kap

录屏软件,支持导出多种常用格式,支持基础的编辑。

使用起来非常方便,软件也是开源github:kap的。

6. Easydict

聚合翻译软件,速度也快,支持快捷唤起。

开发相关

0. Homebrew

Mac,必备,安装软件和各种终端工具。

使用知乎大佬提供的一键安装脚本

sh
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"

推荐选 Gitee 和 阿里的源。

1. Warp

强大又美观的终端工具,内置 AI 能力集成!

相较于传统的终端工具,其更加智能,编辑指令也非常方便。

2. Kiro CLI

笔者主要用这个终端输入提示的功能。

这个功能最早是在 Fig 里,后来被亚马逊收购了。

3. EasyDevo

Mac垃圾清理 & 系统监控软件,开发者友好。

系统监控 node_modules 清理 项目统计



4. uTools

聚合工具平台,笔者主要装了一些开发相关的插件。

5. Whistle Client

代理调试抓包工具!

6. IDE

笔者就常用 TRAECursor,自打AI大爆发以来,VS Code 直接不装了。

终端指令

1. fnm

Node 版本管理工具!

2. zoxide

快速切换目录的工具!

3. yrm

npm 镜像源管理。

sh
yrm ls

* npm ---- https://registry.npmjs.org/
  cnpm --- http://r.cnpmjs.org/
  taobao - https://registry.npmmirror.com/
  nj ----- https://registry.nodejitsu.com/
  rednpm - http://registry.mirror.cqupt.edu.cn/
  npmMirror  https://skimdb.npmjs.com/registry/
  edunpm - http://registry.enpmjs.org/
  yarn --- https://registry.yarnpkg.com

4. ni

sh
npm i -g @antfu/ni

常用的 ni 装依赖,nr 运行 npm 指令。

5. killport

使用 killport 可以一步到位,直接杀死占用端口的进程

其它推荐

1. Marta

文件管理软件,可以拿来替代系统默认的 Finder。支持双栏展示,移动和整理文件的时候也比较方便。

2. LocalSend

多设备之间相互传输文件。足够简单且好用。

汇总

序号 名称 介绍 链接
1 Itsycal 状态栏 日历/时间 小组件。平时排期就拿这个看时间。 https://github.com/sfsam/Itsycal/tree/master
2 Bartender 状态栏图标管理工具。 https://www.macbartender.com/
3 Snipaste 简单但强大的截图工具,用了都说好! https://www.snipaste.com/
4 Alfred 比较老牌的一个聚合工具平台。 https://www.alfredapp.com/
5 Arc Arc 浏览器,用习惯了非常方便,支持多端数据同步(不支持插件),支持多身份的设计。竖向的标签排列。 https://arc.net/
6 BetterDisplay 调节显示器亮度,分辨率等非常方便。 https://github.com/waydabber/BetterDisplay
7 Tencent Lemon 日常拿来清理一下垃圾。不然过几天 500G 的盘又满了。 https://lemon.qq.com/
8 BongoCat ”可爱互动的桌面宠物应用“,基于 Tauri 制作,支持三端! https://github.com/ayangweb/BongoCat
9 HealthTick 久坐提醒工具。 https://github.com/lifedever/health-tick-release?tab=readme-ov-file
10 Shui 全屏展示的提醒喝水的软件!。 https://github.com/rock-zhang/Shui
11 drawio 画图神器,工作中拿来画流程图架构图必备。 https://www.drawio.com/
12 Kap 录屏软件,支持导出多种常用格式,支持基础的编辑。 https://getkap.co/
13 Easydict 聚合翻译软件,速度也快,支持快捷唤起。 https://github.com/tisfeng/Easydict
14 Warp 强大又美观的终端工具,内置 AI 能力集成! https://www.warp.dev/
15 Kiro CLI 笔者主要用这个终端输入提示的功能。 https://kiro.dev/downloads/
16 EasyDevo Mac垃圾清理 & 系统监控软件,开发者友好。 https://easydevo.boringboring.design/
17 uTools 聚合工具平台,笔者主要装了一些开发相关的插件。 https://www.u-tools.cn/
18 Whistle Client 代理调试抓包工具! https://github.com/avwo/whistle-client
19 IDE 笔者就常用 TRAECursor,自打AI大爆发以来,VS Code 直接不装了。 https://www.trae.ai/https://cursor.com/
20 fnm Node 版本管理工具! https://github.com/Schniz/fnm
21 zoxide 快速切换目录的工具! https://github.com/ajeetdsouza/zoxide
22 yrm npm 镜像源管理。 https://github.com/i5ting/yrm
23 ni 常用的 ni 装依赖,nr 运行 npm 指令。 https://github.com/antfu-collective/ni
24 killport 使用 killport 可以一步到位,直接杀死占用端口的进程 https://github.com/jkfran/killport
25 Marta 文件管理软件,可以拿来替代系统默认的 Finder。支持双栏展示,移动和整理文件的时候也比较方便。 https://marta.sh/
26 LocalSend 多设备之间相互传输文件。足够简单且好用。 https://localsend.org/#/download