实战教程来了!从零开始打造MCP+Ollama集成

模型上下文协议MCP与Ollama的整合实现指南

在过去一两个个月里,模型上下文协议(Model Context Protocol,MCP)频繁出现在各种技术微信交流群中。我们已经看到了许多很酷的集成案例,大家似乎相信这个标准会长期存在,因为它为大模型与工具或软件的集成设立了规范。

前面一篇文章给大家分享了MCP一些基础概念,但是读完之后还是模棱两可,所以决定尝试将Ollama中的小型语言模型与MCP服务器连接起来,体验一下这个新标准。今天,向大家展示如何实现Ollama与MCP服务器的集成。

实现步骤

整个集成的主要步骤包括:

  1. 创建测试以及使用MCP服务
  2. 创建客户端文件来发送请求并启动服务
  3. 从服务获取工具到客户端
  4. 将工具转换为pydantic模型
  5. 通过response format将工具(作为pydantic模型)传递给Ollama
  6. 通过Ollama发送对话并接收结构化输出
  7. 如果响应中包含工具,则向服务器发送请求

安装依赖

要运行这个项目,需要安装必要的包。fastmcp库在使用uv运行代码时效果最佳。uv很容易下载和使用,类似于Poetry和pip。

使用以下命令将所需库添加到你的项目中:

uv add fastmcp ollama

这会同时安装MCP服务器和Ollama聊天库,以便你在它们的基础上构建客户端和服务器逻辑。

文件结构

设置时,你的文件夹应该是这样的:

your folder
├── server.py
└── client.py

server.py文件包含MCP服务器和想要暴露的工具。client.py文件在后台进程中启动服务器,获取可用工具,并与Ollama连接。

示例MCP服务器

首先,让我们使用fastmcp库创建一个简单的MCP服务器。该服务器暴露了一个名为magicoutput的工具。这个函数接受两个字符串输入并返回一个固定的字符串作为输出。

@mcp.tool()装饰器用于将函数注册为MCP服务器中的可用工具。当服务器启动后,任何客户端都可以获取并调用这个工具。

通过在主块中调用mcp.run()来启动服务器。

# server.py
from fastmcp import FastMCP
# 创建MCP服务器
mcp = FastMCP("TestServer")
# 我的工具:
@mcp.tool()
def magicoutput(obj1: str, obj2: str) -> int:
    """使用此函数获取魔法输出"""
    print(f"输入参数:obj1:{obj1},obj2:{obj2}")
    return f"输入参数:obj1:{obj1},obj2:{obj2},魔法输出:Hello MCP,MCP Hello"
if __name__ == "__main__":
    mcp.run()

我们运行下面命令,进行调试服务端的工具:

fastmcp dev server.py

输入日志如下:

Need to install the following packages:
@modelcontextprotocol/inspector@0.10.2
Ok to proceed? (y) y

