Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

之前体验过gemini code这个工具,谷歌还算比较友好,有token,有网络就可以用,claude code目前是个很严格,而且这家公司也对国内用户很不友好
所以就研究了下怎么把它对接上国内的模型
幸好之前deepseek发布v3.1的时候天然给了支持

1
2
3
4
5
6
7
8
## 由deepseek提供的兼容claude code的base url
export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic
## deepseek的token
export ANTHROPIC_AUTH_TOKEN={token}
## 对应的deepseek-chat模型,这个是非推理的
export ANTHROPIC_MODEL=deepseek-chat
## 快速小模型(同样可设为 deepseek-chat)
export ANTHROPIC_SMALL_FAST_MODEL=deepseek-chat

如果需要设置乘推理型的
可以把模型改成

1
export ANTHROPIC_MODEL=deepseek-reasoner

当然这个如果要长久有效得放在 .zshrc ,根据所用的shell工具来设置
然后安装claude需要node版本在18及以上

1
2
nvm use v18
npm install -g @anthropic-ai/claude-code

安装以后到想要开发的项目
运行

1
claude

接下来我们同样以todo应用作为测试应用

1
帮我写一个todo应用,使用react,ui需要尽可能美观

只是加了个美观的要求

1
2
3
4
5
6
7
8
⏺ Update Todos
⎿  ☐ Set up React project structure and dependencies
☐ Create main Todo component with state management
☐ Design and implement beautiful UI with CSS/styling
☐ Add todo functionality (add, delete, toggle complete)
☐ Test the application

⏺ Let me start by checking the current directory structure and then create the React todo application.

首先它分了五步
然后逐步运行对应的动作,生成文件等

生成的还是比较美观可用的,说明国内模型在简单的编码任务上也具有比较不错的能力了

上次是文字型的,这次我们来写点代码试试,看看效果怎么样
首先肯定是比较简单的尝试开始
写一个todo应用,主要是看能不能零改动就跑起来
用最简单的提示词
1
帮我写一个todo应用,基于react

然后就给出了代码

下面给你一个 最小可运行 的 Todo 应用示例,基于 React + Vite(如果你习惯 create-react-app,思路几乎完全一样,只是文件夹结构略有差异)。
应用包含:

组件作用
TodoInput新增条目输入框
TodoItem单个待办项(支持完成/取消、删除)
TodoList渲染 Todo 列表
TodoApp/App主容器,维护全局 todos 状态

安装依赖

1
2
3
4
npm create vite@latest todo-app --template react
cd todo-app
npm i
npm run dev

下面按文件展示完整代码(把对应文件替换或新建即可)。


1️⃣ src/main.jsx

1
2
3
4
5
6
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
import "./index.css";

createRoot(document.getElementById("root")).render(<App />);

2️⃣ src/App.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import React, { useState, useEffect } from "react";
import TodoInput from "./components/TodoInput";
import TodoList from "./components/TodoList";
import "./App.css";

/**
* 关键点:
* 1. 用 useState 存放 todos
* 2. 用 useEffect 做本地存储同步,仅在组件挂载时读取一次
* 3. 处理增删改的通用方法
*/
function App() {
const [todos, setTodos] = useState([]);

// 从 localStorage 初始化
useEffect(() => {
const stored = localStorage.getItem("todos");
if (stored) {
setTodos(JSON.parse(stored));
}
}, []);

// 每次 todos 变更时同步到 localStorage
useEffect(() => {
localStorage.setItem("todos", JSON.stringify(todos));
}, [todos]);

const addTodo = (title) => {
const newTodo = {
id: Date.now(),
title,
completed: false,
};
setTodos([newTodo, ...todos]);
};

const toggleComplete = (id) => {
setTodos((prev) =>
prev.map((t) =>
t.id === id ? { ...t, completed: !t.completed } : t
)
);
};

const deleteTodo = (id) => {
setTodos((prev) => prev.filter((t) => t.id !== id));
};

return (
<div className="app-container">
<h1>Todo List</h1>
<TodoInput addTodo={addTodo} />
<TodoList
todos={todos}
toggleComplete={toggleComplete}
deleteTodo={deleteTodo}
/>
</div>
);
}

