当前位置: 首页 > news >正文

IDEA 2025.1更新-AI助手试用和第三方模型集成方案

今天刚把 IntelliJ IDEA 更新到了 2025.1 版本,主要是想看看这次 AI Assistant 有什么新东西。之前看到消息说功能有更新,而且似乎可以免费试用,就动手试了试,顺便把过程和一些发现记录下来,给可能需要的朋友一个参考。

一、启用 AI Assistant 试用

之前的版本 AI Assistant 对国内用户不太友好,这次更新后,我发现通过调整区域设置,可以重新弹出 AI Assistant 的登录和试用选项。

具体步骤是这样的:

  1. 确认 IDEA 版本: 确保是 2025.1 或更新版本。

  2. 修改地区设置:

    image-20250417203643237

  3. 重启 IDEA: 必须完全关闭 IDEA 再重新打开,让配置生效。

  4. 检查 AI Assistant 插件:

    • Settings/Preferences -> Plugins -> Installed 确认 AI Assistant, Junie插件是启用状态。如果没有,去 Marketplace 搜索安装一下。

    image-20250417203601570

  5. 登录并开始试用:

    • 重启后,IDE 右侧应该会出现 AI Assistant 的工具窗口。点击登录你的 JetBrains 账号。
    • 登录成功后,应该会看到一个 “Start Trial” 或类似的按钮,点击它就可以开始试用了。

    image-20250417204108437

注意: 这个方法本质上是开启了 JetBrains 提供的试用期。试用期有多长、结束后政策如何,目前还不确定。这更像是一个基于区域的试用策略,不保证长期有效。

二、新东西:Agent AI

这次更新除了常规的 AI 功能(代码补全、解释、生成 Commit Message 等),比较有意思的是推出了一个叫 “Agent AI” 的东西。

看介绍和初步试用,它似乎不只是建议,而是可以直接参与到跨文件、更复杂的代码修改任务中。比如你可以让它分析某个方法的调用链,或者尝试进行一些重构。

这个功能看起来潜力挺大,可以直接在 IDE 里处理一些稍微繁琐的任务。具体效果怎么样,还需要在实际项目中多用用看。

image-20250417212613727

image-20250417212539428

image-20250417212553335

三、连接本地模型(可选)

对于注重隐私或者想用特定模型的开发者,AI Assistant 现在也支持连接本地运行的大语言模型了。

  1. 本地运行模型: 如果你本地用 Ollama 或其他兼容 OpenAI API 格式的服务跑了模型(比如 Llama 3, Qwen, Gemma 等),确保服务在运行。

  2. 配置 IDEA:

    • 打开 Settings/Preferences -> Tools -> AI Assistant -> LLM Service
    • 选择 CustomLocal (具体选项名称可能微调),然后填入你本地服务的地址,比如 Ollama 默认的 http://localhost:11434

    image-20250417205159689

本地跑不动模型怎么办?

