我發現,在構建根據使用者偏好的個人化健身計畫生成系統時,範例資料的有效利用至關重要。系統需要根據使用者輸入,例如健身水平和目標,智慧選取最相關的範例來構建提示,引導模型生成更精準的健身計畫。以下,我將分享如何設計和應用智慧範例選擇器,提升個人化健身計畫的生成效果。

範例選擇器介面設計

首先,我定義了範例選擇器的介面:

from abc import ABC, abstractmethod
from typing import Dict, List, Any

class BaseExampleSelector(ABC):
    """定義範例選擇器的介面"""

    @abstractmethod
    def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
        """根據輸入選擇範例"""

    @abstractmethod
    def add_example(self, example: Dict[str, str]) -> Any:
        """新增範例到儲存函式庫"""

BaseExampleSelector 作為抽象基礎類別,定義了兩個關鍵方法:select_examples 根據輸入變數字典傳回選定的範例列表,add_example 則用於新增範例到選擇器的儲存函式庫。

範例資料準備

我準備了一些英義翻譯的範例資料:

examples = [
    {"input": "hello", "output": "ciao"},
    {"input": "goodbye", "output": "arrivederci"},
    {"input": "football", "output": "calcio"},
]

這些範例資料以字典形式儲存,每個字典包含 “input” 和 “output” 鍵值對,分別代表英文單詞和對應的義大利文翻譯。

客製化範例選擇器實作

我建立了一個 BaseExampleSelector 的客製化實作:

class CustomExampleSelector(BaseExampleSelector):
    def __init__(self, examples):
        self.examples = examples

    def add_example(self, example):
        self.examples.append(example)

    def select_examples(self, input_variables):
        new_word = input_variables["input"]
        new_word_length = len(new_word)
        best_match = None
        smallest_diff = float("inf")
        for example in self.examples:
            current_diff = abs(len(example["input"]) - new_word_length)
            if current_diff < smallest_diff:
                smallest_diff = current_diff
                best_match = example
        return [best_match]

這個 CustomExampleSelector 根據輸入詞的長度,選取長度最接近的範例。select_examples 方法會計算輸入詞與每個範例詞的長度差,並傳回長度差最小的範例。

客製化範例選擇器應用

以下是如何使用客製化範例選擇器:

example_selector = CustomExampleSelector(examples)
print(example_selector.select_examples({"input": "morning"}))  # 輸出: [{'input': 'hello', 'output': 'ciao'}]

example_selector.add_example({"input": "evening", "output": "sera"})
print(example_selector.select_examples({"input": "morning"}))  # 輸出: [{'input': 'evening', 'output': 'sera'}]

這段程式碼示範瞭如何使用 CustomExampleSelector 選擇範例,並展示了新增範例後選擇結果的變化。

整合 LangChain 提示範本

from langchain.prompts import FewShotPromptTemplate, PromptTemplate

example_prompt = PromptTemplate.from_template("輸入: {input} -> 輸出: {output}")

prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    suffix="輸入: {input} -> 輸出:",
    prefix="將以下單詞從英文翻譯成義大利文:",
    input_variables=["input"],
)

print(prompt.format(input="house"))

這段程式碼展示瞭如何將客製化的範例選擇器整合到 LangChain 的提示範本中,構建用於英義翻譯的提示。

範例選擇器策略選擇

選擇合適的範例選擇器至關重要。一些常見的策略包括:

  • 相似度: 根據語義相似度選擇範例。
  • 最大邊際相關性 (MMR): 平衡相關性和多樣性。
  • 長度: 根據長度限制選擇範例。
  • N-gram: 根據 N-gram 重疊度選擇範例。
  graph LR
    B[B]
    A[使用者輸入] --> B{範例選擇器};
    B --> C[選定範例];
    C --> D[提示範本];
    D --> E[模型];
    E --> F[個人化輸出];

圖表説明:此流程圖展示了範例選擇器在生成個人化輸出中的作用。

LangChain 少樣本提示應用

LangChain 的 FewShotPromptTemplate 簡化了少樣本學習的應用。以下是一個更完整的示例:

from langchain.prompts import FewShotPromptTemplate, PromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector
from langchain.llms import OpenAI

# 設定 OpenAI API 金鑰 (記得替換為您的 API 金鑰)
import os
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"