export default App;

3️⃣ src/components/TodoInput.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import React, { useState } from "react";
import "./TodoInput.css";

const TodoInput = ({ addTodo }) => {
const [value, setValue] = useState("");

const handleSubmit = (e) => {
e.preventDefault();
const trimmed = value.trim();
if (trimmed) {
addTodo(trimmed);
setValue("");
}
};

return (
<form className="todo-input" onSubmit={handleSubmit}>
<input
type="text"
placeholder="Add a new todo..."
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<button type="submit">Add</button>
</form>
);
};

export default TodoInput;

4️⃣ src/components/TodoItem.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from "react";
import "./TodoItem.css";

const TodoItem = ({ todo, toggleComplete, deleteTodo }) => {
return (
<div className="todo-item">
<label>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleComplete(todo.id)}
/>
<span className={todo.completed ? "completed" : ""}>
{todo.title}
</span>
</label>
<button className="delete-btn" onClick={() => deleteTodo(todo.id)}>
×
</button>
</div>
);
};

export default TodoItem;

5️⃣ src/components/TodoList.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from "react";
import TodoItem from "./TodoItem";
import "./TodoList.css";

const TodoList = ({ todos, toggleComplete, deleteTodo }) => {
if (todos.length === 0) {
return <p className="empty-msg">No todos yet. Add something!</p>;
}

return (
<div className="todo-list">
{todos.map((todo) => (
<TodoItem
key={todo.id}
todo={todo}
toggleComplete={toggleComplete}
deleteTodo={deleteTodo}
/>
))}
</div>
);
};

export default TodoList;

6️⃣ src/index.css(可选,简单全局样式)

1
2
3
4
5
6
7
8
9
10
11
12
/* 让页面充满屏幕并居中 */
html, body, #root {
height: 100%;
margin: 0;
font-family: system-ui, sans-serif;
}
body {
display: flex;
justify-content: center;
align-items: flex-start;
background: #f5f5f5;
}

7️⃣ src/App.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.app-container {
width: 90%;
max-width: 480px;
background: #fff;
padding: 20px;
margin-top: 40px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
border-radius: 8px;
}

.app-container h1 {
text-align: center;
margin-bottom: 20px;
}

8️⃣ src/components/TodoInput.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.todo-input {
display: flex;
margin-bottom: 20px;
}

.todo-input input {
flex: 1;
padding: 8px 12px;
font-size: 16px;
}

.todo-input button {
padding: 8px 12px;
margin-left: 8px;
font-size: 16px;
background: #4caf50;
color: #fff;
border: none;
cursor: pointer;
}

.todo-input button:hover {
background: #45a049;
}

9️⃣ src/components/TodoList.css

1
2
3
4
5
6
7
8
9
10
.todo-list {
display: flex;
flex-direction: column;
gap: 8px;
}

.empty-msg {
text-align: center;
color: #777;
}

🔟 src/components/TodoItem.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
.todo-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
background: #fafafa;
border-radius: 4px;
}

.todo-item label {
flex: 1;
display: flex;
align-items: center;
}

.todo-item input[type="checkbox"] {
margin-right: 12px;
}

.todo-item .completed {
text-decoration: line-through;
color: #777;
}

.delete-btn {
background: transparent;
border: none;
color: #ff4444;
font-size: 20px;
cursor: pointer;
}

.delete-btn:hover {
color: #ff0000;
}

🎉 运行、打包

1
2
3
4
5
# 开发模式
npm run dev

# 生产构建
npm run build