我看有人整理了一些提供免费在线 Ollama 服务的列表(比如这个:https://idea.wangwangit.com/zh),你可以找一个试试看,配置方法和本地一样,填入对应的服务地址就行。不过用第三方服务,数据隐私方面就需要自己衡量了。

ollama模型太辣鸡?

那就让我抛出重磅级武器吧,直接接入第三方API, 修改API_URL,API_KEY为自己的配置,在ENABLED_MODELS中添加合适的模型,然后在本地或者服务器启动这份代码! 就可以集成各种在线AI模型使用啦!

from flask import Flask, request, jsonify
import requests
import time
import uuid
import logging
import json
from typing import Dict, Any
from datetime import datetime, UTC# 配置日志(更改为中文)
logging.basicConfig(level=logging.INFO,format='%(asctime)s [%(levelname)s] %(message)s',handlers=[logging.StreamHandler()]
)
logger = logging.getLogger(__name__)app = Flask(__name__)# 启用模型配置:直接定义启用的模型名称
# 用户可添加/删除模型名称,动态生成元数据
ENABLED_MODELS = {"gemini-2.0-flash","grok-3-beta","DeepSeek-V3"
}# API 配置
API_URL = "https://xxxx/v1/chat/completions"
# 请替换为你的 API 密钥(请勿公开分享)
API_KEY = "xxxxx"# 模拟 Ollama 聊天响应数据库
OLLAMA_MOCK_RESPONSES = {"What is the capital of France?": "The capital of France is Paris.","Tell me about AI.": "AI is the simulation of human intelligence in machines, enabling tasks like reasoning and learning.","Hello": "Hi! How can I assist you today?"
}@app.route("/", methods=["GET"])
def root_endpoint():"""模拟 Ollama 根路径,返回 'Ollama is running'"""logger.info("收到根路径请求")return "Ollama is running", 200@app.route("/api/tags", methods=["GET"])
def tags_endpoint():"""模拟 Ollama 的 /api/tags 端点,动态生成启用模型列表"""logger.info("收到 /api/tags 请求")models = []for model_name in ENABLED_MODELS:# 推导 family:从模型名称提取前缀(如 "gpt-4o" -> "gpt")family = model_name.split('-')[0].lower() if '-' in model_name else model_name.lower()# 特殊处理已知模型if 'llama' in model_name:family = 'llama'format = 'gguf'size = 1234567890parameter_size = '405B' if '405b' in model_name else 'unknown'quantization_level = 'Q4_0'elif 'mistral' in model_name:family = 'mistral'format = 'gguf'size = 1234567890parameter_size = 'unknown'quantization_level = 'unknown'else:format = 'unknown'size = 9876543210parameter_size = 'unknown'quantization_level = 'unknown'models.append({"name": model_name,"model": model_name,"modified_at": datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),"size": size,"digest": str(uuid.uuid4()),"details": {"parent_model": "","format": format,"family": family,"families": [family],"parameter_size": parameter_size,"quantization_level": quantization_level}})logger.info(f"返回 {len(models)} 个模型: {[m['name'] for m in models]}")return jsonify({"models": models}), 200def generate_ollama_mock_response(prompt: str, model: str) -> Dict[str, Any]:"""生成模拟的 Ollama 聊天响应,符合 /api/chat 格式"""response_content = OLLAMA_MOCK_RESPONSES.get(prompt, f"Echo: {prompt} (这是来自模拟 Ollama 服务器的响应。)")return {"model": model,"created_at": datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ"),"message": {"role": "assistant","content": response_content},"done": True,"total_duration": 123456789,"load_duration": 1234567,"prompt_eval_count": 10,"prompt_eval_duration": 2345678,"eval_count": 20,"eval_duration": 3456789}def convert_api_to_ollama_response(api_response: Dict[str, Any], model: str) -> Dict[str, Any]:"""将 API 的 OpenAI 格式响应转换为 Ollama 格式"""try:content = api_response["choices"][0]["message"]["content"]total_duration = api_response.get("usage", {}).get("total_tokens", 30) * 1000000prompt_tokens = api_response.get("usage", {}).get("prompt_tokens", 10)completion_tokens = api_response.get("usage", {}).get("completion_tokens", 20)return {"model": model,"created_at": datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ"),"message": {"role": "assistant","content": content},"done": True,"total_duration": total_duration,"load_duration": 1234567,"prompt_eval_count": prompt_tokens,"prompt_eval_duration": prompt_tokens * 100000,"eval_count": completion_tokens,"eval_duration": completion_tokens * 100000}except KeyError as e:logger.error(f"转换API响应失败: 缺少键 {str(e)}")return {"error": f"无效的API响应格式: 缺少键 {str(e)}"}def print_request_params(data: Dict[str, Any], endpoint: str) -> None:"""打印请求参数"""model = data.get("model", "未指定")temperature = data.get("temperature", "未指定")stream = data.get("stream", False)messages_info = []for msg in data.get("messages", []):role = msg.get("role", "未知")content = msg.get("content", "")content_preview = content[:50] + "..." if len(content) > 50 else contentmessages_info.append(f"[{role}] {content_preview}")params_str = {"端点": endpoint,"模型": model,"温度": temperature,"流式输出": stream,"消息数量": len(data.get("messages", [])),"消息预览": messages_info}logger.info(f"请求参数: {json.dumps(params_str, ensure_ascii=False, indent=2)}")@app.route("/api/chat", methods=["POST"])
def ollama_chat_endpoint():"""模拟 Ollama 的 /api/chat 端点,所有模型都能使用"""try:data = request.get_json()if not data or "messages" not in data:logger.error("无效请求: 缺少 'messages' 字段")return jsonify({"error": "无效请求: 缺少 'messages' 字段"}), 400messages = data.get("messages", [])if not messages or not isinstance(messages, list):logger.error("无效请求: 'messages' 必须是非空列表")return jsonify({"error": "无效请求: 'messages' 必须是非空列表"}), 400model = data.get("model", "llama3.2")user_message = next((msg["content"] for msg in reversed(messages) if msg.get("role") == "user"),"")if not user_message:logger.error("未找到用户消息")return jsonify({"error": "未找到用户消息"}), 400# 打印请求参数print_request_params(data, "/api/chat")logger.info(f"处理 /api/chat 请求, 模型: {model}")# 移除模型限制,所有模型都使用APIapi_request = {"model": model,"messages": messages,"stream": False,"temperature": data.get("temperature", 0.7)}headers = {"Content-Type": "application/json","Authorization": f"Bearer {API_KEY}"}try:logger.info(f"转发请求到API: {API_URL}")response = requests.post(API_URL, json=api_request, headers=headers, timeout=30)response.raise_for_status()api_response = response.json()ollama_response = convert_api_to_ollama_response(api_response, model)logger.info(f"收到来自API的响应,模型: {model}")return jsonify(ollama_response), 200except requests.RequestException as e:logger.error(f"API请求失败: {str(e)}")# 如果API请求失败,使用模拟响应作为备用logger.info(f"使用模拟响应作为备用方案,模型: {model}")response = generate_ollama_mock_response(user_message, model)return jsonify(response), 200except Exception as e:logger.error(f"/api/chat 服务器错误: {str(e)}")return jsonify({"error": f"服务器错误: {str(e)}"}), 500@app.route("/v1/chat/completions", methods=["POST"])
def api_chat_endpoint():"""转发到API的 /v1/chat/completions 端点,并转换为 Ollama 格式"""try:data = request.get_json()if not data or "messages" not in data:logger.error("无效请求: 缺少 'messages' 字段")return jsonify({"error": "无效请求: 缺少 'messages' 字段"}), 400messages = data.get("messages", [])if not messages or not isinstance(messages, list):logger.error("无效请求: 'messages' 必须是非空列表")return jsonify({"error": "无效请求: 'messages' 必须是非空列表"}), 400model = data.get("model", "grok-3")user_message = next((msg["content"] for msg in reversed(messages) if msg.get("role") == "user"),"")if not user_message:logger.error("未找到用户消息")return jsonify({"error": "未找到用户消息"}), 400# 打印请求参数print_request_params(data, "/v1/chat/completions")logger.info(f"处理 /v1/chat/completions 请求, 模型: {model}")headers = {"Content-Type": "application/json","Authorization": f"Bearer {API_KEY}"}try:logger.info(f"转发请求到API: {API_URL}")response = requests.post(API_URL, json=data, headers=headers, timeout=30)response.raise_for_status()api_response = response.json()ollama_response = convert_api_to_ollama_response(api_response, model)logger.info(f"收到来自API的响应,模型: {model}")return jsonify(ollama_response), 200except requests.RequestException as e:logger.error(f"API请求失败: {str(e)}")return jsonify({"error": f"API请求失败: {str(e)}"}), 500except Exception as e:logger.error(f"/v1/chat/completions 服务器错误: {str(e)}")return jsonify({"error": f"服务器错误: {str(e)}"}), 500def main():"""启动模拟服务器"""logger.info("正在启动模拟 Ollama 和 API 代理服务器,地址: http://localhost:11434")app.run(host="0.0.0.0", port=11434, debug=False)if __name__ == "__main__":main()

image-20250417232425105

image-20250417232529974

总结

总的来说,IDEA 2025.1 的 AI 功能值得尝试一下,尤其是通过改区域设置就能方便地开启试用。Agent AI 是个新方向,看看后续发展如何。连接本地模型也给了大家更多选择。

我就先用到这儿,算是个快速上手记录。如果你也更新了,欢迎交流使用体验,特别是 Agent AI 的实战效果。

相关文章:

  • 2025年GitHub平台上的十大开源MCP服务器汇总分析
  • 【AI飞】AutoIT入门七(实战):python操控autoit解决csf视频批量转换(有点难,AI都不会)
  • 如何下载适用于Docker环境的Google Chrome浏览器【镜像使用方法】
  • RT-Thread RTThread studio 初使用
  • osgb和obj格式互转
  • 计算机视觉---相机标定
  • Oracle之数据库对象加连表查询
  • 前端 实现文字打字效果(仿AI)
  • 三维点拟合直线ransac c++
  • C/C++中获取或处理时间节点方法
  • UWP特性分析
  • 软件招标评审模板
  • OpenCV day6
  • 责任链模式:从 Sentinel 流控到审批流程的链式处理
  • 什么是Netty
  • 常见免杀框架的使用(3款)---【AniYaGUI1.2.0、AV_Evasion_Tool掩日、FoxBypass_V1.0】
  • IHC肿瘤标志物 | 常见前列腺癌诊断
  • RAG-分块策略
  • 项目实战--新闻分类
  • 如何从EndNote中将某一篇手稿里面涉及到的引用文献导出,导出格式为bib?
  • 外媒:特朗普称或将“大幅降低”对中国的关税
  • “HPV男女共防计划”北半马主题活动新闻发布会在京举办
  • 纪念沈渭滨︱沈渭滨先生与新修《清史》
  • 今年一季度,上海对东盟进出口总值同比增长7.1%
  • 专访|松重丰:“美食家”不孤独,他在自由地吃饭
  • 美国多地举行抗议活动,特朗普经济政策支持率创新低