# 範例資料
examples = [
    {"question": "太陽系中最大的行星是什麼?", "answer": "木星"},
    {"question": "誰畫了蒙娜麗莎?", "answer": "達文西"},
    {"question": "日本的貨幣是什麼?", "answer": "日圓"}
]

# 範例提示範本
example_prompt = PromptTemplate(
    input_variables=["question", "answer"],
    template="問題:{question}\n答案:{answer}"
)

# 少樣本提示範本 (無範例選擇器)
prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    suffix="問題:{input}",
    input_variables=["input"]
)

# 少樣本提示範本 (使用 LengthBasedExampleSelector)
example_selector = LengthBasedExampleSelector(
    examples=examples,
    example_prompt=example_prompt,
    max_length=50
)
prompt_with_selector = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    suffix="問題:{input}",
    input_variables=["input"]
)

# 載入語言模型
llm = OpenAI(model_name="gpt-3.5-turbo", temperature=0.7)

# 測試提示
user_input = "台灣的首都是哪裡?"
print(f"問題:{user_input}\n答案:{llm(prompt.format(input=user_input))}")

user_input_2 = "誰雕刻了大衞像?"
print(f"\n問題:{user_input_2}\n答案:{llm(prompt_with_selector.format(input=user_input_2))}")

這段程式碼示範瞭如何使用 LangChain 建立少樣本提示,並使用 LengthBasedExampleSelector 控制提示長度。同時,它也示範瞭如何使用 OpenAI 的語言模型生成答案。

  graph LR
    B[B]
    max_length[max_length]
    A[初始化 LengthBasedExampleSelector] --> B{遍歷範例};
    B -- 長度 < max_length --> C[選擇範例];
    B -- 長度 >= max_length --> D[跳過範例];
    C --> E[更新已選範例長度];
    E --> B;

圖表説明:此流程圖展示了 LengthBasedExampleSelector 的工作流程。

透過以上方法,我們可以構建一個智慧的範例選擇機制,並將其整合到 LangChain 的提示範本中,從而提升大語言模型生成個人化健身計畫的效能。這個方法也適用於其他類別似場景,例如根據使用者偏好生成食譜、旅遊行程等。

利用 LangChain 和大語言模型,結合智慧範例選擇策略,可以有效提升個人化內容生成的精準度和效率,為使用者提供更優質的體驗。

from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage
from pydantic import BaseModel, Field, ValidationError
import os

# 電影資料模型,加入欄位驗證
class Movie(BaseModel):
    title: str = Field(description="電影名稱")
    director: str = Field(description="導演")
    year: int = Field(description="上映年份")

    @field_validator('title')
    def title_must_be_capitalized(cls, value):
        return value.title()  # 自動將標題轉換為首字母大寫

# 初始化輸出解析器
parser = PydanticOutputParser(pydantic_object=Movie)

# 建立提示範本
prompt = PromptTemplate(
    template="請提供以下格式的電影資訊:\n{format_instructions}\n問題:{query}",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

# 從環境變數取得 OpenAI API 金鑰
openai_api_key = os.getenv("OPENAI_API_KEY")

# 使用環境變數或設定預設值
if openai_api_key is None:
    raise ValueError("未設定 OPENAI_API_KEY 環境變數")

# 初始化語言模型
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0, openai_api_key=openai_api_key)

# 測試查詢
queries = ["2001: 太空漫遊", "奧本海默", "全面啟動"]

for query in queries:
    # 格式化提示
    _input = prompt.format_prompt(query=query)

    # 產生電影資訊
    output = llm(_input.to_messages())

    try:
        # 解析輸出
        movie = parser.parse(output.content)
        print(f"'{query}' 的電影資訊:{movie}")

    except ValidationError as e:
        print(f"無法解析 '{query}' 的資訊。錯誤:{e}")

這段程式碼示範瞭如何使用 LangChain 和 Pydantic 輸出解析器從大語言模型 (LLM) 中提取結構化電影資料。以下是一些改進和説明:

  • 欄位驗證: Movie 模型現在包含一個欄位驗證器 title_must_be_capitalized,確保電影名稱的首字母大寫,提高資料一致性。
  • 錯誤處理: try...except 區塊能處理 ValidationError,提供更強健的錯誤處理機制。
  • 環境變數: 使用 os.getenv() 取得 OpenAI API 金鑰,更安全與易於管理。程式碼也加入了檢查,確保 API 金鑰已設定。
  • 多個查詢: 程式碼現在可以處理多個電影查詢,展示了更實際的應用場景。
  • 清晰的輸出: 輸出格式更清晰,易於理解。
  • 繁體中文: 程式碼中的註解和提示都使用繁體中文,更符合台灣使用者的習慣。