🚀 小贴士

  • 本地存储:示例中使用 localStorage 让 Todo 在刷新后保留。生产环境可以接
    入后端或使用 IndexedDB 之类的更强大存储方案。
  • 状态管理:若项目日后变大,可考虑引入
    Redux/zustand/@tanstack/react-store 等。
  • 类型安全:使用 TypeScript 可以防止类型错误;把文件后缀改成 .tsx 并在
    package.json dependencies 增加 typescript@types/react
  • 单位测试jestreact-testing-library 能帮你保障组件逻辑正确。
  • 样式优化:考虑使用 styled-components/emotion/tailwindcss 等,让样
    式变得更易维护。

现在你就拥有一个完整、可直接跑起的 Todo React 应用,随时可以继续扩展功能(如过
滤、拖拽排序、用户登录等)。祝编码愉快 🚀!


在本地先建个应用

1
npm create vite@latest todo-app --template react

这里要注意下,要用vite的话要node版本在20.19+或者22.12+
还有是需要选择js版本,而不是ts
运行下

1
npm install

这里比较慢的话可以上镜像

1
npm config set registry https://registry.npmmirror.com

接着把生成的代码都保存成文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
├── src
│   ├── App.css
│   ├── App.jsx
│   ├── assets
│   │   └── react.svg
│   ├── components
│   │   ├── TodoInput.css
│   │   ├── TodoInput.jsx
│   │   ├── TodoItem.css
│   │   ├── TodoItem.jsx
│   │   ├── TodoList.css
│   │   └── TodoList.jsx
│   ├── index.css
│   └── main.jsx

运行命令

1
npm run dev

看到效果

结果是真的直接可用的,为什么要测这个呢,主要原因是一个模型本地可用的探讨,我认为如果是要本地可用,至少在这些相对简单的任务上能够完成得比较好,前面那个只是个提问,并没有什么可以验证正确性的,内容还是比较多的,对于做开发的来说能辅助编程还是比较重要的,并且能够完成一些相对独立完整的任务才是比较可用的初级门槛,只是对内存压力还是比较大的

openai终于履行诺言开源了自家模型,只不过不是像deepseek那样把最新最好的开源出来,而是专门调了一大一小两个模型来开源,当然也有一些技术亮点
刚好我本地是18g内存的mbp,勉强可以跑20b大小的,这次开源的有20b跟200b感觉尺寸上还是比较取巧的,20b适合个人本地使用,稍微扩下内存一般就能用了,只是速度稍慢些
官方介绍的引用

Gpt-oss-120b 模型在核心推理基准测试中与 OpenAI o4-mini 模型几乎持平,同时能在单个 80GB GPU 上高效运行。Gpt-oss-20b 模型在常见基准测试中与 OpenAI o3‑mini 模型取得类似结果,且可在仅配备 16GB 内存的边缘设备上运行,使其成为设备端应用、本地推理或无需昂贵基础设施的快速迭代的理想选择。这两个模型在工具使用、少样本函数调用、CoT推理(如在 Tau-Bench 智能体评估套件中的结果所示)以及 HealthBench 测试中表现强劲(甚至超越了 OpenAI o1 和 GPT‑4o 等专有模型)。

预训练和模型架构

gpt-oss 模型采用我们最先进的预训练和后训练技术进行训练,特别注重推理能力、效率以及在各种部署环境中的实际应用性。虽然我们已经公开发布了包括 Whisper⁠ 和 CLIP⁠ 在内的其他模型,但 gpt-oss 模型是我们自 GPT‑2[1]以来的首个开放大型语言模型。

每个模型都是一个 Transformer,它利用专家混合 (MoE[2]) 来减少处理输入所需的活跃参数数量。Gpt-oss-120b 每个令牌激活 51 亿个参数,而 gpt-oss-20b 激活 36 亿个参数。这两个模型的总参数数分别为 1,170 亿和 210 亿。这些模型采用交替的密集和局部带状稀疏注意力模式,与 GPT‑3 [3] 类似。为了提高推理和内存效率,这些模型还使用分组多查询注意力,分组大小为 8。我们使用旋转位置嵌入 (RoPE[4]) 进行位置编码,并原生支持长达 128k 的上下文长度。

