网站项目风险,wordpress 强制更新,最近的新闻大事,长春网站怎么推广在大语言模型 (LLMs) 的应用中#xff0c;我们面临众多挑战#xff0c;包括领域知识的缺乏、信息的准确性问题以及生成的虚假内容。检索增强生成 (RAG) 通过引入外部知识库等额外信息源#xff0c;为这些问题提供了有效的缓解策略。RAG 在那些需要不断更新知识的知识密集型场… 在大语言模型 (LLMs) 的应用中我们面临众多挑战包括领域知识的缺乏、信息的准确性问题以及生成的虚假内容。检索增强生成 (RAG) 通过引入外部知识库等额外信息源为这些问题提供了有效的缓解策略。RAG 在那些需要不断更新知识的知识密集型场景或特定领域应用中尤为有效。与其他方法相比RAG 的一大优势是无需针对特定任务重新训练大语言模型。RAG 系统的核心组成部分包括检索、生成和增强三大环节。 检索增强生成Retrieval Augmented Generation简称 RAG。是通过自有垂域数据库检索相关信息然后合并成为提示模板给大模型生成漂亮的回答。RAG是一个将输入与一组相关的支持文档结合起来的技术这些文档通常来自于像维基百科这样的来源。这些文档被添加到输入提示中一起送入文本生成器从而产生最终的输出。RAG的这一机制特别适用于需要应对信息不断更新的场景因为大语言模型LLM所依赖的参数知识本质上是静态的。通过RAG语言模型可以不经过重新训练而直接访问最新信息以便生成可靠的、基于检索的输出。 RAG通过检索到的证据来提高LLM响应的准确性、可控性和相关性这对于在快速变化的环境中解决问题尤其有价值能有效减少错误信息生成和性能下降的问题。具体步骤如下 输入 是指LLM系统需要回答的问题。如果不使用RAG问题直接由LLM回答。索引 使用RAG时会先将相关文档分块为这些块生成嵌入向量并将它们索引到向量库中。在进行查询时查询内容也会以相似的方式进行嵌入。检索 通过比较查询内容与索引向量找到相关的文档。生成 将找到的相关文档与原始提示结合作为额外上下文然后传递给模型进行回应生成最终形成系统对用户的回答。 初级 RAG 采用了一个传统过程包括索引建立、文档检索和内容生成。简单来说系统根据用户的输入查询相关文档然后将这些文档和一个提示语结合起来交给模型生成最终的回答。如果涉及到多轮对话还可以将对话历史整合到提示语中。 初级 RAG 的局限性包括低精确度检索到的信息不够准确和低召回率有时候无法检索到所有相关的信息。此外有时候模型可能会接收到过时的信息这正是 RAG 系统希望首先解决的问题之一。这可能会导致模型产生不基于事实的幻想性回答从而影响回答的准确性和可靠性。当引入额外信息以增强回答时还可能出现信息重复或冗余的问题。处理多个检索到的文档时如何排列它们的优先级以及如何使生成的内容风格和语调一致也是需要考虑的挑战。我们还需要确保生成的任务不会过分依赖于这些额外信息避免模型仅仅重复这些信息而缺乏创新。 高级 RAG 解决了初级 RAG 面临的问题尤其是在提高检索质量方面包括优化检索前、检索时和检索后的各个过程。在检索前的准备阶段我们通过优化数据的索引建立来提高数据质量包括改善数据的细节度、优化索引结构、添加元数据、改进对齐方式以及混合检索方法。 在检索阶段我们可以通过改进嵌入模型来提高上下文片段的质量。例如通过对嵌入模型进行微调以提高检索的相关性或者使用能够更好理解上下文的动态嵌入模型如 OpenAI 的 embeddings-ada-02 模型。在检索后的优化过程中我们专注于解决上下文窗口限制和减少噪音或分散注意力的信息。常用的方法包括重新排列文档以将更相关的内容放在提示的前后或者重新计算查询与文档片段之间的语义相似度。此外通过压缩提示信息也有助于解决这些问题。 模块化 RAG顾名思义通过增强其功能模块来提升性能例如加入相似性检索的搜索模块以及在检索工具上进行精细调整。模块化 RAG 能够根据具体的任务需求添加、替换或调整模块之间的工作流程从而实现更高的多样性和灵活性。这种设计让模块化 RAG 不仅包括了朴素 RAG 和高级 RAG 这两种固定模式还扩展了包括搜索、记忆、融合、路由、预测和任务适配等多种模块以解决各种问题。随着 RAG 系统构建变得更加灵活一系列优化技术相继被提出用于进一步优化 RAG 流程包括 混合式搜索探索 结合了关键词搜索与语义搜索等多种搜索技术以便检索到既相关又富含上下文的信息特别适用于处理多样化的查询类型和信息需求。递归式检索与查询引擎 通过从小的语义片段开始逐步检索更大的内容块以丰富上下文的递归过程有效平衡了检索效率与信息的丰富度。StepBack-prompt 提示技术 一种特殊的提示方法能让大语言模型进行概念和原则的抽象化处理从而引导更加深入的推理过程。当应用于 RAG 框架时能够帮助模型超越具体事例进行更广泛的推理。子查询策略 采用树状查询或按序查询小块信息的不同策略适用于多种场景。LlamaIndex 提供的子问题查询引擎允许将大的查询任务拆分成多个小问题分别利用不同的数据源进行解答。假设性文档嵌入技术 (HyDE) 通过生成查询的假设性回答并嵌入来检索与这个假设回答相似的文档而不是直接使用查询本身以此来优化检索效果。 一句话总结RAG中文为检索增强生成 检索技术 LLM 提示。例如我们向 LLM 提问一个问题answerRAG 从各种数据源检索相关的信息并将检索到的信息和问题answer注入到 LLM 提示中LLM 最后给出答案。完整的RAG应用流程主要包含两个阶段 数据准备阶段数据提取——文本分割——向量化embedding——数据入库应用阶段用户提问——数据检索召回——注入Prompt——LLM生成答案 数据准备一般是一个离线的过程主要是将私域数据向量化后构建索引并存入数据库的过程。主要包括数据提取、文本分割、向量化、数据入库等环节。 数据提取数据加载包括多格式数据加载、不同数据源获取等根据数据自身情况将数据处理为同一个范式。数据处理包括数据过滤、压缩、格式化等。元数据获取提取数据中关键信息例如文件名、Title、时间等 。文本分割文本分割主要考虑两个因素1embedding模型的Tokens限制情况2语义完整性对整体的检索效果的影响。一些常见的文本分割方式如下句分割以”句”的粒度进行切分保留一个句子的完整语义。常见切分符包括句号、感叹号、问号、换行符等。固定长度分割根据embedding模型的token长度限制将文本分割为固定长度例如256/512个tokens这种切分方式会损失很多语义信息一般通过在头尾增加一定冗余量来缓解。向量化embedding是一个将文本数据转化为向量矩阵的过程该过程会直接影响到后续检索的效果。**数据入库**数据向量化后构建索引并写入数据库的过程可以概述为数据入库过程适用于RAG场景的数据库包括FAISS、Chromadb、ES、milvus等。一般可以根据业务场景、硬件、性能需求等多因素综合考虑选择合适的数据库。 构建 RAG 应用 将LLM 接入 LangChainLangChain 为基于 LLM 开发自定义应用提供了高效的开发框架便于开发者迅速地激发 LLM 的强大能力搭建 LLM 应用。LangChain 也同样支持多种大模型内置了 OpenAI、LLAMA 等大模型的调用接口。但是LangChain 并没有内置所有大模型它通过允许用户自定义 LLM 类型来提供强大的可扩展性。LangChain 提供了对于多种大模型的封装基于 LangChain 的接口可以便捷地调用 ChatGPT 并将其集合在以 LangChain 为基础框架搭建的个人应用中。基于 LangChain 接口调用 ChatGPT 同样需要配置你的个人密钥。 import os
import openai
from dotenv import load_dotenv, find_dotenv
# 读取本地/项目的环境变量。
# find_dotenv()寻找并定位.env文件的路径
# load_dotenv()读取该.env文件并将其中的环境变量加载到当前的运行环境中
# 如果你设置的是全局的环境变量这行代码则没有任何作用。
_ load_dotenv(find_dotenv())
# 获取环境变量 OPENAI_API_KEY
openai_api_key os.environ[OPENAI_API_KEY]接下来你需要实例化一个 ChatOpenAI 类可以在实例化时传入超参数来控制回答例如 temperature 参数。 # 这里我们将参数temperature设置为0.0从而减少生成答案的随机性。
# 如果你想要每次得到不一样的有新意的答案可以尝试调整该参数。
llm ChatOpenAI(temperature0.0)
llm ChatOpenAI(temperature0, openai_api_keyYOUR_API_KEY)
output llm.invoke(请你自我介绍一下自己)默认调用的是 ChatGPT-3.5 模型。另外几种常用的超参数设置包括 model_name所要使用的模型默认为 ‘gpt-3.5-turbo’参数设置与 OpenAI 原生接口参数设置一致。temperature温度系数取值同原生接口。openai_api_keyOpenAI API key如果不使用环境变量设置 API Key也可以在实例化时设置。openai_proxy设置代理如果不使用环境变量设置代理也可以在实例化时设置。streaming是否使用流式传输即逐字输出模型回答默认为 False此处不赘述。max_tokens模型输出的最大 token 数意义及取值同上。 在我们开发大模型应用时大多数情况下不会直接将用户的输入直接传递给 LLM。通常他们会将用户输入添加到一个较大的文本中称为提示模板该文本提供有关当前特定任务的附加上下文。 PromptTemplates 正是帮助解决这个问题它们捆绑了从用户输入到完全格式化的提示的所有逻辑。这可以非常简单地开始 - 例如生成上述字符串的提示就是 from langchain_core.prompts import ChatPromptTemplate
# 这里我们要求模型对给定文本进行中文翻译
prompt 请你将由三个反引号分割的文本翻译成英文\
text: {text}text 我带着比身体重的行李\
游入尼罗河底\
经过几道闪电 看到一堆光圈\
不确定是不是这里。\prompt.format(texttext)我们知道聊天模型的接口是基于消息message而不是原始的文本。PromptTemplates 也可以用于产生消息列表在这种样例中prompt不仅包含了输入内容信息也包含了每条message的信息(角色、在列表中的位置等)。通常情况下一个 ChatPromptTemplate 是一个 ChatMessageTemplate 的列表。每个 ChatMessageTemplate 包含格式化该聊天消息的说明其角色以及内容。 from langchain.prompts.chat import ChatPromptTemplate
template 你是一个翻译助手可以帮助我将 {input_language} 翻译成 {output_language}.
human_template {text}
chat_prompt ChatPromptTemplate.from_messages([(system, template),(human, human_template),
])
text 我带着比身体重的行李\
游入尼罗河底\
经过几道闪电 看到一堆光圈\
不确定是不是这里。\messages chat_prompt.format_messages(input_language中文, output_language英文, texttext)
output llm.invoke(messages)OutputParsers 将语言模型的原始输出转换为可以在下游使用的格式。 OutputParsers 有几种主要类型包括 将 LLM 文本转换为结构化信息例如 JSON将 ChatMessage 转换为字符串将除消息之外的调用返回的额外信息如 OpenAI 函数调用转换为字符串 最后我们将模型输出传递给 output_parser它是一个 BaseOutputParser这意味着它接受字符串或 BaseMessage 作为输入。 StrOutputParser 特别简单地将任何输入转换为字符串。通过输出解析器成功将 ChatMessage 类型的输出解析为了字符串。 from langchain_core.output_parsers import StrOutputParser
output_parser StrOutputParser()
output_parser.invoke(output)现在可以将所有这些组合成一条链。该链将获取输入变量将这些变量传递给提示模板以创建提示将提示传递给语言模型然后通过可选输出解析器传递输出。接下来我们将使用LCEL这种语法去快速实现一条链chain。 chain chat_prompt | llm | output_parser
chain.invoke({input_language:中文, output_language:英文,text: text})构建检索问答链 首先我们加载已经构建的向量数据库。注意此处你需要使用和构建时相同的 Emedding。从环境变量中加载你的 API_KEY import sys
sys.path.append(../C3 搭建知识库) # 将父目录放入系统路径中
# 使用智谱 Embedding API注意需要将上一章实现的封装代码下载到本地
from zhipuai_embedding import ZhipuAIEmbeddings
from langchain.vectorstores.chroma import Chroma
from dotenv import load_dotenv, find_dotenv
import os
_ load_dotenv(find_dotenv()) # read local .env file
zhipuai_api_key os.environ[ZHIPUAI_API_KEY]加载向量数据库其中包含了 …/…/data_base/knowledge_db 下多个文档的 Embedding # 定义 Embeddings
embedding ZhipuAIEmbeddings()
# 向量数据库持久化路径
persist_directory ../C3 搭建知识库/data_base/vector_db/chroma
# 加载数据库
vectordb Chroma(persist_directorypersist_directory, # 允许我们将persist_directory目录保存到磁盘上embedding_functionembedding
)
print(f向量库中存储的数量{vectordb._collection.count()})可以测试一下加载的向量数据库使用一个问题 query 进行向量检索。如下代码会在向量数据库中根据相似性进行检索返回前 k 个最相似的文档。使用相似性搜索前请确保你已安装了 OpenAI 开源的快速分词工具 tiktoken 包pip install tiktoken question 什么是prompt engineering?
docs vectordb.similarity_search(question,k3)
print(f检索到的内容数{len(docs)})
for i, doc in enumerate(docs):print(f检索到的第{i}个内容: \n {doc.page_content}, end\n-----------------------------------------------------\n)调用 OpenAI 的 API 创建一个 LLM import os
OPENAI_API_KEY os.environ[OPENAI_API_KEY]
from langchain_openai import ChatOpenAI
llm ChatOpenAI(model_name gpt-3.5-turbo, temperature 0)
llm.invoke(请你自我介绍一下自己)构建检索问答链 from langchain.prompts import PromptTemplate
template 使用以下上下文来回答最后的问题。如果你不知道答案就说你不知道不要试图编造答
案。最多使用三句话。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问”。
{context}
问题: {question}QA_CHAIN_PROMPT PromptTemplate(input_variables[context,question], templatetemplate)
from langchain.chains import RetrievalQAqa_chain RetrievalQA.from_chain_type(llm,retrievervectordb.as_retriever(),return_source_documentsTrue,chain_type_kwargs{prompt:QA_CHAIN_PROMPT})创建检索 QA 链的方法 RetrievalQA.from_chain_type() 有如下参数 llm指定使用的 LLM指定 chain type : RetrievalQA.from_chain_type(chain_type“map_reduce”)也可以利用load_qa_chain()方法指定chain type。自定义 prompt 通过在RetrievalQA.from_chain_type()方法中指定chain_type_kwargs参数而该参数chain_type_kwargs {“prompt”: PROMPT}返回源文档通过RetrievalQA.from_chain_type()方法中指定return_source_documentsTrue参数也可以使用RetrievalQAWithSourceChain()方法返回源文档的引用坐标或者叫主键、索引 基于召回结果和 query 结合起来构建的 prompt 效果 question_1 什么是南瓜书
question_2 王阳明是谁
result qa_chain({query: question_1})
print(大模型知识库后回答 question_1 的结果)
print(result[result])
result qa_chain({query: question_2})
print(大模型知识库后回答 question_2 的结果)
print(result[result])大模型自己回答的效果 prompt_template 请回答下列问题:{}.format(question_1)
### 基于大模型的问答
llm.predict(prompt_template)
prompt_template 请回答下列问题:{}.format(question_2)
### 基于大模型的问答
llm.predict(prompt_template)通过以上两个问题我们发现 LLM 对于一些近几年的知识以及非常识性的专业问题回答的并不是很好。而加上我们的本地知识就可以帮助 LLM 做出更好的回答。另外也有助于缓解大模型的“幻觉”问题。 现在我们已经实现了通过上传本地知识文档然后将他们保存到向量知识库通过将查询问题与向量知识库的召回结果进行结合输入到 LLM 中我们就得到了一个相比于直接让 LLM 回答要好得多的结果。在与语言模型交互时你可能已经注意到一个关键问题 - 它们并不记得你之前的交流内容。这在我们构建一些应用程序如聊天机器人的时候带来了很大的挑战使得对话似乎缺乏真正的连续性。将介绍 LangChain 中的储存模块即如何将先前的对话嵌入到语言模型中的使其具有连续对话的能力。我们将使用 ConversationBufferMemory 它保存聊天消息历史记录的列表这些历史记录将在回答问题时与问题一起传递给聊天机器人从而将它们添加到上下文中。 from langchain.memory import ConversationBufferMemory
memory ConversationBufferMemory(memory_keychat_history, # 与 prompt 的输入变量保持一致。return_messagesTrue # 将以消息列表的形式返回聊天记录而不是单个字符串
)对话检索链ConversationalRetrievalChain在检索 QA 链的基础上增加了处理对话历史的能力。它的工作流程是: 将之前的对话与新问题合并生成一个完整的查询语句。在向量数据库中搜索该查询的相关文档。获取结果后,存储所有答案到对话记忆区。用户可在 UI 中查看完整的对话流程。 这种链式方式将新问题放在之前对话的语境中进行检索可以处理依赖历史信息的查询。并保留所有信 息在对话记忆中方便追踪。使用上一节中的向量数据库和 LLM 首先提出一个无历史对话的问题“我可以学习到关于提示工程的知识吗” from langchain.chains import ConversationalRetrievalChain
retrievervectordb.as_retriever()
qa ConversationalRetrievalChain.from_llm(llm,retrieverretriever,memorymemory
)
question 我可以学习到关于提示工程的知识吗
result qa({question: question})
print(result[answer])
question 为什么这门课需要教这方面的知识
result qa({question: question})
print(result[answer])对知识库和LLM已经有了基本的理解现在是时候将它们巧妙地融合并打造成一个富有视觉效果的界面了。这样的界面不仅对操作更加便捷还能便于与他人分享。Streamlit 是一种快速便捷的方法可以直接在 Python 中通过友好的 Web 界面演示机器学习模型。Streamlit 可以通过 Python 接口程序快速实现这一目标而无需编写任何前端、网页或 JavaScript 代码。 Streamlit 是一个用于快速创建数据应用程序的开源 Python 库。它的设计目标是让数据科学家能够轻松地将数据分析和机器学习模型转化为具有交互性的 Web 应用程序而无需深入了解 Web 开发。和常规 Web 框架如 Flask/Django 的不同之处在于它不需要你去编写任何客户端代码HTML/CSS/JS只需要编写普通的 Python 模块就可以在很短的时间内创建美观并具备高度交互性的界面从而快速生成数据分析或者机器学习的结果另一方面和那些只能通过拖拽生成的工具也不同的是你仍然具有对代码的完整控制权。Streamlit 提供了一组简单而强大的基础模块用于构建数据应用程序 st.write()这是最基本的模块之一用于在应用程序中呈现文本、图像、表格等内容。st.title()、st.header()、st.subheader()这些模块用于添加标题、子标题和分组标题以组织应用程序的布局。st.text()、st.markdown()用于添加文本内容支持 Markdown 语法。st.image()用于添加图像到应用程序中。st.dataframe()用于呈现 Pandas 数据框。st.table()用于呈现简单的数据表格。st.pyplot()、st.altair_chart()、st.plotly_chart()用于呈现 Matplotlib、Altair 或 Plotly 绘制的图表。st.selectbox()、st.multiselect()、st.slider()、st.text_input()用于添加交互式小部件允许用户在应用程序中进行选择、输入或滑动操作。st.button()、st.checkbox()、st.radio()用于添加按钮、复选框和单选按钮以触发特定的操作。 这些基础模块使得通过 Streamlit 能够轻松地构建交互式数据应用程序并且在使用时可以根据需要进行组合和定制更多内容请查看官方文档 首先创建一个新的 Python 文件并将其保存 streamlit_app.py在工作目录的根目录中,导入必要的 Python 库。 import streamlit as st
from langchain_openai import ChatOpenAI
st.title(动手学大模型应用开发)
openai_api_key st.sidebar.text_input(OpenAI API Key, typepassword)定义一个函数使用用户密钥对 OpenAI API 进行身份验证、发送提示并获取 AI 生成的响应。该函数接受用户的提示作为参数并使用st.info来在蓝色框中显示 AI 生成的响应 def generate_response(input_text):llm ChatOpenAI(temperature0.7, openai_api_keyopenai_api_key)st.info(llm(input_text))
# 最后使用st.form()创建一个文本框st.text_area()供用户输入。当用户单击Submit时generate-response()将使用用户的输入作为参数来调用该函数
with st.form(my_form):text st.text_area(Enter text:, What are the three key pieces of advice for learning how to code?)submitted st.form_submit_button(Submit)if not openai_api_key.startswith(sk-):st.warning(Please enter your OpenAI API key!, icon⚠)if submitted and openai_api_key.startswith(sk-):generate_response(text)返回计算机的终端以运行该应用程序 streamlit run streamlit_app.py但是当前只能进行单轮对话我们对上述做些修改通过使用 st.session_state 来存储对话历史可以在用户与应用程序交互时保留整个对话的上下文。 # Streamlit 应用程序界面
def main():st.title(动手学大模型应用开发)openai_api_key st.sidebar.text_input(OpenAI API Key, typepassword)# 用于跟踪对话历史if messages not in st.session_state:st.session_state.messages []messages st.container(height300)if prompt : st.chat_input(Say something):# 将用户输入添加到对话历史中st.session_state.messages.append({role: user, text: prompt})# 调用 respond 函数获取回答answer generate_response(prompt, openai_api_key)# 检查回答是否为 Noneif answer is not None:# 将LLM的回答添加到对话历史中st.session_state.messages.append({role: assistant, text: answer})# 显示整个对话历史for message in st.session_state.messages:if message[role] user:messages.chat_message(user).write(message[text])elif message[role] assistant:messages.chat_message(assistant).write(message[text]) 添加检索问答 先将2.构建检索问答链部分的代码进行封装get_vectordb函数返回C3部分持久化后的向量知识库; get_chat_qa_chain函数返回调用带有历史记录的检索问答链后的结果; get_qa_chain函数返回调用不带有历史记录的检索问答链后的结果 def get_vectordb():# 定义 Embeddingsembedding ZhipuAIEmbeddings()# 向量数据库持久化路径persist_directory ../C3 搭建知识库/data_base/vector_db/chroma# 加载数据库vectordb Chroma(persist_directorypersist_directory, # 允许我们将persist_directory目录保存到磁盘上embedding_functionembedding)return vectordb
#带有历史记录的问答链
def get_chat_qa_chain(question:str,openai_api_key:str):vectordb get_vectordb()llm ChatOpenAI(model_name gpt-3.5-turbo, temperature 0,openai_api_key openai_api_key)memory ConversationBufferMemory(memory_keychat_history, # 与 prompt 的输入变量保持一致。return_messagesTrue # 将以消息列表的形式返回聊天记录而不是单个字符串)retrievervectordb.as_retriever()qa ConversationalRetrievalChain.from_llm(llm,retrieverretriever,memorymemory)result qa({question: question})return result[answer]
#不带历史记录的问答链
def get_qa_chain(question:str,openai_api_key:str):vectordb get_vectordb()llm ChatOpenAI(model_name gpt-3.5-turbo, temperature 0,openai_api_key openai_api_key)template 使用以下上下文来回答最后的问题。如果你不知道答案就说你不知道不要试图编造答案。最多使用三句话。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问”。{context}问题: {question}QA_CHAIN_PROMPT PromptTemplate(input_variables[context,question],templatetemplate)qa_chain RetrievalQA.from_chain_type(llm,retrievervectordb.as_retriever(),return_source_documentsTrue,chain_type_kwargs{prompt:QA_CHAIN_PROMPT})result qa_chain({query: question})return result[result]然后添加一个单选按钮部件st.radio选择进行问答的模式None不使用检索问答的普通模式; qa_chain不带历史记录的检索问答模式; chat_qa_chain带历史记录的检索问答模式 selected_method st.radio(你想选择哪种模式进行对话,[None, qa_chain, chat_qa_chain],captions [不使用检索问答的普通模式, 不带历史记录的检索问答模式, 带历史记录的检索问答模式])进入页面首先先输入OPEN_API_KEY默认然后点击单选按钮选择进行问答的模式最后在输入框输入你的问题按下回车即可完整代码参考streamlit_app.py 要将应用程序部署到 Streamlit Cloud请执行以下步骤 为应用程序创建 GitHub 存储库。您的存储库应包含两个文件 your-repository/ ├── streamlit_app.py └── requirements.txt 转到 Streamlit Community Cloud单击工作区中的New app按钮然后指定存储库、分支和主文件路径。或者您可以通过选择自定义子域来自定义应用程序的 URL点击Deploy!按钮应用程序现在将部署到 Streamlit Community Cloud并且可以从世界各地访问