這個版本提供了一個更完善的 PydanticOutputParser 使用範例,解決了潛在錯誤,並示範了多輸入處理。記得安裝必要的函式庫 (pip install langchain pydantic openai)。

  graph LR
    B[B]
    D[D]
    A[使用者查詢] --> B{提示格式化}
    B --> C[LLM 產生輸出]
    C --> D{Pydantic 解析}
    D -- 成功 --> E[電影物件]
    D -- 失敗 --> F[錯誤訊息]

這個流程圖展示了程式碼的執行流程:使用者提供查詢後,程式碼會格式化提示,然後將提示送至 LLM。LLM 產生輸出後,程式碼會使用 Pydantic 解析輸出。如果解析成功,則會建立電影物件;如果解析失敗,則會顯示錯誤訊息。

# 使用提示產生電影資訊
query = "告訴我關於電影'全面啟動'的資訊。"
human_message = HumanMessage(content=prompt.format(query=query))
response = llm([human_message])

# 解析LLM的回應
try:
    parsed_movie = parser.parse(response.content)
    # 顯示結構化的電影資料
    print(parsed_movie)
except ValidationError as e:
    print(f"驗證錯誤: {e}")

這段程式碼示範瞭如何使用 LangChain 的 HumanMessageChatOpenAI 與 LLM 互動,並使用 PydanticOutputParser 解析 LLM 的回應。它使用 try...except 區塊處理潛在的 ValidationError,確保程式碼的穩定性。

這個例子展示了輸出解析器如何應用於各種領域,例如整理電影、書籍、產品或任何其他需要從 LLM 回應中提取的結構化資料。

from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI

# 初始化 OpenAI 語言模型
llm = OpenAI(temperature=0.7)

# 定義提示範本
template = """你是一位友善的 AI 助手。請根據以下資訊回答使用者的問題:

上下文:{context}

問題:{question}"""
prompt_template = PromptTemplate(input_variables=["context", "question"], template=template)


# 建立 LLMChain
llm_chain = LLMChain(llm=llm, prompt=prompt_template)

# 執行 LLMChain
context = "台灣是一個美麗的島嶼,以其豐富的文化、美食和友善的人民而聞名。"
question = "台灣以什麼聞名?"
response = llm_chain.run({'context': context, 'question': question})

# 顯示回應
print(response)

以上程式碼示範瞭如何使用 LangChain 建立一個簡單的 LLMChain。 首先,我們初始化一個 OpenAI 語言模型。 接著,我們定義一個提示範本,其中包含上下文和問題兩個變數。 然後,我們使用 llm 和 prompt_template 建立一個 LLMChain。 最後,我們提供上下文和問題,執行 LLMChain,並顯示產生的回應。

Chains 的型別與應用:探索不同場景下的最佳實務

LangChain 提供了多種不同型別的 Chains,每種型別都適用於特定的應用場景。以下列出幾種常見的 Chains 型別:

  1. LLMChain: 最基本的 Chain 型別,用於將 LLM 與提示範本結合。適用於簡單的文字生成任務,例如摘要、翻譯和問答。
  2. SequentialChain: 按順序執行多個 Chains。適用於需要多步驟處理的任務,例如先從 API 擷取資料,然後使用 LLM 進行摘要。
  3. TransformChain: 用於轉換輸入資料的 Chain。例如,您可以使用 TransformChain 將文字轉換為數值向量,或將不同格式的資料轉換為統一格式。
  4. RouterChain: 根據輸入資料的特性,將資料路由到不同的 Chains。適用於需要根據不同條件執行不同操作的場景。
  5. MultiPromptChain: 允許您使用多個提示來引導 LLM 生成不同型別的回應。適用於需要根據不同需求生成不同型別輸出的場景。

掌握 LangChain Chains,開啟生成式 AI 的無限可能

LangChain 的 Chains 模組提供了一個強大與靈活的框架,用於建構生成式 AI 應用。透過理解 Chains 的重要性、組成元件、型別以及如何運用它們,您可以簡化 AI 應用的開發流程,並提升應用程式的可維護性和可擴充套件性。 隨著生成式 AI 技術的快速發展,掌握 LangChain Chains 將成為開發創新 AI 應用的關鍵技能。