模型层数总参数每个令牌的活跃参数总专家数每个令牌的活跃专家数上下文长度
gpt-oss-120b36117b5.1b1284128k
gpt-oss-20b2421b3.6b324128k

比如我本地用ollama来运行了20b大小的,

1
ollama run gpt-oss:20b

运行起来大概是占用了13g多点的内存,因为mac本身也有不少占用内存的以及我自己的一些后台运行的软件,所以比较捉襟见肘,有条件的上32g的mac mini可能比较富裕点
虽然现在ollama已经带了gui界面,但是发现运行的特别慢,直接通过命令行倒还是可以接受,比如我们问个Java相关的问题

1
>>> 怎么成为Java架构师

首先是思维过程

1
2
3
4
5
6
7
8
9
10
11
12
13
Thinking...
The user asks in Chinese: "怎么成为Java架构师" which means "How to become a Java architect?" They likely want steps, skills, learning path. Provide a thorough
guide: fundamentals, design patterns, architecture frameworks, deep dive, system design, cloud, CI/CD, soft skills, leadership, etc. Also talk about
certifications, real-world experience, project, mentorship, portfolio. Cover common architecture patterns: microservices, distributed, event-driven. Tools:
Spring, Hibernate, etc. Should also mention reading books: Clean Architecture, Domain-Driven Design, Patterns. Also cover continuous learning, speaking at
conferences, writing blogs.

Let's structure answer: introduction, prerequisites, technical skills, architectural concepts, real-world experience, soft skills, certifications, community,
portfolio, continuous learning. Provide resources and timelines. Since Chinese user, answer in Chinese. Provide details, resources links. Make it thorough. Use
bullet points for clarity.

Let's now produce final.
...done thinking.

然后就是给出结果,体感是个位数token每秒的输出速度

以下就是生成的内容

目标:成为一名 Java 架构师

架构师不是一次获得“技术标签”,而是一种综合的 设计思维业务洞察 的能力。

下面给你一条完整、可量化的路线图,帮助你从“有经验的 Java 开发者”成长为 架构师

小贴士:如果你手头已有 3–5 年的项目经验,就可以直接对应后面的“实战经验”板块。如果你刚起步,建议先走“技术打底”阶段,然后再投身实战。


一、技术打底(1–2 年)

