1. 环境准备:为你的智能对话助手打好地基

想自己动手搭建一个能理解上下文、还能跟你聊得有来有回的智能对话应用吗?听起来很酷,但第一步往往就卡住了:环境怎么配?别担心,我带你一步步来,保证清晰无坑。咱们这个项目,核心就是让 LangChain 这个强大的 AI 应用框架,去调用 Ollama 本地部署的大语言模型。好处显而易见:数据安全,完全离线,想怎么定制就怎么定制,再也不用担心 API 调用次数和网络延迟了。

首先,我强烈建议你使用 Python 虚拟环境。这就像给你的项目单独准备一个“工作间”,里面所有的工具和材料都是独立的,不会跟其他项目搞混。我见过太多人因为没做环境隔离,导致各种依赖包版本冲突,最后项目跑不起来,排查起来头都大了。创建虚拟环境的方法很简单,现在 Python 3.3 以上版本都自带 venv 模块,用起来非常方便。

# 创建并激活虚拟环境(Linux/Mac)
python3 -m venv langchain_ollama_env
source langchain_ollama_env/bin/activate

# 创建并激活虚拟环境(Windows)
python3 -m venv langchain_ollama_env
langchain_ollama_env\Scripts\activate

激活成功后,你的命令行提示符前面会显示环境名,比如 (langchain_ollama_env),这就表示你已经在这个独立的工作间里了。接下来,确认一下你的 Python 版本,LangChain 对版本有一定要求,建议使用 Python 3.8 或更高版本。

python3 --version
pip3 --version

如果版本没问题,我们就可以开始安装核心的“武器库”了。这里有个小技巧,国内网络直接连 PyPI 可能会比较慢,我们可以使用国内的镜像源来加速,比如阿里云或者清华的镜像。下面这条命令会一次性安装我们需要的几个核心包:langchain 是主框架,langchain-community 包含了很多社区贡献的组件和集成,langchain-ollama 是专门用来连接 Ollama 的官方库,而 langchain-core 则提供了最基础、最核心的抽象和接口。

# 使用阿里云镜像加速安装核心依赖
pip3 install -U langchain langchain-community langchain-ollama langchain-core -i https://mirrors.aliyun.com/pypi/simple/

安装过程通常很快。完成之后,你可以用 pip list 命令看看这些包是否都成功安装好了。环境准备这一步,看似简单,但却是整个项目稳定运行的基石。花几分钟把它做好,能为你后面省下大量排查奇怪问题的时间。我自己的经验是,每开始一个新项目,不管多急,都先老老实实建个虚拟环境,这个习惯让我避开了无数坑。

1.1 安装并启动 Ollama 服务

LangChain 这边准备好了,我们还得把“大脑”——也就是大语言模型——给请过来。Ollama 就是一个让你能在自己电脑上轻松运行各种开源大模型的工具,它把复杂的模型部署过程简化成了一两条命令。首先,我们需要安装 Ollama 本身。官方提供了非常便捷的一键安装脚本。

# 一键下载并安装 Ollama
curl -fsSL https://ollama.ai/install.sh | sh

这条命令适用于 Linux 和 macOS。对于 Windows 用户,可以直接从 Ollama 官网下载安装程序,图形化安装也很简单。安装完成后,Ollama 通常会以后台服务的形式自动运行。但我们最好手动启动一下,并保持这个终端窗口打开,以便观察日志。

# 启动 Ollama 服务(通常安装后已自动运行,此命令用于手动启动或重启)
ollama serve

服务启动后,默认会在本地的 11434 端口监听。接下来就是“下载”模型了。Ollama 支持很多热门的开源模型,比如 Llama 3、Mistral、DeepSeek 等。你可以把它想象成一个模型应用商店,pull 命令就是下载安装。这里我以近期比较火的 deepseek-r1:8b 模型为例,它是一个 80 亿参数量的推理模型,在代码和逻辑任务上表现不错,而且对中文支持也很好,体积适中,适合本地运行。

# 从 Ollama 拉取 deepseek-r1:8b 模型
ollama pull deepseek-r1:8b

下载速度取决于你的网络和模型大小,deepseek-r1:8b 大概 5GB 左右,耐心等待一下。完成后,我们可以验证一下模型是否就绪。