希望這篇文章能幫助您更深入地理解 LangChain Chains。

from langchain.chains import LLMChain, SequentialChain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate

# 各階段的 Prompt 範本與鏈
topic_prompt = PromptTemplate(template="產生與主題相關的關鍵字:{topic}", input_variables=["topic"])
topic_chain = LLMChain(llm=OpenAI(), prompt=topic_prompt)

data_prompt = PromptTemplate(template="擷取與以下關鍵字相關的資料:{keywords}", input_variables=["keywords"])
data_chain = LLMChain(llm=OpenAI(), prompt=data_prompt)

summary_prompt = PromptTemplate(template="摘要以下資料:{data}", input_variables=["data"])
summary_chain = LLMChain(llm=OpenAI(), prompt=summary_prompt)

# 組合順序鏈
overall_chain = SequentialChain(
    chains=[topic_chain, data_chain, summary_chain],
    input_variables=["topic"],
    output_variables=["summary"],
)

# 執行順序鏈
summary = overall_chain.run(topic="人工智慧的未來趨勢")
print(summary)

這段程式碼示範瞭如何使用 SequentialChain 組合三個 LLMChain,分別負責關鍵字生成、資料擷取和摘要生成。input_variablesoutput_variables 定義了整個鏈的輸入和輸出變數。透過 overall_chain.run() 方法,我們可以一步執行整個工作流程,得到最終的摘要結果。

條件鏈:根據條件選擇執行路徑

ConditionalChain 允許根據條件選擇不同的鏈執行。例如,在問答系統中,我可以根據問題型別選擇不同的處理策略:

from langchain.chains import LLMChain, ConditionalChain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate

# 不同問題型別的 Prompt 範本與鏈
simple_prompt = PromptTemplate(template="簡單回答:{question}", input_variables=["question"])
simple_chain = LLMChain(llm=OpenAI(), prompt=simple_prompt)

complex_prompt = PromptTemplate(template="詳細回答:{question}", input_variables=["question"])
complex_chain = LLMChain(llm=OpenAI(), prompt=complex_prompt)

# 條件判斷函式
def question_classifier(question):
    if "為什麼" in question:
        return "complex"
    else:
        return "simple"

# 組合條件鏈
conditional_chain = ConditionalChain(
    default_chain=simple_chain,  # 預設執行 simple_chain
    chains={"complex": complex_chain}, # 條件為 "complex" 時執行 complex_chain
    input_variables=["question"],
    output_variables=["answer"],
    routing_func=question_classifier, # 條件判斷函式
)

# 執行條件鏈
answer = conditional_chain.run(question="台灣的首都是哪裡?")
print(answer)
answer = conditional_chain.run(question="為什麼天空是藍色的?")
print(answer)

這段程式碼示範瞭如何使用 ConditionalChain 根據問題型別選擇不同的 LLMChain 進行處理。routing_func 負責根據輸入判斷執行哪個鏈。

更進階的鏈式組合:開發複雜 AI 工作流程

除了 SequentialChainConditionalChain,LangChain 還提供了其他鏈式組合方式,例如 RouterChain,可以根據輸入動態選擇執行路徑。透過靈活運用這些鏈式組合策略,我們可以建構更複雜、更強大的 AI 應用,例如多輪對話系統、自動化寫作工具等等。

  graph LR
    A[輸入問題] --> B{問題分類別};
    B -- 簡單問題 --> C[簡單回答];
    B -- 複雜問題 --> D[詳細回答];
    C --> E[輸出答案];
    D --> E;

圖表説明: 此流程圖展示了條件鏈的工作原理。根據輸入問題的型別,系統會選擇不同的處理路徑,最終輸出相應的答案。

透過這些實戰案例和圖表説明,我希望讀者能更清晰地理解 LangChain 中的鏈式組合策略,並將其應用到自己的 AI 應用開發中。記住,LangChain 的核心價值在於其靈活性,它允許我們像拼積木一樣組合不同的元件,創造無限可能。

  graph LR
    B[B]
    C[C]
    D[D]
    E[E]
    A[使用者提問] --> B{檔案檢索};
    B --> C{相關檔案};
    C --> D{提示建構};
    D --> E{LLM 生成答案};
    E --> F[答案回傳給使用者];

