解決小LLM6類幻覺的實用指南

MLNLP社群是國內外知名的機器學習與自然語言處理社群,受眾覆蓋國內外NLP碩博生、高校老師以及企業研究人員。
社群的願景是促進國內外自然語言處理,機器學習學術界、產業界和廣大愛好者之間的交流和進步,特別是初學者同學們的進步。
來源 | 知乎
作者 | lucas大叔
LLM中的幻覺有多種不同的形式,例如以下幾種:

  • • 事實幻覺:表現為輸出錯誤回覆或捏造答案,可透過RAG解決
  • • 時間幻覺:表現為將陳舊或過時的知識作為當前知識,可透過時間感知提示解決
  • • 上下文幻覺:表現為在回覆中增加上下文中未提及或暗示的概念,可透過 Lookback Lens(一種基於回溯比例的檢測器)解決
  • • 語言幻覺:表現為回覆的內容語法上沒有問題但語義上沒有意義,可透過語義連貫過濾解決
  • • 外在幻覺:表現為回覆為源文件不支援的內容,可透過複製/指標機制解決
  • • 內在幻覺:表現為自相矛盾的答案,可透過矛盾檢測解決
本文將使用1B LLaMA模型用於文字生成,以展示如何解決小模型中的幻覺問題。我們將處理每一種幻覺型別,以瞭解不同的技術如何克服這些問題。

模型介紹

幾乎所有出現幻覺的AI產品都基於兩個元件:
  • • 文字生成大語言模型(LLM)
  • • 嵌入模型
OpenAI、Gemini和Anthropic的模型非常出色,即使在非常複雜的情況下,它們也幾乎不會產生幻覺。然而,它們的使用是有成本的。另一方面,開源大語言模型,尤其是小模型成本更低,但在生成高質量答案方面表現欠佳。

由於此次使用的是1B LLaMA模型進行文字生成。這樣,我們就可以使用成本較低的模型,作為 RAG 或其他任何chatbot應用場景的可行解決方案。
首先建立一個函式,該函式基於系統/使用者提示模板重複生成文字。
import torchfrom transformers import pipeline# Load the LLaMA model using HuggingFace Transformers pipelinemodel_id = "meta-llama/Llama-3.2-1B-Instruct"pipe = pipeline(    "text-generation",    model=model_id,    torch_dtype=torch.bfloat16,  # Use bfloat16 for efficient computation    device_map="auto",           # Automatically selects available GPU/CPU)
然後,利用LLM建立函式:
def generate_response(system_prompt: str, user_prompt: str) -> str:    """    Generate a response from the model based on a system prompt and user prompt.    Parameters:    - system_prompt (str): The instruction or persona for the model (e.g., "You are a pirate chatbot").    - user_prompt (str): The actual user query or message to respond to.    Returns:    - str: The generated text response from the model.    """    # Construct the input message format for the model    messages = [        {"role": "system", "content": system_prompt},        {"role": "user", "content": user_prompt},    ]    # Generate output using the pipeline    outputs = pipe(messages)    # Extract and return the generated text    return outputs[0]["generated_text"][-1]['content']
對於開源嵌入模型,隨機選一個很小的模型,這樣就能在本地環境載入。此次使用大小為45MB的GTE Tiny來快速建立嵌入。
from sentence_transformers import SentenceTransformerimport numpy as np# Load the model once (outside the function) to avoid reloading on each callembedding_model = SentenceTransformer("TaylorAI/gte-tiny")def get_sentence_embedding(sentence: str) -> np.ndarray:    """    Generate an embedding vector for a given sentence using a preloaded SentenceTransformer model.    Parameters:    - sentence (str): The input sentence to encode.    Returns:    - np.ndarray: The sentence embedding as a NumPy array.    """    # Encode the sentence into a dense vector using the preloaded model    embedding = embedding_model.encode(sentence)    return embedding
現在我們已經搭建好了大語言模型(LLaMA 1B)和嵌入模型(GTE Tiny)。接下來逐一解決這些幻覺型別。

基於RAG的事實性糾錯