# 查看本地已安装的模型列表
ollama list

# 直接与模型进行简单对话测试
ollama run deepseek-r1:8b "你好,请介绍一下自己"

如果测试命令能返回模型的一段自我介绍,那就恭喜你,模型服务已经成功跑起来了!有时候你可能需要从网络上的另一台机器(比如你的开发机)访问部署在服务器上的 Ollama,这就需要一点网络配置。Ollama 默认只允许本地访问,为了安全。如果你需要远程调用,可以修改它的服务配置。

# 编辑 Ollama 的 systemd 服务配置文件(假设你的系统使用 systemd)
sudo vim /etc/systemd/system/ollama.service

[Service] 部分,添加或修改环境变量,让 Ollama 监听所有网络接口,并允许跨域请求:

Environment="OLLAMA_HOST=0.0.0.0"
Environment="OLLAMA_ORIGINS=*"

保存退出后,重新加载配置并重启服务:

sudo systemctl daemon-reload
sudo systemctl restart ollama

注意:在生产环境或公网环境下,将 OLLAMA_ORIGINS 设置为 * 和监听 0.0.0.0 存在安全风险,务必结合防火墙或反向代理进行安全加固。对于本地开发和学习,这样设置问题不大。好了,到现在为止,LangChain 的 Python 环境和 Ollama 模型服务都已经准备就绪,两个核心部件已经点亮,接下来就是让它们握手合作的时候了。

2. 初识 LangChain 与 Ollama:你的第一个对话程序

环境搭好了,是不是有点手痒,想赶紧写几行代码看看效果?这一部分,我们就来写一个最简单的对话程序,感受一下 LangChain 调用 Ollama 是多么的直截了当。很多教程喜欢一上来就讲复杂的概念,我觉得不如先跑通一个“Hello World”级别的例子,有了成就感,再深入理解背后的原理会容易得多。

首先,我们在项目目录下创建一个 Python 文件,比如叫 first_chat.py。然后,我们需要从 langchain_ollama 中导入 ChatOllama 这个类,它就是我们连接 Ollama 服务的桥梁。同时,从 langchain_core.messages 里导入 HumanMessage,这是 LangChain 里用来表示用户输入消息的标准格式。

# first_chat.py
from langchain_ollama import ChatOllama
from langchain_core.messages import HumanMessage

接下来,初始化我们的聊天模型。关键参数就两个:base_urlmodelbase_url 就是你的 Ollama 服务地址,如果 Ollama 和你的 Python 代码运行在同一台机器上,默认就是 http://localhost:11434 或者 http://127.0.0.1:11434model 就是你刚才用 ollama pull 下载的模型名称,必须完全一致。

# 初始化聊天模型,连接到本地的 Ollama 服务
llm = ChatOllama(
    base_url="http://127.0.0.1:11434",
    model="deepseek-r1:8b"
)

初始化完成,就可以开始对话了。我们调用模型的 invoke 方法,并传入一个消息列表。对于单次对话,列表里只需要一个 HumanMessage 对象,其 content 就是我们的问题。

# 构造用户消息
user_message = HumanMessage(content="请用一句话解释人工智能是什么。")

# 调用模型获取回复
response = llm.invoke([user_message])

# 打印模型的回复内容
print("AI回复:", response.content)

保存文件,然后在激活了虚拟环境的终端里运行它:python first_chat.py。稍等片刻,你应该就能在终端里看到模型的回复了。我跑的时候,它除了给出“人工智能是让机器模拟人类智能行为的技术”这样的答案,前面还附带了一大段 <think>...</think> 的“内心独白”。这是 DeepSeek-R1 模型的一个特点,它会把推理过程也输出出来,非常有意思,能让你看到模型是怎么一步步思考得出最终结论的。如果你觉得这个“思考过程”干扰了输出,可以在初始化模型时通过 model_kwargs 参数来关闭它,例如 ChatOllama(model="deepseek-r1:8b", model_kwargs={"reasoning_effort": "off"})

这个简单的例子虽然只有十来行代码,但它已经完成了最核心的流程:连接服务、发送请求、解析回复。你可以试着修改 HumanMessage 里的问题,问点别的,比如“讲个笑话”或者“写一首关于春天的诗”,看看模型的反应。通过这个练习,你就能直观地感受到,把一个强大的大语言模型集成到你的程序里,原来可以这么简单。LangChain 帮我们封装了所有底层的网络通信和协议细节,我们只需要关心业务逻辑。