圖表説明: 此流程圖展示了 RAG 的運作方式。首先,使用者提出問題。系統接著從外部資料來源(例如向量資料函式庫)檢索相關檔案。接著,系統使用檢索到的檔案和使用者問題建構提示。LLM 接收提示並生成答案。最後,系統將答案回傳給使用者。

RAG 的應用案例

以下是一些 RAG 的應用案例:

  • 進階問答系統: RAG 能夠根據特設定檔案或知識函式庫回答問題,例如企業內部檔案、產品説明書或研究論文。
  • 搜尋應用程式: RAG 可以提升搜尋結果的相關性,並提供更精確的答案摘要。
  • 聊天機器人: RAG 可以讓聊天機器人根據特定資訊來源回答問題,例如客戶支援檔案或產品目錄。

使用 LangChain 實作 RAG

LangChain 提供了簡化 RAG 流程的工具。以下是一個使用 LangChain 實作 RAG 的 Python 程式碼範例:

from langchain.chains import RetrievalQA
from langchain.llms import OpenAI
from langchain.document_loaders import TextLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.text_splitter import CharacterTextSplitter

# 載入檔案
loader = TextLoader('state_of_the_union.txt')
documents = loader.load()

# 分割檔案
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

# 建立向量資料函式庫
embeddings = OpenAIEmbeddings()
db = FAISS.from_documents(docs, embeddings)

# 建立 RetrievalQA 鏈
retriever = db.as_retriever()
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=retriever)

# 提問
query = "國情諮文的主題是什麼?"
answer = qa(query)
print(answer['result'])

這段程式碼示範瞭如何使用 LangChain 建立一個簡單的 RAG 系統。首先,它載入一個文字檔案並將其分割成多個區塊。接著,它使用 OpenAI 的嵌入模型建立一個向量資料函式庫。然後,它建立一個 RetrievalQA 鏈,該鏈使用向量資料函式庫檢索相關檔案,並將其傳遞給 LLM 生成答案。最後,它回答使用者提出的問題。

RAG 是一種強大的技術,可以提升 LLM 應用程式的效能和準確性。透過結合檢索和生成,RAG 能夠讓 AI 更智慧地理解並回應使用者需求。LangChain 提供了簡化 RAG 流程的工具,讓開發者更容易構建根據 RAG 的應用程式。我鼓勵所有 AI 開發者探索 RAG 的潛力,並將其應用於各種應用場景。

from langchain.text_splitter import CharacterTextSplitter

# 初始化文字分割器,設定分隔符、區塊大小和重疊大小
text_splitter = CharacterTextSplitter(
    separator="\n\n",
    chunk_size=1000,
    chunk_overlap=200,
    length_function=len,
)

# 輸入文字
text = """這是一段很長的文字。
它包含多個段落。

我們使用 CharacterTextSplitter 來分割它。

分割後的區塊大小約為 1000 個字元,重疊部分為 200 個字元。

這樣可以確保上下文連貫性。
"""

# 分割文字
docs = text_splitter.split_text(text)

# 輸出分割後的文字區塊
for i, doc in enumerate(docs):
    print(f"區塊 {i+1}:\n{doc}\n")

這段程式碼示範瞭如何使用 CharacterTextSplitter 將一段長文字分割成多個區塊。separator 引數指定了用於分割文字的分隔符,這裡使用了兩個換行符 \n\nchunk_size 引數設定了每個區塊的最大字元數,chunk_overlap 引數設定了相鄰區塊之間的重疊字元數。length_function 引數指定了用於計算文字長度的函式,這裡使用了 Python 內建的 len 函式。

視覺化文字分割流程

以下使用 Mermaid 流程圖展示文字分割的流程:

  graph LR
    B[B]
A[輸入文字] --> B{初始化文字分割器};
B --> C[分割文字];
C --> D[輸出文字區塊];

圖表説明: 此流程圖展示了文字分割的基本步驟。首先輸入待分割的文字,然後初始化文字分割器,接著進行文字分割,最後輸出分割後的文字區塊。

  classDiagram
    class TextSplitter{
        separator
        chunk_size
        chunk_overlap
    }
    class CharacterTextSplitter{
        split_text()
    }
    CharacterTextSplitter --|> TextSplitter