讓我們從小LLM的基本問題開始,它們常常對事實性問題給出錯誤答案。
看下面這個例子:
# The system prompt sets the behavior or persona of the AIsystem_prompt = "You are an AI Chatbot!"# The user prompt is the actual question or input from the useruser_prompt = "Who discovered Penicillin in 1928?"# Generate a response from the AI using the system and user promptsresponse = generate_response(system_prompt, user_prompt)# Print the response returned by the AIprint(response)
查詢的真正答案是“Penicillin was discovered in 1928 by Alexander Fleming.”,但大模型的回答是:
Robert Withering, an English physician, is often credited with the discovery of penicillin in
小模型將功勞歸錯了人(如果嘗試多次,它可能會給出正確答案),但在實際應用中,沒有多次嘗試的機會。1B引數的LLaMA訓練資料可能包含也可能不包含正確答案,但無論哪種情況,它的第一個回答都不正確。RAG是解決這個問題最常用的技術之一。

所以,我們通常有大量的文件,而在這些文件的某個地方就隱藏著測試查詢的答案。否則,大模型應該回應說它沒有相關的訓練資料,而不是給出錯誤的答案。這樣,模型的質量對使用者來說仍然是可信的。
讓我們定義知識庫:
# Our Knowledge Base (5 Documents)documents = [    "Robert Withering, an English physician and botanist, is known for his study of the foxglove plant and its medicinal properties, particularly its use in treating dropsy (edema).",    "The process of fermentation is a metabolic process that produces chemical changes in organic substrates through the action of enzymes. It typically occurs in yeast and bacteria, and also in oxygen-starved muscle cells, as in the case of lactic acid fermentation.",    "Sir Alexander Fleming, a Scottish physician and microbiologist, discovered the antibiotic substance penicillin from the mould Penicillium notatum in 1928. This discovery revolutionized medicine.",    "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France. It was named after the engineer Gustave Eiffel, whose company designed and built the tower."]
知識庫包含五份文件,LLM將使用這些文件來回答查詢。所以,讓我們建立簡單的RAG管道,看看它是否能提升大模型的回覆質量。
# Embed the user queryuser_query = "Who discovered Penicillin in 1928?" # Our test queryuser_query_embedding = get_sentence_embedding(user_query)# Embed the Knowledge Basedocument_embeddings = [get_sentence_embedding(doc) for doc in documents]# Find the most relevant document based on embedding similarity (using dot product)similarity_scores = np.dot(document_embeddings, user_query_embedding)# Find the index of the document with the highest scoremost_relevant_doc_index = np.argmax(similarity_scores)# Retrieve the text of the most relevant documentretrieved_context = documents[most_relevant_doc_index]
在生產環境中,通常會檢索和試驗塊大小(chunk size)、重疊(overlap)以及其他引數,包括最相關的塊。但此處為了簡化操作,僅檢索相似度得分最高的文件作為參考,該文件將被傳遞到LLM輸入中。
下面建立系統和使用者提示,看看LLM會給出什麼響應。
# We explicitly tell the AI to use the context providedrag_system_prompt = f"""You are an AI Chatbot!Use the following context to answer the user's question accurately.If the context does not contain enough information to answer the question, respond that you don't have sufficient information from the provided context.Context:{retrieved_context}"""# The user prompt remains the sameuser_prompt = "Who discovered Penicillin in 1928?"# Generate a response using the RAG system prompt and original user promptrag_response = generate_response(rag_system_prompt, user_prompt)# Print the RAG-enhanced responseprint(rag_response)
LLM響應是
Penicillin was actually discovered by Sir Alexander Fleming, a Scottish physician and microbiologist,
LLM在事實性回答方面有了明顯的改進;現在它能正確回答事實性問題了。
讓我們繼續探討下一種幻覺型別,看看如何解決它。

使用時間感知提示進行時間校正

時間幻覺是指 LLM 產生對時間敏感的錯誤或過時資訊的情況。這是因為大語言模型有固定的 “知識截止日期”(它們只瞭解到其訓練日期之前的世界資訊)。
看下面這個例子:
# The system prompt sets the behavior or persona of the AIsystem_prompt = "You are an AI Chatbot!"# The user prompt is the actual question or input from the useruser_prompt = "Who is the president of France today?"# Generate a response from the AI using the system and user promptsresponse = generate_response(system_prompt, user_prompt)# Print the response returned by the AIprint(response)
我們向大模型詢問法國現任總統的資訊,以下是大模型給出的輸出:
The current President of France is Emmanuel Macron.
解決這個問題的一種方法是使用RAG,但並非總是需要有可用的相關知識庫。那麼,該如何處理這種情況呢?