目标必备技术 / 书籍 / 练手练习建议
Java 基础Java SE 8+(lambda, stream, JPA 等)先练手 OOP、设计模式、并发,做 Leetcode、练下 JDK 内部实现(如 ArrayListHashMap
框架Spring Framework(MVC、AOP)、Spring Boot、Spring Cloud、Spring Data JPA搭建多层 CRUD + MVC + Security + Redis + MySQL 的完整项目
ORMHibernate / JPA写复杂的查询,掌握 Fetch 策略、缓存、懒加载
数据库关系型(MySQL/PostgreSQL) + NoSQL(MongoDB / Redis)学习分库分表、事务、读写分离
安全OAuth2 / JWT / Spring Security单独做一套认证系统
单元测试JUnit、Mockito代码覆盖率≥90%
CI/CDGit, Maven/Gradle, Docker, Jenkins/GitHub Actions自动化构建、单元/集成测试、镜像推送
监控Micrometer + Prometheus + Grafana / ELK记录度量、日志、告警
微服务Spring Cloud(Nacos/Spring Cloud Config + Eureka/Consul + Zuul/Gateway + Hystrix)搭建 3‑5 个小服务,练习服务间调用与降级
消息中间件Kafka / RabbitMQ读写队列,练习发布/订阅,事务与回滚
分布式事务Saga、TCC、XA通过 Spring Transaction、Atomikos 练习

学习资源(中文 / 英文)

主题书籍课程文章 / 官网
Java《Java 编程思想》, 《深入理解 Java 虚拟机》《Java 8+ 入门与进阶》(慕课, 极客时间)Oracle JDK 官网, 《Effective Java》解读
Spring《Spring 实战 5》, 《Spring Cloud 实战》Spring 官方培训,Bilibili / 慕课Spring 官网 & Spring Cloud 官网
微服务《微服务设计》, 《Domain-Driven Design》《Spring Cloud 全栈》(极客时间)微服务架构图 (Zhou’s blog, DZone)
大数据 / Kafka《Kafka 权威指南》《Kafka 入门 & 进阶》Apache Kafka 官网
系统设计《系统架构设计》, 《分布式系统设计之道》《系统设计基础》课程阿里云、腾讯云白皮书

练手项目:做一个 电商平台社交系统,分拆为多个服务:用户服务、商品服务、订单服务、支付服务、物流服务等。通过实现 **统一鉴权、限流、熔断、日志聚合
**,让自己彻底体验架构层面的痛点。


二、系统设计能力(3–5 年经验)

1. 业务需求分析

  • 痛点:业务需求往往是模糊、频繁变动的,架构师需要把业务拆解为 核心能力边缘功能
  • 实践:每月挑选一个业务点(如优惠券、库存预警等),写 1–2 页面需求文档,然后把需求拆解成 业务领域模型

2. 设计模式与架构模式

类别经典模式示例
业务层领域模型 (Domain Model), 领域事件 (Domain Event)商品模块使用领域事件实现库存同步
持久层DAO, Repository, Unit of WorkJPA Repository + UnitOfWork
基础设施适配器 (Adapter), 代理 (Proxy), 桥接 (Bridge)用 Feign+Ribbon 代理调用第三方支付
核心架构微服务, 事件驱动, Command Query Responsibility Segregation (CQRS), Event Sourcing, Saga微服务 + Kafka
运行时延迟策略 (Retry), 熔断 (Circuit Breaker), 限流 (Limiter), 负载均衡 (LoadBalancer)Hystrix + Ribbon + Sentinel

书单

  • 《Design Patterns》 经典翻译版
  • 《架构师的选型与设计》
  • 《系统架构师的自我修养》
  • 《大规模分布式系统架构》(阿里巴巴架构师经验分享)

3. 云原生技术

  • 容器: Docker、Kubernetes;自研或使用 OpenJDK + JDK 21
  • 服务网格:Istio/Linkerd。
  • CI/CD:ArgoCD + Jenkins。
  • 自动化:Helm、Terraform、Ansible。
  • 云服务:Aliyun、AWS、Azure,熟悉至少一个云的部署与运维。

4. 监控、日志、运维

  • 分布式追踪:OpenTelemetry + Zipkin/Jaeger。
  • AIOps:使用 Prometheus + Grafana,结合 Alertmanager。
  • 日志:ELK、Loki,或 OpenTelemetry Log

5. 软技能 & 团队协作

领域关键能力学习路径
产品思维理解业务目标、价值主张与 PO、BA 讨论,用业务故事拆解
沟通需求梳理、技术方案说明每周至少 1 次技术分享或午餐会
领导组内技术指导、冲刺规划作为 scrum master 或技术负责人
安全 & 合规数据加密、GDPR/HIPAA学习安全框架、法规手册
成本管理云成本、容量规划通过 Cloud Cost Estimator 评估

练习:把上面 4 大主题写成 PPT,给同事做一个半小时的技术分享,随后收集反思与改进。


三、职业路线(5-10 岁经验)

阶段目标关键步骤
技术负责人完成 3–5 个核心模块的技术方案按模块负责并交付。
架构师对整个平台制定 技术愿景、技术选型、非功能性指标1)制定技术路线图;2)做安全、数据治理、成本管控。
架构顾问对多家企业/业务线提供架构咨询。参与技术评审、代码走查、培训。
高层 CxO(CTO/VP)负责技术战略、团队治理。培养团队、构建技术生态。

核心任务

  • 选型:在技术评估、成本评估、稳定性、社区支持等要素上做出决策。
  • 方案落地:把抽象设计写成 可执行的计划
  • 治理:制定 编码规范CI/CD 标准安全策略成本追踪
  • 治理工具:使用 ArgoRolloutsHelmOPA(Open Policy Agent)来实现自动化治理。