圖表説明: 此類別圖展示了 TextSplitterCharacterTextSplitter 之間的繼承關係,以及 CharacterTextSplitter 的主要引數。

善用 LangChain 提供的文字分割器,可以有效地處理大量文字資料,並為後續的 LLM 應用做好準備。選擇合適的分割器和引數設定,能確保文字區塊的合理大小和上下文連貫性,從而提高 LLM 的處理效率和準確性。

透過理解不同文字分割器的特性和使用方法,並結合 圖表等視覺化工具,我們可以更好地掌握文書處理技巧,提升工作效率。記住,選擇正確的工具和方法,能讓你的文書處理工作事半功倍。

from langchain.embeddings import OpenAIEmbeddings, CacheBackedEmbeddings
from langchain.vectorstores import FAISS
from langchain.storage import LocalFileStore

store = LocalFileStore("./cache/")  # 設定快取儲存位置

# 初始化 OpenAIEmbeddings 和 CacheBackedEmbeddings
underlying_embeddings = OpenAIEmbeddings()
embeddings = CacheBackedEmbeddings.from_bytes_store(
    underlying_embeddings, store, namespace="reviews"
)

# 使用 FAISS 向量儲存函式庫
db = FAISS.from_texts(reviews, embeddings)

# 執行查詢
query = "顧客評論中提到的優點是什麼?"
docs = db.similarity_search(query)

# 顯示查詢結果
for doc in docs:
    print(doc.page_content)

這段程式碼示範瞭如何使用 CacheBackedEmbeddings 快取嵌入,並使用 FAISS 向量儲存函式庫進行相似性搜尋。首先,我們初始化了 LocalFileStore 來儲存快取,然後使用它建立 CacheBackedEmbeddings 例項。接著,使用 FAISS.from_texts 建立向量儲存函式庫,並使用 similarity_search 方法搜尋與查詢最相似的評論。

這個例子展示瞭如何結合文字嵌入、快取和向量儲存來有效地分析顧客評論。透過這些技術,我們可以從大量非結構化資料中提取有價值的洞見,並應用於產品開發、客戶服務和市場行銷等領域。

  graph LR
    B[B]
    E[E]
    A[顧客評論] --> B{文字嵌入}
    B --> C[向量儲存]
    D[查詢] --> E{文字嵌入}
    E --> C
    C --> F[相似性搜尋]
    F --> G[結果]

這張流程圖展示了使用文字嵌入和向量儲存進行顧客評論分析的流程。首先,顧客評論和查詢都經過文字嵌入轉換成向量。然後,評論嵌入被儲存在向量儲存函式庫中。當使用者提交查詢時,查詢也被嵌入成向量,並用於在向量儲存函式庫中進行相似性搜尋。最後,系統傳回與查詢最相似的評論作為結果。

這篇文章探討瞭如何使用 LangChain 處理程式碼和文字資料,包含程式碼分割、摘要、搜尋以及文字嵌入技術的應用。同時,也示範瞭如何利用向量儲存和快取機制提升效率。希望這些技巧能幫助你更好地管理和分析程式碼及文字資料,從中提取有價值的資訊。

  graph LR
    B[B]
    A[輸入] --> B{工具};
    B --> C[輸出];

圖表説明: LangChain 代理接收輸入,使用工具處理輸入,然後產生輸出。

代理的思考過程:一步一步解決問題

LangChain 代理的思考過程類別似於人類解決問題的方式,它會經歷以下步驟:

  1. 定義問題: 確定需要解決的特定問題或需要實作的目標。
  2. 收集資訊: 從各種來源收集與問題相關的資訊,例如資料函式庫、API 或感測器。
  3. 評估選項: 評估不同的解決方案或行動方案,並考慮每個選項的潛在後果。
  4. 做出決策: 選擇最佳行動方案。
  5. 採取行動: 執行所選的行動方案。
  6. 評估結果: 評估行動的結果,並根據需要進行調整。

使用 LangChain 建立自定義代理

LangChain 提供了靈活的框架,可以建立自定義代理,以滿足你的特定需求。以下是一個簡單的範例:

from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent
from langchain.llms import OpenAI

# 定義工具
tools = [
    Tool(
        name="搜尋",
        func=lambda q: q,  # 這裡只是個範例,實際應用中需要替換成搜尋函式
        description="用於搜尋資訊",
    ),
]