2.1 使用提示模板:让对话更专业、更可控

直接问问题虽然方便,但如果我们想让 AI 扮演某个特定角色,或者按照固定格式回答,每次都手动拼接提示词会很麻烦。比如,你想让 AI 扮演一个专业厨师来讲解菜谱,或者扮演一个代码评审员来检查代码。这时候,LangChain 的 提示模板(Prompt Template) 就派上用场了。

提示模板允许你预定义一个带有“占位符”的文本结构。比如,我们可以创建一个厨师模板:“你是一个专业厨师。请用简单步骤解释如何烹饪:{dish}。” 这里的 {dish} 就是一个占位符,在实际调用时,我们再传入具体的菜名,比如“红烧肉”。这样做的好处是,模板可以复用,逻辑更清晰,也便于管理。

让我们来改造一下之前的代码,引入提示模板。首先,需要从 langchain_core.prompts 导入 ChatPromptTemplate

# prompt_template_demo.py
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate

# 初始化模型(和之前一样)
llm = ChatOllama(
    base_url="http://127.0.0.1:11434",
    model="deepseek-r1:8b"
)

# 定义提示模板。{dish} 是变量,调用时传入具体值。
template = "你是一个专业厨师,拥有20年经验。请用不超过5个核心步骤,向厨房新手解释如何烹饪:{dish}。"
prompt = ChatPromptTemplate.from_template(template)

定义好模板后,我们可以用 | 操作符(在 LangChain 中称为 LCEL,LangChain Expression Language)把模板和模型“连接”起来,形成一个链(Chain)。这个链的输入是包含变量的字典,输出就是模型的回复。

# 创建链:模板 -> 模型
chain = prompt | llm

# 调用链,并传入具体的菜名
result = chain.invoke({"dish": "西红柿炒鸡蛋"})
print(result.content)

运行这段代码,你会得到一份以专业厨师口吻、步骤清晰的西红柿炒鸡蛋菜谱。通过模板,我们轻松地给 AI 设定了角色和回答格式。你可以尝试把 {dish} 换成“麻婆豆腐”、“清蒸鲈鱼”,看看效果。模板的威力远不止于此,你可以设计非常复杂的模板,包含系统指令、上下文、示例对话(Few-shot)等等,从而精准地控制模型的输出行为。这是构建可靠 AI 应用的关键一步。

3. 构建对话记忆:实现真正的多轮聊天

我们之前写的程序,每次对话都是独立的,模型并不记得你上一句说了什么。这显然不是一个合格的“对话助手”。真正的智能对话需要记忆(Memory) 功能,让模型能记住整个对话的历史上下文。LangChain 提供了多种记忆组件,最简单也最常用的就是 ConversationBufferMemory,它就像一个聊天记录本,会把所有历史对话都保存下来。

让我们来创建一个具有记忆功能的对话链。首先,需要导入记忆相关的模块。

# memory_chat.py
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory

MessagesPlaceholder 是一个特殊的提示组件,它会在模板中为历史对话消息预留位置。ConversationChain 是一个高级的链,它专门为对话场景设计,可以方便地集成记忆功能。ConversationBufferMemory 则是具体的内存实现。

接下来,我们初始化模型、记忆,并构建一个包含记忆位置的提示模板。

# 1. 初始化模型
llm = ChatOllama(
    base_url="http://127.0.0.1:11434",
    model="deepseek-r1:8b"
)

# 2. 初始化记忆。return_messages=True 确保记忆以消息格式存储。
memory = ConversationBufferMemory(return_messages=True)

# 3. 构建提示模板。`chat_history` 是 MessagesPlaceholder 的变量名。
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个乐于助人且知识渊博的助手。"),
    MessagesPlaceholder(variable_name="chat_history"), # 历史对话将插入这里
    ("human", "{input}"), # 当前用户输入
])

# 4. 创建对话链
conversation = ConversationChain(
    llm=llm,
    memory=memory,
    prompt=prompt,
    verbose=True # 设置为 True 可以看到链的详细执行过程,调试时很有用
)