四、推荐路线图(时间轴示例)

月份阶段关键任务
1–6Java 基础 & Spring Boot1 个 CRUD 项目
7–12中间件 & 微服务3 个微服务 + 统一鉴权
13–18系统设计 & DDD业务拆解、领域模型
19–24分布式 & 缓存Kafka、Redis、分布式事务
25–36云原生 & 运维Kubernetes + Prometheus + Zipkin
37–48设计模式 & 框架事件驱动、Saga、CQRS
49–60软技能 & 领导组内技术分享、技术评审
60+架构师制定技术愿景、治理

关键点每个阶段都要有交付。写好技术文档、代码库、可复现的 demo,让别人能够看到你“解决了什么”而不是仅仅“看懂你说了些什么”。


五、实战案例 / 经验总结

  1. 从业务痛点出发
    • 痛点:订单系统的并发高峰导致库存穿透。
    • 方案:采用 Redis 分布式锁 + 限流,把订单请求拆成两部分:下单 + 支付确认。
    • 结果:库存一致性恢复,系统 QPS 提升 200%。
  2. 选型要有成本意识
    • 评估 AWS vs 阿里云:计算预计 8 万/年与 6 万/年,选阿里云。
    • 在选型后做 性能基准(LTP测试)来验证业务水平。
  3. 保持“可审计”
    • 在微服务中加入 OpenTelemetry,把日志、指标、追踪统一到 ELK。
    • 业务日志采用 业务日志表,可以跟踪数据脏读与回滚路径。
  4. 持续学习
    • 每周至少读 1 次技术文章(Hacker News、InfoQ、阿里巴巴技术分享)。
    • 每年至少读 2 本系统架构书籍,把知识写进 技术笔记

六、如何验证自己的能力?

验证方式说明
技术博客 / 公开课发布 8+ 篇系统设计技术文章,完成 1 次公开技术分享。
GitHub 项目至少 3 个真实业务项目或开源项目,PR 贡献。
项目验收记录给同事或客户交付至少 2 次业务改造。
面试评估Top 技术平台(猎聘、BOSS 直聘)上,面试 “架构师” 级别。
认证Oracle Certified ProfessionalAWS Certified Solutions Architect – Professional阿里云架构师认证 等。

面试题准备

  • 业务场景 → 需求分析 → 系统架构 → 数据模型 → 性能方案 → 监控与运维 → 失败模式与可恢复性
  • 经典面试题:
    • 给定 100 个并发用户 同时下单,怎么防止库存穿透?
    • 如何实现微服务之间的 幂等调用
    • 解释“CAP定理”并给出符合业务的解决方案。

七、最后的实戰建議

  1. 先学会 “怎么写代码”,再学 “怎么设计架构”。
    • 把代码质量放在首位:单元测试、代码评审、CI/CD。
  2. 与业务同事保持紧密沟通,避免 “技术孤岛”。
  3. 学习:架构师不只是技术,更是 业务、合规、成本 的统筹者。
  4. 保持好奇心:阅读每季度的 技术白皮书(阿里巴巴、腾讯、Google、Microsoft)。
  5. 培养 “反脆弱” 思维:系统设计不是一次性完成的,而是 持续演进
  6. 分享:通过技术分享会、博客或社区演讲,把自己的知识体系和思维体系固化。

结语
成为 Java 架构师是一段 从 “熟练编码” → “系统设计” → “业务与技术双栖” 的成长旅程。只要你把每一步拆解成可执行的目标,系统练习并且用落地项目检验自己的能力,就
能稳扎稳打地迈向架构师角色。祝你早日成为团队里的架构引路人!

如果你想进一步细化任何一板块(如某个具体的技术选型、微服务拆分方案,或是面试技巧),随时告诉我!祝你编码愉快 🚀✌️