Starting MCP inspector...
⚙️ Proxy server listening on port 6277
🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀
New SSE connection
Query parameters: [Object: 

本地访问页面http://127.0.0.1:6274/#tools,我们可以看构造的函数,并且可以调试

图片

获取服务器工具

为了连接到MCP服务器并列出可用工具,我们使用来自mcp库的ClientSessionStdioServerParametersstdio_client

我们定义一个名为OllamaMCP的类来处理服务器连接和工具获取。在类内部,_async_run方法启动异步会话,初始化它,并从服务器获取工具列表。

我们使用threading.Event()来跟踪会话何时准备就绪,并将工具列表存储在self.tools中。

在脚本末尾,我们定义服务器参数并在后台线程中运行客户端。这会启动连接并打印服务器返回的工具元数据。

# client.py
import asyncio
import threading 
from pathlib import Path
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from typing import Any

class OllamaMCP:
    """
    Ollama和FastMCP的简单集成
    """
    def __init__(self, server_params: StdioServerParameters):
        self.server_params = server_params
        self.initialized = threading.Event()
        self.tools: list[Any] = []
    def _run_background(self):
        asyncio.run(self._async_run())
    async def _async_run(self):
        try:
            async with stdio_client(self.server_params) as (read, write):
                async with ClientSession(read, write) as session:
                    await session.initialize()
                    self.session = session
                    tools_result = await session.list_tools()
                    self.tools = tools_result.tools
                    print(tools_result)
        except Exception as e:  
            print(f"启动MCP服务器时出错 {str(e)}")
if __name__ == "__main__":
    server_parameters = StdioServerParameters(
        command="uv",
        args=["run", "python", "server.py"],
        cwd=str(Path.cwd())
    )
    ollamamcp = OllamaMCP(server_params=server_parameters)
    ollamamcp._run_background()

运行上面的代码后,你会从服务器得到以下响应,其中可以看到服务器上可用的工具列表。

[04/19/25 12:10:47] INFO     Starting server "TestServer"...       server.py:261
meta=None nextCursor=None tools=[Tool(name='magicoutput', description='使用此函数获取魔法输出', inputSchema={'properties': {'obj1': {'title': 'Obj1', 'type': 'string'}, 'obj2': {'title': 'Obj2', 'type': 'string'}}, 'required': ['obj1', 'obj2'], 'title': 'magicoutputArguments', 'type': 'object'})]

将工具转换为pydantic模型

现在我们已经从服务器接收到了工具列表,下一步是将它们转换为Pydantic模型。我们使用Pydantic的create_model来动态定义新的响应模式,基于服务器的工具定义。还有一个辅助函数来将JSON类型映射到有效的Python类型。

Pydantic 是一个用于数据验证和序列化的 Python 模型库。它在 FastAPI 中广泛使用,用于定义请求体、响应体和其他数据模型,提供了强大的类型检查和自动文档生成功能

这帮助我们动态定义模型,使语言模型确切知道在返回工具参数时应使用什么结构。

图片

# client.py
import asyncio
import threading
from pathlib import Path
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from typing import Any, Union, Optional
from pydantic import BaseModel, create_model, Field

class OllamaMCP:
    """Ollama和FastMCP的简单集成"""

    def __init__(self, server_params: StdioServerParameters):
        self.server_params = server_params
        self.initialized = threading.Event()
        self.tools: list[Any] = []

    def _run_background(self):
        asyncio.run(self._async_run())

    async def _async_run(self):
        try:
            async with stdio_client(self.server_params) as (read, write):
                async with ClientSession(read, write) as session:
                    await session.initialize()
                    self.session = session
                    tools_result = await session.list_tools()
                    self.tools = tools_result.tools
        except Exception as e:  
            print(f"启动MCP服务器时出错 {str(e)}")


    def create_response_model(self):
        dynamic_classes = {}
        for tool in self.tools:
            class_name = tool.name.capitalize()
            properties = {}
            for prop_name, prop_info in tool.inputSchema.get("properties", {}).items():
                json_type = prop_info.get("type", "string")
                properties[prop_name] = self.convert_json_type_to_python_type(json_type)

            model = create_model(
                class_name,
                __base__=BaseModel,
                __doc__=tool.description,
                **properties,
            )
            dynamic_classes[class_name] = model

        if dynamic_classes:
            all_tools_type = Union[tuple(dynamic_classes.values())]
            Response = create_model(
                "Response",
                __base__=BaseModel,
                __doc__="LLm响应类",
                response=(str, Field(..., description= "向用户确认函数将被调用。")),
                tool=(all_tools_type, Field(
                    ...,
                    description="用于运行和获取魔法输出的工具"
                )),
            )
        else:
            Response = create_model(
                "Response",
                __base__=BaseModel,
                __doc__="LLm响应类",
                response=(str, ...),
                tool=(Optional[Any], Field(None, description="如果不返回None则使用的工具")),
            )

        self.response_model = Response
        print(Response.model_fields)

    @staticmethod
    def convert_json_type_to_python_type(json_type: str):
        """简单地将JSON类型映射到Python(Pydantic)类型。"""
        if json_type == "integer":
            return (int, ...)
        if json_type == "number":
            return (float, ...)
        if json_type == "string":
            return (str, ...)
        if json_type == "boolean":
            return (bool, ...)
        return (str, ...)
    
if __name__ == "__main__":
    server_parameters = StdioServerParameters(
        command="uv",
        args=["run", "python", "server.py"],
        cwd=str(Path.cwd())
    )
    ollamamcp = OllamaMCP(server_params=server_parameters)
    ollamamcp._run_background()
    ollamamcp.create_response_model()

运行代码后,print(Response.model_fields)的输出显示了我们刚刚构建的响应模型的完整结构。这个模型包括两部分:一部分是助手发送给用户的消息,另一部分是可选字段,保存工具参数。

如果模型填充了工具字段,我们将使用它来调用服务器。否则,我们只使用普通的响应字符串。

[04/19/25 12:17:20] INFO     Starting server "TestServer"...       server.py:261
{'response': FieldInfo(annotation=str, required=True, description='向用户确认函数将被调用。'), 'tool': FieldInfo(annotation=Magicoutput, required=True, description='用于运行和获取魔法输出的工具')}

使用后台线程和队列调用工具

现在工具可以作为pydantic模型使用了,我们可以继续并启用工具调用。为此,我们使用后台线程并设置两个队列。一个用于向服务器发送请求,另一个用于接收响应。

call_tool方法将请求放入队列,后台线程监听该请求。一旦使用MCP会话调用工具,结果就会放入响应队列。

import asyncio
import threading
import threading 
import queue
from pathlib import Path
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from typing import Any, Union, Optional
from pydantic import BaseModel, create_model, Field

class OllamaMCP:
    """Ollama和FastMCP的简单集成"""
    def __init__(self, server_params: StdioServerParameters):
        self.server_params = server_params
        self.initialized = threading.Event()
        self.tools: list[Any] = []
        self.request_queue = queue.Queue()
        self.response_queue = queue.Queue()
        # 启动后台线程异步处理请求
        self.thread = threading.Thread(target=self._run_background, daemon=True)
        self.thread.start()
    def _run_background(self):
        asyncio.run(self._async_run())
    async def _async_run(self):
        try:
            async with stdio_client(self.server_params) as (read, write):
                async with ClientSession(read, write) as session:
                    await session.initialize()
                    self.session = session
                    tools_result = await session.list_tools()
                    self.tools = tools_result.tools
                    self.initialized.set()
                    while True:
                        try:
                            tool_name, arguments = self.request_queue.get(block=False)
                        except queue.Empty:
                            await asyncio.sleep(0.01)
                            continue
                        if tool_name is None:
                            print("收到关闭信号。")
                            break
                        try:
                            result = await session.call_tool(tool_name, arguments)
                            self.response_queue.put(result)
                        except Exception as e:
                            self.response_queue.put(f"错误: {str(e)}")
        except Exception as e:
            print("MCP会话初始化错误:", str(e))
            self.initialized.set()  # 即使初始化失败也解除等待线程的阻塞
            self.response_queue.put(f"MCP初始化错误: {str(e)}")

    def call_tool(self, tool_name: str, arguments: dict[str, Any]) -> Any:
        """
        发布工具调用请求并等待结果
        """
        if not self.initialized.wait(timeout=30):
            raise TimeoutError("MCP会话未能及时初始化。")
        self.request_queue.put((tool_name, arguments))
        result = self.response_queue.get()
        return result

    def shutdown(self):
        """
        干净地关闭持久会话
        """
        self.request_queue.put((None, None))
        self.thread.join()
        print("持久MCP会话已关闭。")

    def create_response_model(self):
        dynamic_classes = {}
        for tool in self.tools:
            class_name = tool.name.capitalize()
            properties = {}
            for prop_name, prop_info in tool.inputSchema.get("properties", {}).items():
                json_type = prop_info.get("type", "string")
                properties[prop_name] = self.convert_json_type_to_python_type(json_type)
            model = create_model(
                class_name,
                __base__=BaseModel,
                __doc__=tool.description,
                **properties,
            )
            dynamic_classes[class_name] = model
        if dynamic_classes:
            all_tools_type = Union[tuple(dynamic_classes.values())]
            Response = create_model(
                "Response",
                __base__=BaseModel,
                response=(str, ...),
                tool=(Optional[all_tools_type], Field(None, description="如果不返回None则使用的工具")),
            )
        else:
            Response = create_model(
                "Response",
                __base__=BaseModel,
                response=(str, ...),
                tool=(Optional[Any], Field(None, description="如果不返回None则使用的工具")),
            )
        self.response_model = Response
    @staticmethod
    def convert_json_type_to_python_type(json_type: str):
        """简单地将JSON类型映射到Python(Pydantic)类型。"""
        if json_type == "integer":
            return (int, ...)
        if json_type == "number":
            return (float, ...)
        if json_type == "string":
            return (str, ...)
        if json_type == "boolean":
            return (bool, ...)
        return (str, ...)
if __name__ == "__main__":
    server_parameters = StdioServerParameters(
        command="uv",
        args=["run", "python", "server.py"],
        cwd=str(Path.cwd())
    )
    ollamamcp = OllamaMCP(server_params=server_parameters)
    if ollamamcp.initialized.wait(timeout=30):
        print("准备调用工具。")
        result = ollamamcp.call_tool(
            tool_name="magicoutput",
            arguments={"obj1": "dog", "obj2": "cat"}
        )
        print(result)
    else:
        print("错误: 初始化超时。")

请注意,在这个阶段,我们正在使用call_tool方法手动传递函数名称和参数。在下一节中,我们将根据Ollama返回的结构化输出触发这个调用。

运行此代码后,我们可以确认一切正常。工具被服务器正确识别、执行,并返回结果。

[04/19/25 12:18:26] INFO     Starting server "TestServer"...       server.py:261
准备调用工具。
meta=None content=[TextContent(type='text', text='输入参数:obj1:dog,obj2:cat,魔法输出:Hello MCP,MCP Hello', annotations=None)] isError=False

Ollama + MCP结合

首先我们先通过Ollama部署一个大模型服务,这里我们下gemma3

图片图片下面代码中,我是设置的局域网的ip

client = Client(
  host='http://192.168.1.5:11434',
  headers={'x-some-header': 'some-value'}
)

有了队列和call_tool函数,现在是时候该集成Ollama了。我们将响应类传递到Ollama的format字段中,告诉我们的语言模型(这里是Gemma)在生成输出时遵循该模式。

我们还定义了一个ollama_chat方法,用于发送对话,验证模型的响应是否符合模式,并检查是否包含工具。如果是,它提取函数名称和参数,然后使用在后台线程中的持久MCP会话调用它。

在main函数中,我们设置服务器连接,启动后台循环,并等待一切就绪。然后我们准备系统提示和用户消息,将它们发送给Ollama,并等待结构化输出。

最后,我们打印服务器的结果并关闭会话。

import asyncio
import threading
import queue

from pathlib import Path
from typing import Any, Optional, Union
from pydantic import BaseModel, Field, create_model
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from ollama import chat,Client


client = Client(
  host='http://192.168.1.5:11434',
  headers={'x-some-header': 'some-value'}
)

class OllamaMCP:

    def __init__(self, server_params: StdioServerParameters):
        self.server_params = server_params
        self.request_queue = queue.Queue()
        self.response_queue = queue.Queue()
        self.initialized = threading.Event()
        self.tools: list[Any] = []
        self.thread = threading.Thread(target=self._run_background, daemon=True)
        self.thread.start()

    def _run_background(self):
        asyncio.run(self._async_run())

    async def _async_run(self):
        try:
            async with stdio_client(self.server_params) as (read, write):
                async with ClientSession(read, write) as session:
                    await session.initialize()
                    self.session = session
                    tools_result = await session.list_tools()
                    self.tools = tools_result.tools
                    self.initialized.set()

                    while True:
                        try:
                            tool_name, arguments = self.request_queue.get(block=False)
                        except queue.Empty:
                            await asyncio.sleep(0.01)
                            continue

                        if tool_name is None:
                            break
                        try:
                            result = await session.call_tool(tool_name, arguments)
                            self.response_queue.put(result)
                        except Exception as e:
                            self.response_queue.put(f"错误: {str(e)}")
        except Exception as e:
            print("MCP会话初始化错误:", str(e))
            self.initialized.set()  # 即使初始化失败也解除等待线程的阻塞
            self.response_queue.put(f"MCP初始化错误: {str(e)}")

    def call_tool(self, tool_name: str, arguments: dict[str, Any]) -> Any:
        """
        发布工具调用请求并等待结果
        """
        if not self.initialized.wait(timeout=30):
            raise TimeoutError("MCP会话未能及时初始化。")
        self.request_queue.put((tool_name, arguments))
        result = self.response_queue.get()
        return result

    def shutdown(self):
        """
        干净地关闭持久会话
        """
        self.request_queue.put((None, None))
        self.thread.join()
        print("持久MCP会话已关闭。")


    @staticmethod
    def convert_json_type_to_python_type(json_type: str):
        """简单地将JSON类型映射到Python(Pydantic)类型。"""
        if json_type == "integer":
            return (int, ...)
        if json_type == "number":
            return (float, ...)
        if json_type == "string":
            return (str, ...)
        if json_type == "boolean":
            return (bool, ...)
        return (str, ...)

    def create_response_model(self):
        """
        基于获取的工具创建动态Pydantic响应模型
        """
        dynamic_classes = {}
        for tool in self.tools:
            class_name = tool.name.capitalize()
            properties: dict[str, Any] = {}
            for prop_name, prop_info in tool.inputSchema.get("properties", {}).items():
                json_type = prop_info.get("type", "string")
                properties[prop_name] = self.convert_json_type_to_python_type(json_type)

            model = create_model(
                class_name,
                __base__=BaseModel,
                __doc__=tool.description,
                **properties,
            )
            dynamic_classes[class_name] = model

        if dynamic_classes:
            all_tools_type = Union[tuple(dynamic_classes.values())]
            Response = create_model(
                "Response",
                __base__=BaseModel,
                __doc__="LLm响应类",
                response=(str, Field(..., description= "向用户确认函数将被调用。")),
                tool=(all_tools_type, Field(
                    ...,
                    description="用于运行和获取魔法输出的工具"
                )),
            )
        else:
            Response = create_model(
                "Response",
                __base__=BaseModel,
                __doc__="LLm响应类",
                response=(str, ...),
                tool=(Optional[Any], Field(None, description="如果不返回None则使用的工具")),
            )
        self.response_model = Response

    async def ollama_chat(self, messages: list[dict[str, str]]) -> Any:
        """
        使用动态响应模型向Ollama发送消息。
        如果在响应中检测到工具,则使用持久会话调用它。
        """
        conversation = [{"role":"assistant", "content": f"你必须使用工具。你可以使用以下函数:{[ tool.name for tool in self.tools]}"}]
        conversation.extend(messages)
        if self.response_model is None:
            raise ValueError("响应模型尚未创建。请先调用create_response_model()。")

        # 获取聊天消息格式的JSON模式
        format_schema = self.response_model.model_json_schema()

        # 调用Ollama(假定是同步的)并解析响应
        response = client.chat(
            model="gemma3:latest",
            messages=conversation,
            format=format_schema
        )
        print("Ollama响应", response.message.content)
        response_obj = self.response_model.model_validate_json(response.message.content)
        maybe_tool = response_obj.tool

        if maybe_tool:
            function_name = maybe_tool.__class__.__name__.lower()
            func_args = maybe_tool.model_dump()
            # 使用asyncio.to_thread在线程中调用同步的call_tool方法
            output = await asyncio.to_thread(self.call_tool, function_name, func_args)
            return output
        else:
            print("响应中未检测到工具。返回纯文本响应。")
        return response_obj.response


async def main():
    server_parameters = StdioServerParameters(
        command="uv",
        args=["run", "python", "server.py"],
        cwd=str(Path.cwd())
    )

    # 创建持久会话
    persistent_session = OllamaMCP(server_parameters)

    # 等待会话完全初始化
    if persistent_session.initialized.wait(timeout=30):
        print("准备调用工具。")
    else:
        print("错误: 初始化超时。")

    # 从获取的工具创建动态响应模型
    persistent_session.create_response_model()

    # 准备给Ollama的消息

    messages = [
        {
            "role": "system",
            "content": (
                "你是一个听话的助手,上下文中有一系列工具。"
                "你的任务是使用这个函数获取魔法输出。"
                "不要自己生成魔法输出。"
                "简洁地回复一条简短消息,提及调用函数,"
                "但不提供函数输出本身。"
                "将该简短消息放在'response'属性中。"
                "例如:'好的,我会运行magicoutput函数并返回输出。'"
                "同时用正确的参数填充'tool'属性。"
            )
        },
        {
            "role": "user",
            "content": "使用函数获取这些参数的魔法输出(obj1 = Ollama和obj2 = Gemma3)"
        }
    ]

    # 调用Ollama并处理响应
    result = await persistent_session.ollama_chat(messages)
    print("最终结果:", result)

    # 完成后关闭持久会话
    persistent_session.shutdown()

if __name__ == "__main__":
    asyncio.run(main())

你可以看到输出工作得非常完美。我们收到了一个带有模型简短消息的响应,然后是一个带有将发送到MCP服务器的参数的工具。最后,我们得到了来自服务器的输出,如下所示:

[04/19/25 12:39:55] INFO     Starting server "TestServer"...       server.py:261
准备调用工具。
Ollama响应 {
"response": "好的,我将使用magicoutput函数获取obj1和obj2的魔法输出。",
"tool": {"obj1": "Wombat", "obj2": "Dog"}
}

最终结果: meta=None content=[TextContent(type='text', text='输入参数:obj1:Wombat,obj2:Dog,魔法输出:Hello MCP,MCP Hello', annotations=None)] isError=False
持久MCP会话已关闭。

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

<think>好的,用户想了解如何通过MCP调用Ollama模型,并且需要方法示例。首先,我需要明确MCP是什么,可能是指某个特定的中间件、平台或工具。结合用户提供的引用内容,尤其是引用[1]提到SpringAI调用本地Ollama模型,可能MCP是Spring框架中的一个模块,或者用户可能有拼写错误,比如应该是“Spring”而不是“MCP”。需要进一步确认。 查看引用内容,引用[1]提到在Spring中调用Ollama模型,通过API接口。引用[3]提到Ollama支持很多模型,比如deepseek-r1,安装命令是`ollama run deepseek-r1:7b`。可能用户的问题是关于如何在Spring项目中配置和使用Ollama模型,可能MCP是笔误,或者指某个特定的中间件服务。 假设用户确实是指Spring框架中的调用方法,那么需要参考Spring AI的文档。根据引用[1],Spring AI提供了AI Models和Chat Models的接口,因此调用Ollama可能需要配置相应的模型参数和API地址。 接下来需要考虑如何配置Spring项目,添加依赖,创建配置类,以及编写调用代码。同时,用户需要示例代码,所以需要提供具体的Java或Kotlin代码片段,展示如何初始化Ollama的客户端,发送请求,处理响应。 另外,用户可能遇到的问题包括模型服务的启动、端口配置是否正确,以及如何处理不同的模型版本。需要确保Ollama服务在本地运行,并且端口正确(如默认的11434)。同时,模型名称需要与安装的模型一致,比如`deepseek-r1:7b`。 可能还需要解释配置文件中的参数,如baseUrl和model,以及如何通过Spring的依赖注入来获取OllamaClient实例。此外,可能需要处理异常情况,比如连接失败或模型未找到的情况。 最后,生成的相关问题需要围绕调用Ollama模型的其他方面,比如参数调优、流式响应处理、集成到Web应用,以及模型选择建议。这些问题可以帮助用户进一步深入使用Ollama模型。</think>### 通过MCP调用Ollama模型的方法示例 根据您提供的引用内容,推测"MCP"可能指向中间件服务或框架(如Spring框架中的模块),以下以**Spring AI调用本地Ollama模型**为例说明具体实现步骤: --- #### 步骤1:启动Ollama模型服务 首先确保已通过Ollama安装并运行所需模型(以deepseek-r1:7b为例): ```bash ollama run deepseek-r1:7b ``` 服务默认运行在`http://localhost:11434`[^3] --- #### 步骤2:Spring项目配置 1. **添加依赖**:在`pom.xml`中引入Spring AI模块 ```xml <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-ollama-spring-boot-starter</artifactId> <version>0.8.1</version> </dependency> ``` 2. **配置文件**:`application.yml` ```yaml spring: ai: ollama: base-url: http://localhost:11434 chat: model: deepseek-r1:7b ``` --- #### 步骤3:代码实现 ```java import org.springframework.ai.ollama.OllamaClient; import org.springframework.ai.ollama.api.OllamaApi; import org.springframework.ai.ollama.api.OllamaOptions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class OllamaController { private final OllamaClient ollamaClient; @Autowired public OllamaController(OllamaApi ollamaApi) { this.ollamaClient = new OllamaClient(ollamaApi); } @GetMapping("/ask") public String askQuestion(@RequestParam String prompt) { OllamaOptions options = OllamaOptions.create() .withTemperature(0.7f); return ollamaClient.generate(prompt, options).getGeneration().getText(); } } ``` --- #### 关键参数说明 1. `temperature`:控制生成文本的随机性(0-1) 2. `top_p`:核采样概率阈值 3. `max_tokens`:最大输出长度[^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值