# 建立代理
llm = OpenAI(temperature=0)
agent = LLMSingleActionAgent.from_tools(tools, llm, verbose=True)
agent_executor = AgentExecutor.from_agent_and_tools(agent, tools, verbose=True)

# 執行代理
agent_executor.run("搜尋 LangChain 代理的相關資訊")

這段程式碼定義了一個名為「搜尋」的工具,並使用 LLMSingleActionAgent 建立了一個代理。代理會使用指定的 LLM 和工具來執行任務。在這個例子中,代理會執行「搜尋 LangChain 代理的相關資訊」這個任務。

LangChain 代理為構建自主思考的應用程式提供了強大的工具。透過理解代理的核心概念、型別、工作流程和思考過程,我們可以利用 LangChain 的靈活性創造出能夠解決複雜問題的人工智慧應用。隨著技術的進一步發展,LangChain 代理將在更多領域發揮重要作用,推動軟體開發的進步。

# 安裝必要套件 (如果尚未安裝)
!pip install langchain==0.0.218 openai==0.27.8 python-dotenv==1.0.0 google-search-results==2.4.2

import os
from dotenv import load_dotenv
import openai
from langchain.agents import load_tools, initialize_agent
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI

# 載入環境變數
load_dotenv()

# 設定 API 金鑰 (請將 YOUR_OPENAI_API_KEY 和 YOUR_SERPAPI_API_KEY 替換為您的實際金鑰)
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"
os.environ["SERPAPI_API_KEY"] = "YOUR_SERPAPI_API_KEY"

# 初始化 OpenAI 語言模型
llm = OpenAI(temperature=0)
chat_model = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo") # 使用 gpt-3.5-turbo 以降低成本

# 載入工具
tools = load_tools(["serpapi", "llm-math"], llm=llm)

# 初始化代理
agent = initialize_agent(tools, chat_model, agent="zero-shot-react-description", verbose=True)

# 損益平衡點計算範例
try:
    agent_response = agent.run("一家公司每單位產品售價 20 元,固定成本為 50,000 元,每單位產品可變成本為 10 元。該公司的損益平衡點是多少單位?")
    print(agent_response)
except Exception as e:
    print(f"代理執行過程中發生錯誤:{e}")


# 更多損益平衡點計算範例,測試代理的適應性
examples = [
    "假設一家公司銷售每件 100 元的產品。固定成本為 20,000 元,每件產品的可變成本為 60 元。損益平衡點是多少?",
    "如果一家公司的固定成本為 10,000 元,每單位產品售價為 5 元,每單位可變成本為 2 元,那麼損益平衡點的銷售額是多少?",
    "一家新創公司的固定成本為 30,000 元,每單位產品售價為 15 元,每單位可變成本為 5 元。損益平衡點是多少單位?",
]

for example in examples:
    try:
        agent_response = agent.run(example)
        print(f"問題:{example}\n答案:{agent_response}\n")
    except Exception as e:
        print(f"代理執行過程中發生錯誤:{e}")

這段程式碼示範瞭如何使用 LangChain 建立一個可以計算損益平衡點的智慧代理。 首先,它安裝了必要的套件,包括 langchain, openai, python-dotenv, 和 google-search-results。 然後,它載入了環境變數,其中包含 OpenAI 和 SerpAPI 的 API 金鑰。 接著,它初始化了 OpenAI 語言模型和聊天模型,並載入了 serpapillm-math 工具。 serpapi 工具允許代理執行網路搜尋,而 llm-math 工具允許代理執行數學運算。 初始化代理後,程式碼使用 agent.run() 方法執行代理,並提供一個問題作為輸入。 代理會使用其工具和語言模型來回答問題。 程式碼還包含錯誤處理,以防代理執行過程中發生錯誤。 最後,程式碼提供了一些額外的範例,以展示代理如何處理不同型別的損益平衡點計算問題。 使用 gpt-3.5-turbo 模型可以有效降低 API 使用成本,同時保持良好的效能。 程式碼中的註解詳細解釋了每個步驟的目的,使程式碼更易於理解。

  graph LR
    B[B]
    C[C]
    E[E]
    A[使用者提問] --> B{代理分析問題}
    B --> C{選擇工具: SerpAPI / llm-math}
    C --> D[執行工具]
    D --> E{整合結果}
    E --> F[輸出答案]

圖一:損益平衡點計算代理流程