研究人員提出了一個重寫查詢以包含時間約束的框架 — TimeR4[1]。可以使用這種時間感知提示方法讓LLM知曉所提出查詢的時間範圍。
  • • today → 14 May 2025
  • • this year → 2025
  • • this month → May
透過這種方式,用重寫的查詢引導LLM,該查詢明確指定了所涉及的時間範圍,使大模型能夠根據其訓練資料更準確地做出回應。
這也可以提高 RAG 的檢索質量,因為我們在其中納入了時間範圍。
讓我們實現這種時間感知提示技術。可以為此使用Python的datetime模組,也可以使用大模型。但目前,我們將建立一個函式或一些簡單的程式碼,透過將諸如“today”之類的時間關鍵詞替換為實際的當前日期來重寫使用者查詢。
from datetime import datetimedef make_query_time_aware(user_prompt: str) -> str:    """    Rewrites the user prompt to include the current date for temporal context.    This is a simplified example targeting specific keywords.    Parameters:    - user_prompt (str): The original user query.    Returns:    - str: The rewritten, time-aware query.    """    current_date_str = datetime.now().strftime("%d %B %Y") # e.g., "05 May 2025"    # Simple replacements - expand this for more temporal keywords    rewritten_prompt = user_prompt.replace("today", current_date_str)    rewritten_prompt = rewritten_prompt.replace("this year", datetime.now().strftime("%Y"))    rewritten_prompt = rewritten_prompt.replace("this month", datetime.now().strftime("%B %Y"))    # You might add more complex logic or regex for different temporal phrases    return rewritten_prompt
讓我們在查詢上執行此函式。
# Let's apply this to our original temporal queryuser_prompt = "Who is the president of France today?"time_aware_user_prompt = make_query_time_aware(user_prompt)print(f"Original Query: {user_prompt}")print(f"Time-Aware Query: {time_aware_user_prompt}")
今天是2025年5月14日,此程式碼片段的輸出將是:
Original Query: Who is the president of France today?Time-Aware Query: Who is the president of France 14 May 2025?
現在將time_aware_user_prompt與最初的簡單系統提示一起使用來生成響應。
系統提示不需要更改,因為時間資訊現在直接嵌入到使用者查詢本身。
# The system prompt remains simplesystem_prompt = "You are an AI Chatbot!"# Generate a response using the simple system prompt and the time-aware user prompttemporal_response = generate_response(system_prompt, time_aware_user_prompt)# Print the time-aware responseprint(temporal_response)
1B LLaMA的響應是
I'm an AI chatbot, and my training data is up to December 2023
這種方法不僅為LLM提供了一個不回答這個問題的有力理由,而且當你引入RAG時,時間框架肯定會影響資訊獲取過程,因為 “today” 會給大模型造成混淆,而日期則不會。如果知識庫中存在相關文件,這種方法將確保能夠檢索到它們。

使用回顧視角的上下文問題

上下文幻覺是指語言模型給出不正確或具有誤導性的答案,即使獲取了所有的正確資訊。當模型沒有正確使用或理解所提供的細節時,就會發生這種情況,導致答案看似相關,但實際上是錯誤或不完整的。看下面這個例子:
# Our source context (representing a document or retrieved chunk)source_context = """ByteBuilders Q3 profit: ~5.02% adj, 4.9% unadj, +502 bps margin, –0.1 ppt FX drag, vs. 4.5% est."""# The system prompt (Report + System prompt)system_prompt = f"""You are an AI Chatbot!Article Snippet:{source_context}"""# The user prompt is simply asking for the summaryuser_prompt = "Summarize the Q3 earnings."# Generate a response using the system prompt with contextresponse = generate_response(system_prompt, user_prompt)# Print the response returned by the AIprint(response)
源上下文可以是檢索到的文字塊、文件或網路搜尋結果,基本上是ByteBuilders公司的財務報告。
由於文件中已有相關資訊,我們要求LLM對其進行總結。
這是得到的回覆:
ByteBuilders reported Q3 earnings (4th quarter) with a net profit of approximately 4.
它給出的淨利潤數值是錯誤的,儘管文件中明確給出了正確數值。以下是我們的事實依據:
  • • 季度混淆:Q3是第三季度,而非第四季度。
  • • 錯誤的利潤資料:利潤增長並非 “約4”(無論是百分比還是其他單位)。在上下文中,ByteBuilders實際公佈的調整後利潤增長率為5.02%(預期為4.50%)。