内容正确性仅供参考
只是输出的质量体感可能赶得上最初版的chatgpt了,按这种效果本地用来做一些辅助工作的能力感觉是够用了。根据官方的测评20b的模型也是超过了o3-mini,主要是目前的内存占用还比较吃力对我来说,如果是32g内存的话应该就比较舒服了,也期待会有更小的且效果不输于gpt-oss:20b的模型,本地的模型使用就会越来越普遍且好用

上周被spring-ai调用模型api这个折腾的有点难受,这周又试了下用deepseek官方的api,但结果还是一样,不确定是啥原因,请求会一直卡着
后来想着本地有ollama,那是不是可以直接用ollama来调本地模型
这里我们用一个非常基础很小的模型

1
ollama run gemma3:1b

然后对应的配置是

1
2
3
4
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>

当然这里有个坑,因为目前还不成熟,所以这个包的依赖跟之前openai的是不兼容的
需要引用

1
2
3
4
5
6
7
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.0-M1</version>
<type>pom</type>
<scope>import</scope>
</dependency>

属性配置就很简单了

1
2
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.chat.model=gemma3:1b

然后就是简单写个Controller就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
@RequestMapping("/demo")
public class OllamaController {
private static final Logger logger = LoggerFactory.getLogger(OllamaController.class);

@Autowired
private OllamaChatModel ollamaChatModel;


@RequestMapping("/ollama")
public Object ollama(String msg) {
String call = ollamaChatModel.call(msg);
return call;
}
}

这样我们的初始调用就完成了
比如我们提问 ‘how to learn java’