這個流程圖清晰地展現了代理如何逐步解決損益平衡點計算問題,從使用者提問到最終輸出答案。

核心要領:

LangChain Agents 的核心優勢在於其靈活性和適應性。它們可以根據不同的任務需求動態選擇和使用工具,而不需要預先定義固定的執行流程。 這個特性使得 Agents 非常適合處理複雜的、需要多步驟推理的任務,例如損益平衡點計算。

玄貓指引:

在實際應用中,您可以根據具體的業務需求調整代理的組態,例如選擇不同的語言模型、載入不同的工具,以及修改代理的提示範本。 此外,您還可以透過監控代理的執行日誌來分析其決策過程,並進一步最佳化代理的效能。

額外説明:

  • 確保您的 .env 檔案包含正確的 API 金鑰。
  • 您可以根據需要調整 temperature 引數來控制語言模型的創造性。
  • 如果您遇到 API 金鑰相關問題,請檢查您的環境變數設定。

在行動應用程式開發的浪潮中,準確評估投資回報至關重要。損益平衡分析是評估投資回報週期的有效工具,它能幫助我們瞭解何時能收回成本,並開始盈利。本文將探討如何利用損益平衡分析,精準預測行動應用程式投資的回報週期,並提供實用的 Python 程式碼範例與圖表説明。

損益平衡點:投資回報的關鍵指標

損益平衡點是指總收入等於總成本的點,也就是既不盈利也不虧損的狀態。對於行動應用程式開發而言,損益平衡點分析可以幫助我們瞭解應用程式需要產生多少收入才能彌補開發和維護成本。

計算損益平衡點:Python 程式碼實作

以下 Python 程式碼示範如何計算行動應用程式的損益平衡點:

import math

def calculate_break_even_point(fixed_costs, revenue_per_unit, variable_costs_per_unit):
    """
    計算損益平衡點。

    Args:
        fixed_costs: 固定成本。
        revenue_per_unit: 每單位收入。
        variable_costs_per_unit: 每單位變動成本。

    Returns:
        損益平衡點(單位數量)。
    """
    if revenue_per_unit <= variable_costs_per_unit:
        return float('inf')  # 如果每單位收入小於等於每單位變動成本,則永遠無法達到損益平衡點
    return fixed_costs / (revenue_per_unit - variable_costs_per_unit)

# 範例:一家軟體公司開發新的行動應用程式
fixed_costs = 200000  # 初始開發成本
revenue_per_month = 15000  # 每月收入
variable_costs_per_month = 5000  # 每月維護成本

break_even_point_months = calculate_break_even_point(fixed_costs, revenue_per_month, variable_costs_per_month)

print(f"損益平衡點:{math.ceil(break_even_point_months)} 個月")

這段程式碼定義了一個名為 calculate_break_even_point 的函式,它接受固定成本、每單位收入和每單位變動成本作為輸入,並傳回損益平衡點(單位數量)。函式中包含一個檢查,如果每單位收入小於等於每單位變動成本,則傳回 float('inf'),表示永遠無法達到損益平衡點。接著,程式碼使用提供的範例資料呼叫函式,計算行動應用程式達到損益平衡點所需的月數,並列印結果。

案例分析:視覺化損益平衡點

以下 圖表展示了案例中的成本和收入關係:

  graph LR
    A[固定成本] --> C(總成本)
    B[變動成本] --> C
    D[收入] --> E((損益平衡點))
    C --> E

圖表説明: 此流程圖展示了固定成本、變動成本和收入如何影響損益平衡點。

提升獲利能力:關鍵策略

達到損益平衡點只是第一步,提升應用程式的獲利能力才是最終目標。以下是一些關鍵策略:

  • 提高使用者留存率: 透過持續最佳化使用者經驗,提升應用程式的使用者留存率,進而增加長期收入。
  • 探索多元變現模式: 除了應用程式內購買,還可以探索廣告、訂閲等多元變現模式,增加收入來源。
  • 最佳化營運成本: 透過流程最佳化和技術提升,降低應用程式的維護和營運成本,提高盈利能力。

透過損益平衡點分析,結合有效的營運策略,行動應用程式開發者可以更精準地預測投資回報,並做出更明智的商業決策。 這個案例分析和程式碼示例,提供了一個清晰的框架,讓開發者能夠更好地理解和應用損益平衡點分析,進而提升行動應用程式的投資回報率。