我們可以使用一種類似於Lookback Lens[2]的方法,以確保模型所做的任何具體事實性陳述實際上都有提供的輸入上下文支援。
我們可以從生成的摘要中提取關鍵資訊(如“淨利潤為4”),並將其作為明確的驗證問題拋給大模型,再次向其提供原始源上下文,並要求它充當事實核查員。
好處是通常可以使用與生成內容時相同的小模型來執行此驗證任務!
# Our source context (representing a document or retrieved chunk)source_context = """ByteBuilders Q3 profit: ~5.02% adj, 4.9% unadj, +502 bps margin, –0.1 ppt FX drag, vs. 4.5% est."""# Fact checking system promptverification_system_prompt = f"""You are a fact-checking assistant. Your task is to determine if the following STATEMENT is fully and directly supported by the provided CONTEXT.Answer (only one option to select):1. Yes2. No3. Partially SupportedCONTEXT:{source_context}"""# Proper naming (Last summarized response = hallucinated summary)hallucinated_summary = response
我們正在定義驗證系統提示,它將與幻覺生成的總結資訊一起傳遞,以檢視大模型會給出什麼回應。
# Generate a response using the system prompt with contextverify = generate_response(source_context, hallucinated_summary)# Print the response returned by the AIprint(verify)
以下是得到的響應:
Based on the provided context, The statement is partially supported
我們可以使用這些驗證資訊,並在此基礎上,要麼要求大模型重新生成其總結回覆,要麼將任務重定向到更強大的大模型,以便為查詢生成更準確的總結。讓我們看看這樣做,對回覆有何影響。
# Decide based on the verification outcomeif "No" in verify or "Partially" in verify:    # Regenerate the summarized info    response = generate_response(improved_system_prompt, user_prompt)    # Show the new response    print(response)else:    pass
生成的響應:
ByteBuilders reported Q3 earnings of ~5.02% annualized growth
我們可以在for迴圈中構建管道,以便並行地重新嘗試,這有助於避免讓使用者等待答案。但在例子中,第二次嘗試已經給了一個更好的結果。

使用語義連貫過濾的語言問題

語言幻覺是指語言模型生成的句子聽起來正確,語法上也說得通,但意思卻是錯誤的、不相關的或毫無意義。
其結果表面上看起來不錯,但缺乏真實或有用的內容。
設想一下,當10個不同的人同時向大模型提出類似的問題,或者多次輸入相同的提示時,很有可能其中一人或多人會遇到這種問題。
看下面這個例子:
# The system prompt sets the behavior or persona of the AIsystem_prompt = "You are an AI Chatbot!"# The user prompt is the actual question or input from the useruser_prompt = "Explain how photosynthesis works in plants"# Initializing a list to store multiple generated responsesresponses = []# Loop to generate 10 different responsesfor i in range(10):  # Generating Responses  response = generate_response(system_prompt, user_prompt)  # Append the generated response to the list  responses.append(response)
我們使用一個非常簡單的查詢,許多大模型的訓練資料很可能包含這個查詢。
既然已經生成了回覆,那麼在查詢和生成的回覆之間生成相似度分數,以確定問題出在哪裡。
# Get the embedding for the user's queryuser_query_embedding = get_sentence_embedding(user_query)# Get embeddings for all responsesresponse_embeddings = [get_sentence_embedding(response) for response in responses]# Calculate similarity scores between the query and each response using dot productsimilarity_scores = np.dot(response_embeddings, user_query_embedding)# Printing sim scoreprint(similarity_scores)
得分為:
array([68.78545 , 69.63894 , 67.53516 , 67.09607 , 32.15152, 67.746735,       67.09607 , 69.6586  , 28.45125, 69.6586  ], dtype=float32)
索引為(4, 8)的兩個回覆相似度得分極低。列印其中一個低得分回覆,看看可能存在什麼問題:
# Printing Response at index 4print(f"response[4]: {responses[4]}")
"Photosynthesis is a process where plants turn sunlight into sound waves, which they use to create energy."
這是對光合作用的錯誤描述,因為該過程並不涉及聲波。這個回答聽起來語法正確,但在這裡意思卻毫無意義。