1
Okay, let's break down how to learn Java! It can seem daunting at first, but with a structured approach, you'll be coding in Java in no time. Here’s a breakdown of a recommended learning path, broken down into phases: **1. Foundation (2-4 Weeks)** * **Understand the Basics:** * **What is Java?** Java is a robust, object-oriented programming language known for its platform independence ("write once, run anywhere"). It’s used for enterprise applications, Android development, and more. * **Why Learn Java?** It’s a popular choice for beginners because it’s relatively easy to learn, has a large community, and is used in many real-world applications. * **Key Concepts:** * **Variables & Data Types:** Understand different data types (int, float, String, boolean, etc.). * **Operators:** Arithmetic, comparison, logical, assignment. * **Control Flow:** `if`, `else`, `for`, `while` – controlling the flow of your program. * **Basic Syntax:** The code structure of Java. * **Resources:** * **Tutorialspoint Java Course:** [https://www.tutorialspoint.com/java/index.htm](https://www.tutorialspoint.com/java/index.htm) - A good, comprehensive, and free overview. * **Codecademy's Learn Java:** [https://www.codecademy.com/learn/learn-java](https://www.codecademy.com/learn/learn-java) - Interactive, hands-on exercises. * **Google's Java Tutorial:** [https://developer.android.com/training/jdbc](https://developer.android.com/training/jdbc) (Java is built on JDBC, so this will give you a baseline) **2. Core Concepts (4-8 Weeks)** * **Data Structures:** * **Arrays:** Fundamental data structures. Understand how to declare, initialize, and use arrays. * **Linked Lists:** Another essential data structure, offering flexibility. * **Object-Oriented Programming (OOP) Fundamentals:** * **Classes and Objects:** The basis of OOP. Learn how to define classes, create objects, and interact with them. * **Encapsulation:** Bundling data and methods that operate on that data within a class. * **Inheritance:** Creating new classes based on existing classes. * **Polymorphism:** The ability of objects to take on many forms. * **Java Syntax & Semantics:** * **Statements:** The commands you write. * **Expressions:** Results of calculations. * **Keywords:** Reserved words with special meanings (e.g., `class`, `if`, `else`). * **Comments:** Explain your code. * **Resources:** * **Oracle Java Tutorials:** [https://docs.oracle.com/javase/tutorial/](https://docs.oracle.com/javase/tutorial/) – A more in-depth guide. * **FreeCodeCamp's Java Tutorial:** [https://www.freecodecamp.org/learn/java-tutorial/](https://www.freecodecamp.org/learn/java-tutorial/) - Great for visual learners. **3. Practical Application - Projects** * **Simple Programs:** Start with small, manageable projects: * **Number Guessing Game:** A classic introductory project. * **Rock-Paper-Scissors:** A basic example of OOP. * **Simple Calculator:** Reinforces fundamental concepts. * **Gradually Increase Complexity:** * **Print Statements:** A simple way to understand output. * **Palindrome Checker:** A challenge to practice string manipulation. * **Basic Console Applications:** Write programs that run directly in the console. **4. Intermediate Concepts (Ongoing)** * **Exception Handling:** Understanding and handling errors. * **Collections:** Learn about ArrayLists, LinkedLists, Sets, and Maps. * **String Manipulation:** Working with strings effectively. * **Multithreading:** Understanding how to run multiple tasks concurrently (basic concepts). * **Java Collections Framework:** The cornerstone of modern Java programming. **Resources for Continued Learning:** * **Stack Overflow:** [https://stackoverflow.com/](https://stackoverflow.com/) - An invaluable resource for solving coding problems and learning from others. * **Reddit's r/java:** [https://www.reddit.com/r/java/](https://www.reddit.com/r/java/) - A community forum with discussions and resources. * **YouTube:** Search for Java tutorials and courses (e.g., "Java for beginners"). **Tips for Success:** * **Practice Regularly:** Even 30 minutes a day is better than long, infrequent sessions. * **Write Code Frequently:** The more you write, the better you'll understand. * **Don't Be Afraid to Make Mistakes:** Mistakes are part of the learning process. Learn from them. * **Read Code:** Look at code written by others to understand different approaches. * **Join a Community:** Connecting with others can provide support and motivation. **To help me tailor my advice even more, could you tell me:** * **What's your background in programming?** (e.g., Have you programmed before? If so, what languages?) * **What are your goals for learning Java?** (e.g., Career change? Personal project? Specific application like Android?)

格式不太美观,但是至少是能输出来结果了,而且可以选择本地可用的最佳模型,话说openai的oss试了下,本地有点吃不消,不然可能是比较合适的

之前经常看一些LLM的工具,类似于ollama,chatbox等等,这些都类似于是个独立工具,真的在代码里使用的话可能没那么方便
正好看了下spring有个spring-ai的包,可以来使用试下
首先我们要用比较新的jdk版本,比如jdk17,然后需要使用springboot比较新的版本,比如3.2.3,但是不建议使用最新稳定版,3.4.x,因为会有bug,别问我怎么知道的。
真的是折腾,
简单分享下吧
需要在pom中增加仓库定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 仓库定义 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>

然后增加依赖

1
2
3
4
5
6
7
8
9
10
11
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.0-M5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

引入主要的几个包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>

代码也很简单,但是不确定是api限流太严重还是啥,响应慢的离谱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@RestController
public class ChatController {

private final ChatClient chatClient;

public ChatController(ChatClient.Builder builder) {
this.chatClient = builder.defaultSystem("你是个资深服务端架构师").build();
}

@GetMapping("/demo/{message}")
public String demo(@PathVariable("message") String message) {

message = "怎么学习java";
String response = chatClient.prompt()
.user(message)
.call().content();

return response;
}
}

对的,甚至把prompt写死了

这里经过了好几个包版本的调整
原先比较早的0.8的不支持接口的自定义路径,因为要用火山的接口,它的接口跟openai是不一样的,后面有个v3啥的
所以需要增加最下面一行

1
2
3
spring.ai.openai.base-url=https://ark.cn-beijing.volces.com/api/v3
spring.ai.openai.chat.options.model=deepseek-r1-250120
spring.ai.openai.chat.completions-path=/chat/completions

但是可以从上面的图里看出来,响应非常慢,简直不能忍,有openai 权限的可以帮忙试下究竟是啥原因,抓包啥的也不太方便

0%