利用 Github Models 免费使用 GPT-4o 和 GPT-4o mini

751 阅读9分钟

首先假定你们了解并正常使用 Github,不然建议先了解后再做此配置

0. 目的

  • 可以使用原生的 openai 提供的 GPT-4o 和 GPT-4o mini 模型
  • 具体次数可参考官方使用限制,免费用户每天可使用一定数量,4o 模型一天约 50 次调用,4o-mini 每天约 150 次调用
  • 一点对接 Github Models 的 Azure 提供模型的设计思路,方便让 AI 为自己编写代码,供前端小白参考

1. 资格申请

Github

  • 首先你要有一个 Github 账号,如果没有,请先申请
  • Github Model 申请 github.com/marketplace…,步骤如下图所示
  • 通过之后,可见图片3,可点其中一个模型 OpenAI GTP-4o
  • 进入之后,点 Get Started → 按要求创建 Github Token

2. 如何使用

之前有用 nodejs 写一个本地化的启动脚本,考虑到对一些人来说不实用,就改用在 uTools 发布插件了,比较纯净。

通过 uTools

  • 打开插件应用市场,搜索《HI AI》下载即可

3. 说在后面

这套页面本身是全程使用 AI 来搭建的,全程自己的编码量小于 30%,如有兴趣。希望 AI 能给你们工作生活带来帮助。

4. 灵感来源

5. 开发思路

【注:以下开始,都是在从 AI 编码方面讲技术思路,有兴趣可以看看】

模块划分

按自己常用的各类 AI 模型的 web 页面,自己把功能划分为如下几块

  • TOKEN 设置功能
  • 会话管理
  • 聊天窗口
  • 发送窗口
  • 辅助功能(导出等)

API 设计

由于本地启动供他人使用会比较麻烦,故做成 uTools 工具的一个插件使用,使用 uTools 提供的 nodejs 能力,和 uTools 提供的本地数据库

  • uTools DB 提供如下:
    • GITHUB_TOKEN 的存储
    • 会话列表(不涉及网络传输,为了数据简单处理,消息直接存会话里面)
  • 方法设计
    • githubToken()、获取、设置 githubToken
    • session()、获取、设置 session
    • queryAnswer()、获取 AI 的答复

6. 开发设计

主进程 / 客户端(uTools)

  • 数据库格式
// token
utools.db.put({
  _id: 'tokens',
  githubToken: 'string',
})
// sessions
utools.db.put({
  _id: 'sessions',
  sessions: { 
    1726928423680 :{ // 会话ID
      id: 'number', // Date().now
      name: 'string',
      messages: [{
        role: 'user', // system, user, assistant
        model: 'gpt-4o', // gpt-4o, gpt-4o-mini
        message: 'string',
        steam: false, // 是否流式输出
      }],
    },
  },
})
  • 和渲染进程交互
window.utools = {
  // 复制
  copyText: text => utools.copyText(text),
  
  // 默认浏览器打开链接
  shellOpenExternal: url => utools.shellOpenExternal(text),

  // 操作数据库
  db: utools.db,
  
  queryAnswer: openai.queryAnswer, // 对接 Azure 提供的 api   
}

渲染进程(Web)

  • TOKEN 设置功能
    • 支持设置、修改
  • 会话管理
    • 支持会话的增、删、改
    • 按 id(时间)排序
  • 聊天窗口
    • 支持三种对话显示,会话 propmt,问,AI 回答
    • 支持 markdown 展示
    • 支持展示图片
    • 考虑 code 过长的换行处理
    • 支持点击链接跳转默认浏览器(uTools 内默认不支持)
  • 发送窗口
    • 可以选择 AI 回答的模型,默认 gpt-4o-mini
    • Shift + Enter 发送
  • 辅助功能
    • 导出 markdown 格式到电脑

编码

先这样写、再那样、最后这样,代码就写好了,在前端工程师的眼里,页面样式转成代码,不就像切图仔切图一样流畅。

开个玩笑,这个项目主题是什么,怎么丝滑使用 AI,代码肯定不能全自己写了。

选项目框架

首先打开老朋友 Cursor 编辑器。把项目基座建好,这里我们使用 svelte,简单丝滑。

关于怎么使用 Cursor 写代码,这里不过多介绍,仅展示两组,B 站上本身很多介绍视频推荐大家去学习,这里仅让大家了解有这样一个东西,希望 AI 给大家编程带来更多的帮助,感谢大家阅读~

  • 开始编写 propmt,我选的模型是 claude-3.5-sonnet 第一次尝试,按自己想法写,先让 AI 写整体框架,不涉及太细的东西