我們可以為相似度分數設定一個閾值(例如,20%)。任何相似度分數低於此閾值的回覆都將被標記以便重新生成。
# Set a similarity score thresholdthreshold = 50# Iterate over the responses and regenerate if the score is below the thresholdfor i, score in enumerate(similarity_scores):    if score < threshold:        # Regenerate the response        regenerated_response = generate_response(system_prompt, user_prompt)        responses[i] = regenerated_response
在重新生成索引4和8處的回覆後,重新檢查相似度分數,以確保新的回覆更相關且準確。
重新計算相似度分數:
# Get embeddings for the regenerated responsesresponse_embeddings = [get_sentence_embedding(response) for response in responses]# Recalculate similarity scores between the query and each regenerated responsenew_similarity_scores = np.dot(response_embeddings, user_query_embedding)# Printing the new similarity scoresprint("New similarity scores after regeneration:")print(new_similarity_scores)
看下最新生成的相似度得分:
array([68.78545 , 69.63894 , 67.53516 , 67.09607 , 51.479702, 67.746735,       67.09607 , 69.6586  , 69.21619 , 69.6586  ], dtype=float32)
索引4和索引8分數有所提高,並且越來越接近使用者查詢,這意味著它們現在可能包含與查詢相關的資訊。
當你需要從大模型獲得高質量回復時,這種技術非常有用且重要。

使用矛盾檢查的內在問題

內在幻覺是指LLM的輸出與輸入源相矛盾或錯誤解讀輸入源的情況。換句話說,模型錯誤地歪曲了給定的事實。
你可能覺得內在幻覺和上下文幻覺非常相似,我們先透過簡單的例子來理解一下:
  • • 輸入: The dog is running in the park.
  • • (上下文幻覺): The dog is running on the beach.
  • • (內在幻覺): The dog is flying in the park.
內在輸出與輸入直接矛盾。狗不會飛,所以與原始陳述產生了根本性的不一致,這與上下文問題不同,在上下文問題中,模型保持在狗奔跑的上下文中,但改變了地點(從公園到海灘)。
讓我們生成一個有此問題的輸出。
# Our source context (representing a document or retrieved chunk)source_context = """The Nile River originates from the Great Lakesregion in Africa."""# Our user promptuser_prompt = "Where does the Nile originate?"# Generate a response using the system prompt with contextresponse = generate_response(system_prompt, user_prompt)# Print the response returned by the AIprint(response)
讓我們看下大模型的輸出:
The Nile River originates from Lake Hindia, in Tanzania.
大模型輸出與輸入直接矛盾。為了檢測前提(源文字)和假設(模型輸出)之間的矛盾,可以使用基於BERT的預訓練模型,該模型針對自然語言推理(NLI)進行了微調。

該模型將幫助我們對前提和假設之間的關係進行分類,尤其關注尋找矛盾關係。
為此,使用facebook/bart-large-mnli,這是在MNLI資料集上微調過的流行模型。
from transformers import pipeline# Define premise (source text) and hypothesis (model output)premise = source_contexthypothesis = response# Load an NLI model (fine-tuned on MNLI)nli_pipeline = pipeline("text-classification", model="facebook/bart-large-mnli")# Use a prompting format for NLIresult = nli_pipeline(f"Premise: {premise}  Hypothesis: {hypothesis}")print(result)
讓我們看看模型輸出與源文字之間的矛盾得分。
[{'label': 'contradiction', 'score': 0.9499581456184387}]
矛盾分數非常高,約為95%,顯然我們可以使用與語言方法相同的方法,即設定閾值引數,重新生成LLM的回覆,看是否能解決問題。
# Set a contradiction score thresholdthreshold = 0.60# Iterate over the responses and regenerate if the score is below the thresholdif score < threshold:    # Regenerate the response    regenerated_response = generate_response(source_context, user_prompt)print(regenerated_response)
重新生成的響應為:
The Nile River originates from the Great Lakes region in Africa.
透過這種方式,可以得出一個儘可能少矛盾的恰當的大模型回覆。

使用複製/指標機制的外部問題