现在,我们可以开始进行多轮对话了。使用 conversation.predict(input="...") 方法来发送消息,记忆会自动更新。

# 第一轮对话
response1 = conversation.predict(input="你好,我叫小明。")
print("AI:", response1)

# 第二轮对话,AI会记得我的名字
response2 = conversation.predict(input="你还记得我叫什么吗?")
print("AI:", response2)

# 第三轮,可以基于之前的上下文继续
response3 = conversation.predict(input="你能用我的名字写一句诗吗?")
print("AI:", response3)

运行这段代码,你会看到 AI 在第二轮对话中准确地回答出了你的名字“小明”,并且在第三轮中尝试用这个名字创作诗句。如果你设置了 verbose=True,在终端里还能看到 LangChain 内部是如何将历史记录和当前问题组合成完整的提示词发送给模型的,这对于理解和调试非常有帮助。

ConversationBufferMemory 会把所有对话都存下来,对于长对话,这可能会导致提示词过长,超出模型上下文窗口,或者增加不必要的计算开销。因此,LangChain 还提供了其他记忆类型,比如 ConversationSummaryMemory(只保存对话的摘要)、ConversationBufferWindowMemory(只保存最近 K 轮对话)等。你可以根据实际应用场景选择。对于大多数简单的聊天机器人,ConversationBufferMemory 已经足够好用了。通过引入记忆,我们的应用终于有了“连续性”,开始像一个真正的对话助手了。

3.1 深入对话链:自定义更复杂的交互逻辑

ConversationChain 虽然方便,但有时候我们需要更精细地控制对话流程。比如,我们可能想在用户提问后,先根据历史记录去数据库查询一些相关信息,再把查询结果和问题一起交给模型回答。这就需要我们自定义链(Custom Chain)。别被“自定义”吓到,利用 LangChain 的 LCEL,这其实非常直观。

假设我们想构建一个“餐厅推荐助手”,它不仅能聊天,还能根据用户提到的菜品偏好,“偷偷”去一个模拟的菜品数据库里查询匹配的餐厅。我们来模拟这个场景。

首先,我们定义一个虚拟的“数据库查询函数”。在实际项目中,这里会是真正的数据库调用。

# custom_chain_demo.py
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# 初始化模型
llm = ChatOllama(model="deepseek-r1:8b", base_url="http://127.0.0.1:11434")

# 1. 模拟一个根据菜品查询餐厅的函数
def query_restaurant_by_dish(dish: str) -> str:
    # 这里模拟一个简单的数据库映射
    restaurant_db = {
        "火锅": "推荐‘海底捞’和‘小龙坎’,服务好,口味正宗。",
        "披萨": "推荐‘必胜客’和‘达美乐’,外卖速度快,种类多。",
        "寿司": "推荐‘元气寿司’和‘将太无二’,食材新鲜,环境优雅。",
        "烧烤": "推荐‘木屋烧烤’和‘很久以前羊肉串’,氛围热闹,味道棒。"
    }
    return restaurant_db.get(dish, f"抱歉,暂时没有找到专门做{dish}的推荐餐厅。")

# 2. 定义提示模板
prompt_template = ChatPromptTemplate.from_messages([
    ("system", "你是一个美食推荐助手。请根据用户想吃的菜品和以下餐厅信息,给出亲切的推荐。"),
    ("human", "我想吃{dish}。\n餐厅信息:{restaurant_info}")
])

# 3. 使用 LCEL 构建自定义链
chain = (
    {"dish": RunnablePassthrough(), # 直接传递用户输入的菜品
     "restaurant_info": lambda x: query_restaurant_by_dish(x["dish"])} # 根据菜品查询信息
    | prompt_template
    | llm
    | StrOutputParser() # 将模型输出解析为字符串
)

# 4. 调用链
result = chain.invoke("火锅")
print(result)

这段代码的精髓在于链的构建部分。我们用字典定义了一个数据流:RunnablePassthrough() 表示直接把输入(这里就是字符串“火锅”)作为 dish 的值传递下去。同时,我们用一个匿名函数 lambda 捕获这个 dish 值,并调用 query_restaurant_by_dish 函数得到 restaurant_info。然后,dishrestaurant_info 这两个值会被填充到提示模板中对应的位置 {dish}{restaurant_info},形成完整的提示词,再交给模型生成回复。