我需要你帮忙写一个页面,页面细节如下,我提几点要求,结构清晰,样式要尽量好看
1. 有一个初始页面,这个页面内容有
	1.1 加一个确认按钮,确认成功调用 createGithubToken() 方法,暂先把这个 token 保存在 localstorage 里面
	1.2 每次进入页面先检查有没有这个token,没有就展示设置页,有的话就先不展示这个初始页,直接进入正常页面
	1.3 在正常页面,可以点击修改TOKEN 重新进入到这个初始页面,并会在确定旁边多一个取消按钮,点击回到正常页面
2. 正常页面
	2.1 如果有 token,则直接进入正常页面
  2.2 首先页面分为左右两个区域,左边区域宽度在200px左右,右侧自适应,左侧需要有一个按钮,可以展开和收缩
  2.3 左侧上方有一个修改 GITHUB_TOKEN 的按钮,点击之后就回到首次进入的初始页面。有取消按钮,可以回到正常页面。
  2.4 左侧的接下来需要有会话列表(sessions),会话列表显示会话的名字(name),这个鼠标悬浮到上面需要有 hover 效果,hover时右边出现两个小icon,可以修改会话名称(name),还有一个是删除会话的功能
  2.5 右侧上面是主体模块,是消息列表,是选中的其中一个会话里面的聊天信息,和通常的聊天软件一样,自己说的话在右边展示,AI说的话在左边展示,会话都要在气泡里面,让样式好看一点,可以参照微信或iMessage
  2.6 右侧下面是一个发送框,需要有两个元素,一个 textarea,一个发送按钮
  • AI 帮忙把页面写出来了,并有如下回复,但目前的样式,很简陋,并且有一些别的问题,只能让 AI 一步一步去修复
好的,我来帮您设计这个页面。以下是一个基本的 Svelte 组件实现,包含了您描述的主要功能和布局:

# svelte:renderer/src/routes/+page.svelte

<script>
  import { onMount } from 'svelte';
  import { fade, slide } from 'svelte/transition';
  
  let token = '';
  let showInitialPage = true;
  let sessions = [];
  let selectedSession = null;
  let messages = [];
  let newMessage = '';
  let showLeftPanel = true;

  onMount(() => {
    token = localStorage.getItem('github_token');
    if (token) {
      showInitialPage = false;
    }
  });

  function createGithubToken() {
    // 调用 createGithubToken() 方法
    token = 'new_token'; // 假设这是返回的 token
    localStorage.setItem('github_token', token);
    showInitialPage = false;
  }

  function modifyToken() {
    showInitialPage = true;
  }

  function cancelModifyToken() {
    showInitialPage = false;
  }

  function toggleLeftPanel() {
    showLeftPanel = !showLeftPanel;
  }

  // 其他功能函数...

</script>