外在幻覺是指語言模型添加了原始輸入中沒有依據的額外資訊。與內在幻覺不同,內在幻覺與所提供的資料相沖突,而外在幻覺則創造出全新的、編造的事實。請看下面的例子:
# Meeting summary Reportdocument = """Meeting Summary – April 10, 2025- Discussion of Q1 2025 performance and upcoming product launch.- CFO presented the Q2 2025 budget proposal."""# User prompt to test for extrinsic hallucinationsuser_prompt = """Can you summarize the meeting that took place on April 10th, 2025, and include any decisions made about budget allocations or new project approvals?"""# Generating Responsesresponse = generate_response(document, user_prompt)# Print the generated responseprint(response)
在這個提示中,我們特別詢問LLM是否存在文件中未提及的新專案批准情況。讓我們看看大模型是否會編造出任何事實。
Meeting Summary – April 10, 2025**Introduction*** The meeting was attended by the Executive Team, led by the CEO.**Q1 2025 Performance Review*** The team reviewed the Q1 2025 performance,highlighting areas of success and challenges faced.**New Project Approvals*** The Executive Team approved several new projects, including: + A cloud-based CRM system for customer engagement and support
當LLM設定為較高的最大新生成token數(例如500)時,1B引數的小模型就開始生成一堆編造的事實,只是為了填滿token空間,而這些事實在原始文件中根本不存在。
一種已被證實可減少外部幻覺的方法是使用指標/複製機制[3]

這些技術使模型直接從源文字中提取內容,而不是生成新資訊。例如,摘要中的指標生成網路允許模型生成新詞或從輸入中複製。在大模型中強制進行復制的一種簡單方法是使用系統提示,引導模型直接從源文字中複製。
以下是可以構建提示的一個示例:
system_prompt = """Please summarize the following document, but make sure to only use information that is present in the text.Do not add any new facts or details that are not in the original document."""
讓我們用這個更新後的模板生成回覆,看看大模型輸出是什麼:
# User prompt + documentcombined_info = document + user_prompt# Generating Responses with copying mechanismresponse_with_copy = generate_response(system_prompt, combined_info)print(response_with_copy)
更新後的輸出是:
The meeting summary provided is as follows:- The Q1 2025 performance was discussed.- A product launch for the upcoming period was announced.- The CFO presented a Q2 2025 budget proposal.
LLM並非憑藉自身“思考”來撰寫內容,而只是從原始來源複製文字。這是一種有用的技術,因為在大多數情況下,知識庫非常龐大,包含了相關資訊,這些資訊只需呼叫,無需重新表述。

總結

我們透過小模型(LLaMA 1B)和小嵌入模型(GTE Tiny),證明可以用更少的資源開展工作。
  • • 事實性問題?使用RAG來解決。簡單又有效。
  • • 時間錯誤?讓查詢 “具有時間感知”,注入日期會產生奇妙效果!
  • • 上下文混淆?實施 “回顧視角”,LLM根據來源進行自我事實核查!
  • • 語言怪異?使用嵌入相似度閾值過濾無意義的輸出並重新生成。
  • • 內在矛盾?使用自然語言推理(NLI)模型檢測輸出是否與來源衝突,若衝突則重新生成。
  • • 外在編造內容?透過提示強制採用 “複製/指標” 風格,緊扣源文字。
透過這些技術系統地解決幻覺問題,我們可以讓小引數、低成本的大模型成為可行選擇。

參考文件

https://medium.com/@fareedkhandev/8d15c11650d3

引用連結

[1] TimeR4: https://aclanthology.org/2024.emnlp-main.394/[2] Lookback Lens: https://arxiv.org/html/2407.07071v1#:~:text=To%20leverage%20signals%20from%20attention,The[3] 指標/複製機制: https://arxiv.org/pdf/2005.00661#:~:text=and%20inference,intrinsic%20hallucination

技術交流群邀請函

△長按新增小助手
掃描二維碼新增小助手微信
請備註:姓名-學校/公司-研究方向
(如:小張-哈工大-對話系統)
即可申請加入自然語言處理/Pytorch等技術交流群

關於我們

MLNLP 社群是由國內外機器學習與自然語言處理學者聯合構建的民間學術社群,目前已經發展為國內外知名的機器學習與自然語言處理社群,旨在促進機器學習,自然語言處理學術界、產業界和廣大愛好者之間的進步。
社群可以為相關從業者的深造、就業及研究等方面提供開放交流平臺。歡迎大家關注和加入我們。


相關文章