运行后,输出可能是:“您好!根据您的需求,想吃火锅的话,我为您推荐‘海底捞’和‘小龙坎’。海底捞以其极致的服务和多样的锅底闻名,而小龙坎则有着地道的川味火锅风味。两家餐厅都非常受欢迎,建议您根据距离和排队情况选择哦!”

这个例子展示了如何将外部工具(数据库查询)无缝集成到对话流程中。你可以把 query_restaurant_by_dish 替换成任何函数,比如调用天气 API、查询股票信息、搜索文档等等。通过 LCEL,你可以像搭积木一样,组合出非常复杂和强大的 AI 应用逻辑,而代码依然保持清晰和可维护性。

4. 进阶实战:打造一个具备文件处理能力的智能助手

前面的例子都是处理文本对话。但在真实场景中,我们经常需要让 AI 处理我们提供的文件内容,比如分析一份 PDF 报告、总结一篇网页文章,或者从 CSV 数据中提取洞察。这就需要用到 LangChain 的文档加载器(Document Loaders)文本分割器(Text Splitters)。这一部分,我们来实战构建一个能读取本地文本文件并回答相关问题的小助手。

首先,我们需要安装处理文档可能需要的额外依赖。LangChain 社区提供了大量针对不同文件格式的加载器。

pip install langchain-text-splitters pypdf  # 用于处理PDF和文本分割

假设我们有一个 report.txt 文件,里面是一份简单的项目周报。我们想让 AI 助手读这份报告,然后回答我们的问题。步骤如下:1. 加载文档;2. 将长文档分割成小块(因为模型有上下文长度限制);3. 将文档块转换成向量并存储(为了快速检索);4. 用户提问时,先检索相关文档块,再交给模型生成答案。这个过程就是经典的 RAG(检索增强生成) 的简化版。

我们先完成前两步:加载和分割。

# rag_assistant.py
from langchain_ollama import ChatOllama, OllamaEmbeddings
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate

# 1. 加载文档
loader = TextLoader("./report.txt", encoding="utf-8")
documents = loader.load()

# 2. 分割文档
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,  # 每个块大约500字符
    chunk_overlap=50  # 块之间重叠50字符,避免上下文断裂
)
texts = text_splitter.split_documents(documents)
print(f"将文档分割成了 {len(texts)} 个块。")

RecursiveCharacterTextSplitter 是常用的分割器,它会尝试按段落、句子、单词等层级递归分割,尽量保持语义的完整性。chunk_sizechunk_overlap 需要根据你的模型上下文窗口和文档特点调整。

接下来是第三步:向量化存储。我们需要一个嵌入模型(Embedding Model)把文本转换成向量,以及一个向量数据库来存储和检索它们。幸运的是,Ollama 也提供了嵌入模型,我们可以用 OllamaEmbeddings 来调用。这里我们用 Chroma 作为向量数据库,它轻量且易于使用。

# 3. 创建向量存储
embeddings = OllamaEmbeddings(
    base_url="http://127.0.0.1:11434",
    model="nomic-embed-text"  # 一个高效的嵌入模型,需要先运行 `ollama pull nomic-embed-text`
)

# 将分割后的文本转换为向量并存入 Chroma
vectorstore = Chroma.from_documents(
    documents=texts,
    embedding=embeddings,
    persist_directory="./chroma_db"  # 向量数据库持久化目录
)
# 后续可以直接加载,无需重复计算:vectorstore = Chroma(persist_directory="./chroma_db", embedding_function=embeddings)

这里我们使用了 nomic-embed-text 模型来生成嵌入向量,你需要先用 ollama pull nomic-embed-text 命令下载它。Chroma.from_documents 方法会完成向量计算和存储,persist_directory 参数指定了数据库保存到本地磁盘的路径。

最后一步,创建检索问答链。RetrievalQA 是 LangChain 提供的一个高级链,它封装了“检索相关文档 -> 组合提示词 -> 调用模型 -> 返回答案”的完整流程。

# 4. 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})  # 每次检索返回最相关的2个文档块