<main>
  {#if showInitialPage}
    <div class="initial-page" transition:fade>
      <h2>设置 GitHub Token</h2>
      <input type="text" bind:value={token} placeholder="输入你的 GitHub Token">
      <button on:click={createGithubToken}>确认</button>
      {#if !showInitialPage}
        <button on:click={cancelModifyToken}>取消</button>
      {/if}
    </div>
  {:else}
    <div class="main-page">
      <div class="left-panel" class:hidden={!showLeftPanel} transition:slide={{duration: 300}}>
        <button on:click={modifyToken}>修改 GITHUB_TOKEN</button>
        <button on:click={toggleLeftPanel}>收起/展开</button>
        <div class="sessions-list">
          <!-- 会话列表 -->
        </div>
      </div>
      <div class="right-panel">
        <div class="messages-container">
          <!-- 消息列表 -->
        </div>
        <div class="input-area">
          <textarea bind:value={newMessage} placeholder="输入消息..."></textarea>
          <button>发送</button>
        </div>
      </div>
    </div>
  {/if}
</main>

<style>
  main {
    width: 100%;
    height: 100vh;
    display: flex;
  }

  .initial-page {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .main-page {
    display: flex;
    width: 100%;
  }

  .left-panel {
    width: 200px;
    border-right: 1px solid #ccc;
    transition: width 0.3s;
  }

  .left-panel.hidden {
    width: 0;
    overflow: hidden;
  }

  .right-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
  }

  .messages-container {
    flex: 1;
    overflow-y: auto;
    padding: 20px;
  }

  .input-area {
    display: flex;
    padding: 10px;
  }

  .input-area textarea {
    flex: 1;
    margin-right: 10px;
  }

  /* 添加更多样式... */
</style>


这个基本结构实现了您描述的主要功能:

1. 初始页面和正常页面的切换
2. GitHub Token 的设置和存储
3. 左右分栏布局,左侧可收缩
4. 修改 Token 的功能
5. 消息列表区域和输入区域的基本布局

您需要进一步完善以下部分:

1. 实现会话列表的渲染和交互
2. 添加会话的编辑和删除功能
3. 实现消息列表的渲染,区分自己和 AI 的消息
4. 添加发送消息的功能
5. 优化样式,使其更美观

建议您逐步实现这些功能,并根据需要调整样式。如果您需要某个特定部分的详细实现,请告诉我,我会为您提供更具体的代码。
  • 先修复几个明显问题,我提给它
首先先解决第几个问题,
问题1:从初始页面到正常页面切换过程很丑,会有线动来动去,需要去掉这个过程或者让他更淡化美观一点。
问题2:在我侧边栏收起了之后,我没办法展开,需要调整一下收起展开按钮位置,这个最好能用svg图标,好看一点
  • AI回复,并且建议修改代码,我这也直接接受它的建议(因为我并不想自己写)
好的,我理解您的问题。让我们来解决这两个问题。

1. 优化页面切换动画
2. 调整侧边栏收起/展开按钮的位置和样式

以下是修改后的代码:

# svelte:renderer/src/routes/+page.svelte
<script>
  import { onMount } from 'svelte';
  import { fade } from 'svelte/transition';
  
  // ... 其他变量保持不变

  let showLeftPanel = true;

  onMount(() => {
    token = localStorage.getItem('github_token');
    if (token) {
      showInitialPage = false;
    }
  });

  // ... 其他函数保持不变

  function toggleLeftPanel() {
    showLeftPanel = !showLeftPanel;
  }
</script>

<main>
  {#if showInitialPage}
    <div class="initial-page" transition:fade={{duration: 300}}>
      <h2>设置 GitHub Token</h2>
      <input type="text" bind:value={token} placeholder="输入你的 GitHub Token">
      <button on:click={createGithubToken}>确认</button>
      {#if !showInitialPage}
        <button on:click={cancelModifyToken}>取消</button>
      {/if}
    </div>
  {:else}
    <div class="main-page" transition:fade={{duration: 300}}>
      <div class="left-panel" class:hidden={!showLeftPanel}>
        <button on:click={modifyToken}>修改 GITHUB_TOKEN</button>
        <div class="sessions-list">
          <!-- 会话列表 -->
        </div>
      </div>
      <div class="toggle-button" on:click={toggleLeftPanel}>
        <svg viewBox="0 0 24 24" width="24" height="24">
          <path d={showLeftPanel ? "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" : "M10.59 6L12 7.41 8.83 12 12 16.59 10.59 18l-6-6z"} />
        </svg>
      </div>
      <div class="right-panel">
        <div class="messages-container">
          <!-- 消息列表 -->
        </div>
        <div class="input-area">
          <textarea bind:value={newMessage} placeholder="输入消息..."></textarea>
          <button>发送</button>
        </div>
      </div>
    </div>
  {/if}
</main>

<style>
  main {
    width: 100%;
    height: 100vh;
    display: flex;
  }

  .initial-page, .main-page {
    width: 100%;
    height: 100%;
  }

  .initial-page {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .main-page {
    display: flex;
    position: relative;
  }

  .left-panel {
    width: 200px;
    border-right: 1px solid #ccc;
    transition: width 0.3s, margin-left 0.3s;
    overflow: hidden;
  }

  .left-panel.hidden {
    width: 0;
    margin-left: -200px;
  }

  .toggle-button {
    position: absolute;
    left: 200px;
    top: 50%;
    transform: translateY(-50%);
    background-color: #f0f0f0;
    border: 1px solid #ccc;
    border-left: none;
    padding: 10px 5px;
    cursor: pointer;
    transition: left 0.3s;
    z-index: 10;
  }

  .left-panel.hidden + .toggle-button {
    left: 0;
  }

  .right-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
  }

  .messages-container {
    flex: 1;
    overflow-y: auto;
    padding: 20px;
  }

  .input-area {
    display: flex;
    padding: 10px;
  }

  .input-area textarea {
    flex: 1;
    margin-right: 10px;
  }

  /* 添加更多样式... */
</style>

这些修改解决了您提到的两个问题:

1. 页面切换动画:我们只使用了 `fade` 过渡效果,并将持续时间设置为 300 毫秒。这样可以使过渡更加平滑和淡化。

2. 侧边栏收起/展开按钮:
   - 添加了一个新的 `toggle-button` 元素,它始终可见。
   - 使用 SVG 图标来表示展开/收起状态。
   - 按钮位置会随着侧边栏的状态而改变。

这些更改应该能够改善用户体验,使页面切换更加流畅,并且在侧边栏收起时仍然可以轻松地展开它。

如果您还有其他需要调整或改进的地方,请告诉我,我会继续帮您优化代码。