HTML 之 ollama流式API客户端 -完整版

Ollama完整教程:本地LLM管理、WebUI对话、Python/Java客户端API应用 Ollama可以非常方便的管理和部署我们本地大语言模型,老牛同学希望通过本文对Ollama进行一次详细介绍,包括本地大模型管理和使用、WebUI对话界面部署、通过Python和Java使用Ollama的API接口等…… 阅读详情

环境变量设置如下:

set OLLAMA_HOST=0.0.0.0:11434
set OLLAMA_ORIGINS=*

ollama流式API客户端

<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="UTF-8">
		<!-- 添加viewport标签确保移动端正确缩放 -->
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>AI-聊天模式</title>
		<style>
			body {
				font-family: 'Segoe UI', Arial, sans-serif;
				background: #f0f2f5;
				margin: 0;
				min-height: 100vh;
				/* 改为min-height避免内容溢出 */
				display: flex;
				justify-content: center;
				align-items: center;
			}

			.container {
				width: 95vw;
				/* 增加宽度占比 */
				height: 95vh;
				display: flex;
				flex-direction: column;
				gap: 10px;
				/* 缩小间隙 */
				padding: 5px;
				/* 添加内边距 */
			}

			#output {
				flex: 1;
				width: calc(100% - 10px);
				/* 考虑内边距 */
				min-height: 50%;
				padding: 12px;
				font-size: 16px;
				/* 增大字体 */
				border: 2px solid #e3e8ee;
				border-radius: 6px;
				background: white;
				resize: none;
				overflow-y: auto;
				/* 确保滚动条可用 */
			}

			.input-group {
				display: flex;
				flex-direction: column;
				/* 改为垂直布局 */
				gap: 8px;
				height: auto;
				/* 自动高度 */
			}

			#input {
				width: calc(100% - 10px);
				min-height: 80px;
				/* 更适合移动端的高度 */
				padding: 10px;
				font-size: 16px;
				border: 2px solid #e3e8ee;
				border-radius: 6px;
				resize: vertical;
				/* 允许垂直调整 */
			}

			button {
				padding: 12px 20px;
				background: #007bff;
				color: white;
				border: none;
				border-radius: 6px;
				font-size: 16px;
				cursor: pointer;
				transition: background 0.2s;
				touch-action: manipulation;
				/* 优化触摸响应 */
			}

			/* 新增按钮容器样式 */
			.button-row {
				display: flex;
				gap: 8px;
				width: 100%;
			}

			/* 发送按钮宽度设置 */
			button[onclick="sendMessage()"] {
				flex: 1;
				/* 占据剩余空间 */
				width: 80%;
			}

			button:active {
				background: #0056b3;
			}

			/* 新增图标按钮样式 */
			button.icon-button {
				padding: 12px;
				width: 20%;
				min-width: 60px;
				background: #28a745;
				display: flex;
				justify-content: center;
				align-items: center;
			}

			/* 调整按钮组间距 */
			.button-group {
				display: flex;
				gap: 8px;
				margin-top: 8px;
			}

			.icon-button {
				position: relative;
			}

			/* 喇叭图标样式 */
			.icon-button svg {
				width: 24px;
				height: 24px;
				fill: white;
				transition: opacity 0.3s;
			}

			.icon-button .off-icon {
				position: absolute;
				opacity: 0;
			}

			/* 激活状态 */
			.icon-button.active .on-icon {
				opacity: 0;
			}

			.icon-button.active .off-icon {
				opacity: 1;
			}

			/* 颜色变化 */
			.icon-button.active {
				background: #dc3545;
			}

			/* 手机端响应式调整 */
			@media (max-width: 480px) {
				.container {
					width: 100vw;
					height: 100vh;
					padding: 5px;
				}

				#output {
					font-size: 15px;
					padding: 10px;
				}

				#input {
					font-size: 15px;
					min-height: 70px;
				}

				button {
					padding: 15px 20px;
					/* 增大点击区域 */
					font-size: 15px;
				}

				button.icon-button {
					padding: 10px;
					width: 44px;
				}

				.icon-button svg {
					width: 22px;
					height: 22px;
				}

				.tab-buttons {
					gap: 4px;
					padding-bottom: 6px;
				}

				.tab-button {
					padding: 6px 12px;
					font-size: 13px;
				}

				.file-input-wrapper {
					max-width: 100%;
					min-width: 60px;
				}

				.file-input-button {
					padding: 10px;
					height: 40px;
					border-radius: 4px;
				}

				.file-input-button svg {
					width: 22px;
					height: 22px;
				}
			}

			/* 高对比度模式适配 */
			@media (prefers-contrast: more) {
				.file-input-button {
					border: 2px solid currentColor;
				}
			}

			#fileInput {
				position: absolute;
				opacity: 0;
				width: 100%;
				left: 0;
				top: 0;
				width: 100%;
				height: 100%;
				cursor: pointer;
				z-index: 1;
				-webkit-tap-highlight-color: transparent;
			}

			.file-input-wrapper {
				position: relative;
				display: inline-block;
				flex: 1;
				max-width: 120px;
				min-width: 80px;
				touch-action: manipulation;
			}

			.file-input-button {
				padding: 12px;
				background: #6c757d;
				color: white;
				border-radius: 6px;
				position: relative;
				z-index: 0;
				display: flex;
				justify-content: center;
				align-items: center;
				width: 100%;
				border: 1px solid #dee2e6;
				transition:
					background 0.2s,
					border-color 0.2s;/
			}

			.file-input-button:active {
				background: #5a6268;
				border-color: #5a6268;
			}

			.file-input-wrapper:active .file-input-button {
				transform: scale(0.98);
			}


			.file-input-button svg {
				width: 24px;
				height: 24px;
				fill: white;
			}

			.file-input-button:hover {
				background: #5a6268;
			}

			/* 禁用状态 */
			#fileInput:disabled+.file-input-button {
				opacity: 0.6;
				pointer-events: none;
			}

			/* 新增的 Tab 按钮样式 */
			.tab-buttons {
				display: flex;
				gap: 6px;
				margin-bottom: 12px;
				border-bottom: 2px solid #e3e8ee;
				padding-bottom: 8px;
			}

			.tab-button {
				padding: 8px 16px;
				border: none;
				border-radius: 4px 4px 0 0;
				background: #f0f2f5;
				color: #495057;
				font-size: 14px;
				cursor: pointer;
				transition: all 0.2s;
				position: relative;
				bottom: -2px;
			}

			.tab-button.active {
				background: white;
				color: #007bff;
				border-bottom: 3px solid #007bff;
				font-weight: 500;
			}

			.tab-button:hover:not(.active) {
				background: #e9ecef;
				color: #212529;
			}
		</style>
	</head>
	<body>
		<div class="container">
			<textarea id="output" readonly placeholder="结果将显示在这里..."></textarea>
			<!-- 按钮容器 -->
			<div class="tab-buttons">
				<button id="chat" class="tab-button active" data-target="chat">💬 聊天</button>
				<button id="generate" class="tab-button" data-target="generate">🔍 查询</button>
			</div>
			<div class="input-group">
				<textarea id="input" rows="2" placeholder="输入命令(/clear 清空)Shift+Enter换行"></textarea>
				<div class="button-row">
					<button onclick="sendMessage()">发送</button>
					<button class="icon-button" onclick="playSound(this)">
						<svg class="on-icon" viewBox="0 0 24 24">
							<path fill="currentColor"
								d="M15 3v18l-5-4H4V7h6l5-4zm3.5 5.5c1-1 2.5-1.5 4-1.5v3c-.6 0-1.2.2-1.7.5l-2.3-2zm2.3 7.7c.8-.6 1.5-1.5 1.9-2.7h-3c-.1.5-.3 1-.7 1.4l1.8 1.3z" />
						</svg>

						<svg class="off-icon" viewBox="0 0 24 24">
							<path fill="currentColor"
								d="M15 3v18l-5-4H4V7h6l5-4zm7.1 14.7l-1.4-1.4-3.6-3.6-3.6 3.6-1.4-1.4 3.6-3.6-3.6-3.6 1.4-1.4 3.6 3.6 3.6-3.6 1.4 1.4-3.6 3.6 3.6 3.6z" />
						</svg>
					</button>
					<div class="file-input-wrapper">
						<button class="file-input-button">
							<svg viewBox="0 0 24 24">
								<path fill="currentColor"
									d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11zm-3-9H7v-2h8v2zm-8 4h8v-2H7v2z" />
							</svg>
						</button>
						<input type="file" id="fileInput" accept=".txt" />
					</div>
				</div>
			</div>
		</div>

		<script>
			if (localStorage.getItem('baseURL') === null) {
				localStorage.setItem('baseURL', 'http://127.0.0.1:11434');
			}
			if (localStorage.getItem('baseModel') === null) {
				localStorage.setItem('baseModel', 'modelscope.cn/modelscope/Qwen2.5-7B-Instruct-1M-GGUF:latest');
			}
			const outputDiv = document.getElementById('output');
			let baseURL = localStorage.getItem('baseURL');
			let baseModel = localStorage.getItem('baseModel');
			let isSpeaking = false;
			let isSending = null;
			let currentUtterance = null;
			let fullText = null;

			document.addEventListener("DOMContentLoaded", function() {
				document.addEventListener("keydown", function(event) {
					if (event.key === "Enter") {
						sendMessage();
						event.preventDefault();
					}
				});
			});

			let targetId = 'chat';
			const buttons = document.querySelectorAll('.tab-button');
			buttons.forEach(button => {
				button.addEventListener('click', function() {
					buttons.forEach(btn => btn.classList.remove('active'));
					this.classList.add('active');
					targetId = this.dataset.target;
					document.title = `AI-${targetId === 'chat' ? "聊天" : "查询"}模式`;
					console.log('当前选项卡:', targetId);
					document.querySelectorAll('.content').forEach(content => {
						content.classList.remove('active');
					});
					if (isSending === null) {
						document.getElementById(targetId).classList.add('active');
						outputDiv.value = '';
						if (targetId === 'chat') {
							let i = 1;
							while (i < messages.length) {
								outputDiv.value +=
									`\n\n您:${messages[i]['content']}\n\nAI:${messages[i+1]['content']}`;
								i += 2;
							}
							outputDiv.scrollTop = outputDiv.scrollHeight;
						}
					}
				});
			});

			// 可选:添加键盘导航支持Alt+1
			document.addEventListener('keydown', (e) => {
				if (e.altKey) {
					if (e.key === '1') document.querySelector('[data-target="chat"]').click();
					if (e.key === '2') document.querySelector('[data-target="generate"]').click();
				}
			});

			function playSound(btn) {
				return new Promise((resolve) => { // 返回 Promise
					const content = outputDiv.value.split('AI:');
					const aiText = content[content.length - 1]?.trim() || '';
					if (!isSpeaking) {
						if (content) {
							// 创建语音实例
							currentUtterance = new SpeechSynthesisUtterance(aiText);
							currentUtterance.lang = 'zh-CN';

							// 语音结束回调
							currentUtterance.onend = () => {
								isSpeaking = false;
								btn.classList.toggle('active');
								resolve(); // 异步完成,通知外部
							};
							// 处理播放错误
							currentUtterance.onerror = () => {
								isSpeaking = false;
								btn.classList.remove('active');
								resolve();
							};

							window.speechSynthesis.speak(currentUtterance);
							isSpeaking = true;
							btn.classList.toggle('active');
						} else {
							resolve(); // 无内容时直接 resolve
						}
					} else {
						window.speechSynthesis.cancel();
						isSpeaking = false;
						btn.classList.toggle('active');
						resolve(); // 异步完成,通知外部
					}
				});
			}

			// 添加 HTML 转义函数
			const sanitizeHTML = (str) => {
				const div = document.createElement('div');
				div.textContent = str.replace(/\s/g, '');
				return div.innerHTML;
			};

			let data = null;
			let messages = [{
				role: "system",
				content: "You are a warm-hearted assistant, and you only speak Chinese."
			}];
			if (localStorage.getItem('messages') !== null) {
				messages = JSON.parse(localStorage.getItem("messages")) || [];
				document.querySelector('[data-target="chat"]').click();
			}

			function sendMessage() {
				let input = document.getElementById('input').value;
				document.getElementById('input').value = '';
				if (isSending) {
					alert('请勿打扰,思考中。。。。。。');
					return;
				}
				if (input.trim() === '/clear') {
					outputDiv.value = '';
					messages.splice(1);
					localStorage.setItem("messages", JSON.stringify(messages));
					fullText = '';
					return;
					//localStorage.removeItem('user_theme');
					//localStorage.clear();
				}
				if (input.trim().slice(0, 4) === '/url') {
					const urlRegex =
						/^https?:\/\/((1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.){3}(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)(:\d+)?(\/.*)?$/;
					if (urlRegex.test((input.trim().slice(4)).trim())) {
						localStorage.setItem('baseURL', (input.trim().slice(4)).trim());
						baseURL = localStorage.getItem('baseURL');
					} else {
						alert('请按下面格式输入。\n输入命令(/url http://127.0.0.1:11434)');
					}
					return;
				}
				if (input.trim().slice(0, 6) === '/model') {
					if (input.trim().length > 6) {
						localStorage.setItem('baseModel', (input.trim().slice(6)).trim());
						baseModel = localStorage.getItem('baseModel');
					} else {
						alert('请按下面格式输入。\n输入命令(/model deepseek-r1:8b)');
					}
					return;
				}
				if (input.trim().length === 0) {
					alert('输入为空!');
					return;
				}
				if (input.trim().slice(0, 1) === '/' || input.trim() === '/help') {
					alert('下面是常用命令。\n清空 /clear\nIP:PORT /url http://127.0.0.1:11434\n模型 /model deepseek-r1:8b');
					return;
				}
				outputDiv.value += `\n\n您:${sanitizeHTML(input)}\n\nAI:\n`;
				outputDiv.scrollTop = outputDiv.scrollHeight;
				isSending = targetId;
				if (isSending === 'chat') {
					messages.push({
						role: "user",
						content: input
					});
					data = {
						model: baseModel,
						messages: messages,
						stream: true
					};
				} else {
					if (typeof fullText === 'string' && fullText.trim().length > 0) {
						input = `基于以下上下文:\n${fullText}\n\n请回答:${input}`;
						console.log(input);
					}
					data = {
						model: baseModel,
						prompt: input
					};
				}
				const url = `${baseURL}/api/${isSending}`;
				console.log(url);
				fetch(url, {
						method: 'POST',
						headers: {
							'Content-Type': 'application/json'
						},
						body: JSON.stringify(data),
						mode: 'cors'
					})
					.then(response => {
						if (!response.ok) throw new Error(`HTTP错误: ${response.status}`);

						const reader = response.body.getReader();
						const decoder = new TextDecoder('utf-8');
						let prevChunk = '';

						function processChunk({
							done,
							value
						}) {
							if (done) {
								// 处理流结束后的剩余数据
								if (prevChunk) {
									try {
										const parsed = JSON.parse(prevChunk);
										appendToOutput(`${targetId === 'chat' ? parsed.message.content : parsed.response}`);
									} catch (e) {
										appendToOutput(`解析错误: ${e.message}`, true);
									}
								}
								return; // 结束递归
							}

							const chunk = decoder.decode(value, {
								stream: true
							});
							prevChunk += chunk;
							const lines = prevChunk.split('\n');
							prevChunk = lines.pop() || ''; // 保存未完成的行

							for (const line of lines) {
								try {
									const parsed = JSON.parse(line);
									appendToOutput(`${isSending === 'chat' ? parsed.message.content : parsed.response}`);
								} catch (e) {
									appendToOutput(`解析错误: ${e.message}`, true);
								}
							}

							// 继续读取下一个chunk
							return reader.read().then(processChunk);
						}

						// 辅助函数:更新界面并滚动
						function appendToOutput(text, isError = false) {
							outputDiv.value += text + (isError ? '\n' : '');
							outputDiv.scrollTop = outputDiv.scrollHeight;
						}

						// 开始读取流
						return reader.read().then(processChunk);
					})
					.then(() => {
						console.log('流式处理完成');
						if (targetId === 'chat') {
							if (outputDiv.value.trim()) {
								const content = outputDiv.value.split('AI:');
								messages.push({
									role: "assistant",
									content: content[content.length - 1]
								});
								if (messages.length > 21) messages.splice(1, 2);
							}
							localStorage.setItem("messages", JSON.stringify(messages));
							document.querySelector('.icon-button').click();
						}
						isSending = null;
					})
					.catch(error => {
						messages.splice(-1, 1);
						outputDiv.value += `错误:${error.message}\n`;
						outputDiv.scrollTop = outputDiv.scrollHeight;
						isSending = null;
					});
			}
			// 添加到JavaScript中
			document.getElementById('fileInput').addEventListener('change', function(e) {
				const file = event.target.files[0];
				if (file && file.name.endsWith('.txt')) {
					fileName = file.name;
					const reader = new FileReader();

					reader.readAsText(file, 'UTF-8');
					reader.onload = (e) => {
						const utf8Text = e.target.result;
						if (!/[\\u4E00-\\u9FA5]/.test(utf8Text)) { // 检测是否存在中文
							reader.readAsText(file, 'GBK'); // 尝试 GBK 编码
							reader.onload = (e) => {
								splitText(e);
							};
						} else {
							splitText(e);
						}
					};
				} else {
					alert('请选择一个有效的 .txt 文件。');
				}
			});

			function splitText(e) {
				fullText = e.target.result;
				console.log(fullText);
			}
		</script>
	</body>
</html>

手撸简易Agent:Ollama+Docker实现流式多轮本地对话 Agent 是大语言模型从‘能说’走向‘能做’的关键范式,其核心原理在于状态维护、模型调用与响应编排。技术价值体现在降低LLM应用门槛、提升交互实时性与部署可控性。典型应用场景包括企业内部工具自动化、离线环境智能助手及AI原型快速验证。本文聚焦轻量级落地路径,摒弃LangChain等重型框架,基于Ollama本地模型服务与Docker环境封装,实现可调试、可复现的流式多轮对话系统,全程强调透明性与工程可操作性,特别适配Windows/Mac/Linux多平台本地开发与客户现场离线部署需求。 阅读详情

相关推荐

Python调用Ollama API实现本地大模型工程化落地

本地大模型部署的核心在于将Ollama从命令行玩具升级为可集成、可监控、可扩展的HTTP服务组件。其底层基于标准RESTful API(如/api/chat、/api/generate、/api/embeddings),通过Python生态(requests、httpx、FastAPI)实现低门槛接入与高可靠性调度。结合token精准截断、流式响应容错、嵌入向量检索等关键技术,可支撑Excel自动摘要、工单分类、语义搜索等真实业务场景。Ollama服务本质是轻量级HTTP守护进程,Python调用的关键不是

mxdxm8899的专栏 482

推荐5个免费Ollama WebUI客户端

我们推荐5款开源免费的Ollama WebUI客户端,帮助您了解Ollama本地模型框架,轻松掌握其优缺点,提升您的使用体验。Ollama 的模型在本地运行,所有用户生成的数据都存储在本地,使其安全且私密,无需审查,有效满足您的数据隐私需求。而且,对于本地运行的应用程序来说,这种方法不仅提高了效率,而且消除了对网络环境的依赖。尽管Ollama可以在本地部署模型服务,但其原生交互界面是基于命令行的,这不允许用户轻松地与AI模型交互。

m0_59163425的博客 1万+

Ollama图形化客户端:本地大模型管理的可视化解决方案

在人工智能应用开发领域,模型管理与交互是核心环节。传统命令行工具虽然功能强大,但存在操作繁琐、可视化不足的痛点。通过RESTful API调用实现前后端分离,能够构建轻量级、高兼容性的客户端应用。这种架构在提升开发效率、降低使用门槛方面具有显著技术价值,尤其适用于本地大模型的日常管理与调试场景。Electron和Tauri等跨平台框架为此类桌面应用开发提供了成熟解决方案,结合React、Vue等前端技术可实现响应式交互界面。本文聚焦于Ollama-app这一具体实现,该工具通过图形化界面将模型拉取、对话交互

weixin_33739541的博客 418

五个优秀的免费 Ollama WebUI 客户端推荐

Ollama 是一款强大的本地运行大型语言模型(LLM)的框架,它允许用户在自己的设备上直接运行各种大型语言模型,包括 Llama 2、Mistral、Dolphin Phi 等多种模型,无需依赖网络连接。此外,Ollama 还提供跨平台的支持,包括 macOS、Windows、Linux 以及 Docker, 几乎覆盖了所有主流操作系统。详细信息请访问 [Ollama 官方开源社区]

2401_85343303的博客 3万+

FastAPI与ollama大模型异步流式响应实战

异步编程是现代Web开发的核心技术,通过事件循环机制实现高并发处理。Python的asyncio库提供了原生的异步支持,而FastAPI作为基于ASGI的异步Web框架,天然适合处理IO密集型任务。在实际工程中,将大模型服务如ollama与Web框架集成时,流式响应(StreamingResponse)能显著提升用户体验,避免长时间等待。本文通过FastAPI+ollama的实战案例,详解如何用httpx实现异步HTTP客户端,处理模型推理的流式输出,并解决异步编程中的常见陷阱,为AI服务集成提供可靠方案。

weixin_34128839的博客 435

Ollama本地运行AI Agent:零API Key的开源智能体实践

AI Agent 是一种能自主规划、调用工具并迭代推理的智能系统,其核心依赖稳定低延迟的LLM推理服务。传统方案高度耦合云端API(如OpenAI),受限于网络、配额与数据合规风险;而本地化Agent通过Ollama等轻量级LLM运行时,在设备端提供OpenAI兼容接口,实现协议级无缝迁移。这种架构将开发重心从‘对接外部服务’转向‘设计行为逻辑’,显著提升调试可见性、响应确定性与数据主权——尤其适合隐私敏感、离线可用或需高频迭代的工程场景。本文以Llama3+Python构建可运行的本地Agent为例,详解

culh2177的博客 632

HTML 之 ollama流式API客户端 -generate模式

ollama流式API客户端。

liujava56的专栏 288

vcpkg管理OpenCASCADE的5个高效技巧:从多版本共存到离线部署

本文详细介绍了使用vcpkg高效管理OpenCASCADE的5个实用技巧,包括多版本共存、性能优化、团队共享、CI/CD集成和离线部署。通过自动配置和版本控制,vcpkg显著简化了OpenCASCADE的开发环境管理,特别适合工业级CAD开发场景。

rain6的博客 189

HTML 之 ollama流式API客户端 -chat模式

ollama流式API客户端。

liujava56的专栏 365

用c++生成随机迷宫_自动生成随机迷宫(1)prim算法

“程序 = 数据 + 算法”,一款好的作品不单单是代码的堆砌,还有其灵魂的部分,那就是算法;算法是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。算法既然是解决某类型问题的规范,那么我们就学习它,并在我们的作品中使用它。从这一期开始做一个迷宫系列,包括用算法生成随机迷宫,用算法自动寻址走迷宫。 三大迷宫生成算法之一“随机Prim算法不是...

weixin_31787547的博客 2598

vue高德地图POI关键字搜索定位

最近在项目中遇到了关于地图的问题,首先为了满足需求从而使用的是JSAPI为2.0版本的。需求是根据关键字搜索定位到该位置。值得注意的是在使用 AMap.Event.addListener时 Event一定要大写的E,不然页面会报错。在地图上定义一个输入框,根据输入的位置进行提示,然后点击后跳转到对应的位置并打点标记。JSAPI主要使用这两个。

YL 2136

从 HTTP 到 Ollama API

HTTP,全称为超文本传输协议(HyperText Transfer Protocol),是互联网上应用最为广泛的一种网络协议。它是客户端和服务器之间进行通信的规则集合,允许将超文本标记语言(HTML)文档从Web服务器传输到Web浏览器。简而言之,HTTP是Web浏览器和Web服务器之间的“语言”,使得用户能够浏览网页、下载文件、提交表单等。比如:- 你发一个''请求''(比如“请帮我生成一段文字”)。- 服务器返回一个 **响应**(模型生成的文字)。

2501_94085327的博客 573

1.全基因组重测序数据分析介绍

二代测序原理及fastq数据解读、全基因组重测序数据分析内容

weixin_53682198的博客 1884

Ollama 已部署DeepSeek模型,如果用Java语言实现调用

String result = client.generate("deepseek", "解释量子纠缠", 0.8, 1000);System.err.println("JSON 解析错误: " + e.getMessage());System.out.println("模型回复:\n" + response);System.err.println("网络错误: " + e.getMessage());-- 使用最新版本 -->System.out.println("收到片段: " + line);

meisongqing的博客 2333

深度强化学习算法PPO训练Pendulum

returnadv = 0print('状态空间维度:', state_n)print('动作空间维度:', action_n)steps = []if done:breakif done:breakelse:steps = []if done:break。

weixin_43336108的博客 808

YOLOv12改进策略【模型轻量化】| 替换骨干网络为EfficientNet v1 高效的移动倒置瓶颈结构

本文记录的是基于。采用了创新性的方法,通过精心平衡网络和来提升性能。本文将的设计优势融入YOLOv12中,提升YOLOv12的性能与效率,使其在目标检测任务中表现更为出色。本文配置了原模型中的共种不同大小的模型结构,以满足不同的需求。

Limiiiing的博客 964

QwQ-32B在ollama中支持流式输出吗?SSE实现与前端实时渲染教程

本文介绍了如何在星图GPU平台上自动化部署【ollama】QwQ-32B镜像,实现大语言模型的流式推理与前端实时渲染。通过SSE协议支持,用户可直观查看AI逐字生成的思考过程,典型应用于智能对话助手、教学问答系统等需低延迟响应的交互场景。

weixin_42590539的博客 433

基于Python的彩票数据爬虫:数据抓取与趋势分析

爬虫是一种用于从互联网上自动抓取信息的程序。在抓取彩票数据时,我们首先需要确定目标网站并获取其网页内容,接着提取彩票的开奖结果信息并保存。彩票数据通常是以HTML表格或列表的形式展示,爬虫可以利用Python的requests和来抓取静态网页,或使用Selenium来抓取动态页面。在本篇博客中,我们深入探讨了如何使用Python编写彩票数据爬虫,抓取并分析彩票开奖结果。通过Python爬虫技术,结合数据分析与可视化工具,我们能够全面分析历史开奖数据,揭示彩票号码的频率分布、趋势变化以及未来的可能走势。

2201_76125261的博客 1940

Ollama部署DeepSeek-R1-Distill-Qwen-7B:支持流式响应的Web前端实时交互实现

本文介绍了如何在星图GPU平台上自动化部署【ollama】DeepSeek-R1-Distill-Qwen-7B镜像,快速构建支持流式响应的本地AI对话系统。该镜像专为逻辑推理与代码生成优化,适用于技术文档问答、编程辅助等典型场景,显著提升开发者本地AI交互效率。

weixin_32921023的博客 162

2026年数字IC设计紫光展锐笔试带答案解析

本文是一份数字IC设计工程师/芯片验证工程师的笔试样题,包含单选题和多选题两部分。单选题共20题(每题2分),涵盖数字电路、C++/Verilog编程、芯片设计基础等内容,例如D/A转换计算、面向对象编程特性、三极管工作区域、Verilog仿真时间格式等。多选题15题(每题2分),考察Hold违例修复方法、验证方法学等知识点。试卷总分100分,考试时长90分钟,题型设计兼顾基础理论与工程实践,重点测试应聘者对芯片设计核心概念和工具链的掌握程度。部分题目解析详细说明了计算过程或概念原理,如第1题通过二进制转换

Open 111

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Cogito-v1-preview-llama-3B实战教程:API流式响应+前端集成示例

本文介绍了如何在星图GPU平台自动化部署cogito-v1-preview-llama-3B镜像,并实现API流式响应与前端集成。该镜像具备强大的文本生成和推理能力,可应用于智能对话系统开发,为用户提供实时、流畅的交互体验。

weixin_36047538的博客 612

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Spring AI Alibaba 入门开发1-环境搭建、ollama部署、Chat和ChatModel、流式输出

环境配置:基于JDK21+SpringBoot3.5.5+SpringAI1.0.0搭建项目框架,配置API密钥与环境变量。 核心调用:支持ChatModel直接调用(call/stream方法)或ChatClient高级封装(集成提示模板、输出解析)。多模型并发:可同时配置qwen与deepseek模型,实现流式输出响应。本地部署:通过Ollama工具本地运行qwen3:4b等轻量模型,降低云端依赖。全文提供完整代码示例,涵盖API配置、中文编码处理等关键细节,助力快速开发AI应用。

geminigoth的博客 397

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

从零部署本地LLM服务:Ollama集成与API调用实战指南

大型语言模型(LLM)作为当前人工智能领域的核心技术,通过海量数据预训练获得强大的自然语言理解和生成能力。其工作原理基于Transformer架构,通过自注意力机制处理序列数据,在代码生成、文档撰写和智能问答等场景展现巨大价值。在企业级应用中,数据安全与隐私保护成为关键考量,本地化部署成为重要解决方案。通过开源推理框架如Ollama,开发者可以在可控环境中部署LLM服务,实现数据不出域的安全保障。本文以Ollama为例,详细演示如何从环境准备、模型拉取到API集成的完整流程,帮助开发者快速构建私有化LLM应

weixin_34056162的博客 332

终极指南:如何快速配置Chatbox多模型AI桌面客户端实现高效对话

Chatbox是一款强大的开源AI桌面客户端,让你在一个界面中就能同时使用ChatGPT、Claude、Google Gemini、Ollama等多种主流AI模型,彻底告别多平台切换的烦恼。无论你是开发者、内容创作者还是普通用户,这款跨平台应用都能大幅提升你的AI对话效率,实现真正的多模型协同工作。 ## 为什么你需要Chatbox多模型AI客户端? 在AI应用日益普及的今天,你是否遇到过这些

gitblog_00107的博客 1072
上一篇: HTML 之 ollama流式API客户端 -chat模式
小6哥
博客等级 码龄18年 16粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值