# 5. 定义自定义提示模板,告诉模型如何利用检索到的上下文
custom_prompt = PromptTemplate.from_template(
    """请根据以下上下文信息回答问题。如果你不知道答案,就说你不知道,不要编造答案。

上下文:
{context}

问题:{question}
答案:"""
)

# 6. 初始化大语言模型
llm = ChatOllama(model="deepseek-r1:8b", base_url="http://127.0.0.1:11434", temperature=0)

# 7. 创建检索问答链
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",  # 将检索到的所有文档“塞”进提示词
    retriever=retriever,
    chain_type_kwargs={"prompt": custom_prompt},
    return_source_documents=True  # 返回参考的来源文档,便于验证
)

# 8. 进行问答
question = "本周项目进展如何?主要完成了哪些任务?"
result = qa_chain.invoke({"query": question})
print("问题:", question)
print("答案:", result["result"])
print("\n参考来源:")
for doc in result["source_documents"]:
    print(f"- {doc.page_content[:200]}...")  # 打印每个来源文档的前200字符

运行这个脚本,它会读取你的 report.txt,建立向量索引,然后根据你的问题,从报告中找到相关信息片段,并生成一个准确的答案。temperature=0 让模型的输出更确定、更忠于上下文。chain_type="stuff" 是最简单直接的方式,把所有检索到的文档内容都放入提示词。对于更长的文档,你可能需要考虑 map_reducerefine 等更复杂的处理方式。

这个例子虽然只处理了文本文件,但思路是通用的。你可以轻松更换 TextLoaderPyPDFLoaderCSVLoaderUnstructuredHTMLLoader 等,来处理 PDF、Excel、网页等各种格式的文件。通过结合文档加载、向量检索和大语言模型,你就能打造出真正“懂你资料”的个性化智能助手,无论是知识库问答、文档总结还是数据分析,都能胜任。

4.1 优化与部署考量:让应用更健壮、更可用

走到这一步,一个功能完整的智能对话应用原型已经有了。但在真正投入使用前,我们还需要考虑一些优化和部署的实际问题。首先就是性能。本地运行大模型,尤其是进行向量检索,对硬件有一定要求。如果你的文档库很大,全部加载到内存的向量数据库可能吃不消。这时可以考虑使用 Chroma 的持久化模式(我们上面已经用了),或者换用 FAISSWeaviate 等支持磁盘索引或服务化部署的向量数据库。

其次,提示工程(Prompt Engineering) 是影响模型输出质量的关键。我们之前用的提示词都比较简单。在实践中,你需要精心设计系统指令和用户提示的格式。例如,明确告诉模型“请用中文回答”、“答案请分点列出”、“如果信息不足,请明确指出”。多做一些测试,根据模型的反馈不断迭代你的提示词。对于 RAG 应用,一个常见的技巧是在提示词中要求模型“严格基于提供的上下文回答”,并在答案后“引用上下文中的段落编号”,这能大大提高答案的准确性和可追溯性。

第三,错误处理与稳定性。网络可能不稳定,Ollama 服务可能重启,模型可能一时“卡住”。在你的应用代码中,需要对 invoke 调用添加重试机制和超时设置。可以使用 tenacity 库进行重试,或者使用 LangChain 自带的 RunnableWithRetry 包装器。

from langchain_core.runnables import RunnableWithRetry

# 为链添加重试逻辑
robust_chain = qa_chain.with_retry(
    stop_after_attempt=3,
    wait_exponential_jitter=True
)

最后,关于部署。如果你只是自己用,在本地运行 Python 脚本就够了。但如果想提供给团队或用户使用,可以考虑用 FastAPIGradio 快速搭建一个 Web 界面。用 FastAPI 可以将你的链包装成 RESTful API,而 Gradio 则能在几分钟内生成一个带有聊天界面的 Web 应用,特别适合演示和内部测试。将 Ollama 服务部署在一台性能较好的服务器上,你的应用通过网络调用它,这样可以实现计算资源的分离和更灵活的扩展。

我自己的项目在从原型走向实际使用的过程中,大部分时间都花在了这些“非核心”的优化上:调整提示词让回答更符合业务要求,增加日志记录以便排查问题,设计更友好的用户交互界面。技术集成本身,有了 LangChain 和 Ollama 这样的工具,已经变得前所未有的简单。剩下的就是结合你的具体场景,不断地打磨和迭代。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