本教程将介绍如何使用LangChain库和chatglm API来解决一个4x4的数独问题。我们将通过以下步骤实现这一目标:
- 初始化chatglm 的聊天模型。
- 定义数独问题和解决方案。
- 创建一个自定义的检查器来验证每一步的思考。
- 使用ToTChain来运行整个思考过程。
1. 初始化chatglm4 的聊天模型
首先,我们需要导入langchain_openai
库中的ChatOpenAI
类,并初始化一个聊天模型实例。
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
temperature=1,
model="GLM-4-Plus",
openai_api_key="your api key",
openai_api_base="https://open.bigmodel.cn/api/paas/v4/",
max_tokens=512,
)
2. 定义数独问题和解决方案
接下来,我们定义一个4x4的数独问题和其解决方案,并生成问题描述。
sudoku_puzzle = "3,*,*,2|1,*,3,*|*,1,*,3|4,*,*,1"
sudoku_solution = "3,4,1,2|1,2,3,4|2,1,4,3|4,3,2,1"
problem_description = f"""
{sudoku_puzzle}
- This is a 4x4 Sudoku puzzle.
- The * represents a cell to be filled.
- The | character separates rows.
- At each step, replace one or more * with digits 1-4.
- There must be no duplicate digits in any row, column or 2x2 subgrid.
- Keep the known digits from previous valid thoughts in place.
- Each thought can be a partial or the final solution.
""".strip()
print(problem_description)
输出结果如下:
3,*,*,2|1,*,3,*|*,1,*,3|4,*,*,1
- This is a 4x4 Sudoku puzzle.
- The * represents a cell to be filled.
- The | character separates rows.
- At each step, replace one or more * with digits 1-4.
- There must be no duplicate digits in any row, column or 2x2 subgrid.
- Keep the known digits from previous valid thoughts in place.
- Each thought can be a partial or the final solution.
3. 创建自定义检查器
我们需要创建一个自定义的检查器MyChecker
,用于验证每一步的思考是否有效。
import re
from typing import Tuple
from langchain_experimental.tot.checker import ToTChecker
from langchain_experimental.tot.thought import ThoughtValidity
class MyChecker(ToTChecker):
def evaluate(
self, problem_description: str, thoughts: Tuple[str, ...] = ()
) -> ThoughtValidity:
last_thought = thoughts[-1]
clean_solution = last_thought.replace(" ", "").replace('"', "")
regex_solution = clean_solution.replace("*", ".").replace("|", "\\|")
if sudoku_solution in clean_solution:
return ThoughtValidity.VALID_FINAL
elif re.search(regex_solution, sudoku_solution):
return ThoughtValidity.VALID_INTERMEDIATE
else:
return ThoughtValidity.INVALID
4. 测试检查器
我们可以通过一些断言来测试检查器的功能。
checker = MyChecker()
assert (
checker.evaluate("", ("3,*,*,2|1,*,3,*|*,1,*,3|4,*,*,1",))
== ThoughtValidity.VALID_INTERMEDIATE
)
assert (
checker.evaluate("", ("3,4,1,2|1,2,3,4|2,1,4,3|4,3,2,1",))
== ThoughtValidity.VALID_FINAL
)
assert (
checker.evaluate("", ("3,4,1,2|1,2,3,4|2,1,4,3|4,3,*,1",))
== ThoughtValidity.VALID_INTERMEDIATE
)
assert (
checker.evaluate("", ("3,4,1,2|1,2,3,4|2,1,4,3|4,*,3,1",))
== ThoughtValidity.INVALID
)
5. 运行ToTChain
最后,我们使用ToTChain
来运行整个思考过程,并尝试解决数独问题。
from langchain_experimental.tot.base import ToTChain
tot_chain = ToTChain(
llm=llm, checker=MyChecker(), k=30, c=5, verbose=True, verbose_llm=False
)
tot_chain.run(problem_description=problem_description)
输出结果如下:
C:\Users\32564\AppData\Local\Temp\ipykernel_5080\1223294212.py:6: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use :meth:`~invoke` instead.
tot_chain.run(problem_description=problem_description)
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[1m> Entering new ToTChain chain...[0m
Starting the ToT solve procedure.
[33;1m[1;3mThought: 3,*,*,2|1,*,3,*|*,1,*,3|4,*,*,1
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[31;1m[1;3m Thought: 3,1,*,2|1,*,3,*|*,1,*,3|4,*,*,1
[0m[31;1m[1;3m Thought: 3,*,4,2|1,*,3,*|*,1,*,3|4,*,*,1
[0m[33;1m[1;3m Thought: 3,*,*,2|1,2,3,*|*,1,*,3|4,*,*,1
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought: 3,*,*,2|1,2,3,4|*,1,*,3|4,*,*,1
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought: 3,*,*,2|1,2,3,4|2,1,*,3|4,*,*,1
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought: 3,*,*,2|1,2,3,4|2,1,4,3|4,*,*,1
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought: 3,*,*,2|1,2,3,4|2,1,4,3|4,3,*,1
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought:
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought:
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought: 3,*,*,2|1,2,3,4|2,1,4,3|4,3,2,1
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought: 3,*,*,2|1,2,3,4|2,1,4,3|4,3,2,1
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[31;1m[1;3m Thought: 3,1,*,2|1,2,3,4|2,1,4,3|4,3,2,1
[0m[33;1m[1;3m Thought: 3,4,*,2|1,2,3,4|2,1,4,3|4,3,2,1
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought:
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought:
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[33;1m[1;3m Thought:
[0m
d:\soft\anaconda\envs\langchain\Lib\site-packages\langchain\chains\llm.py:341: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
warnings.warn(
[32;1m[1;3m Thought: 3,4,1,2|1,2,3,4|2,1,4,3|4,3,2,1
[0m
[1m> Finished chain.[0m
'3,4,1,2|1,2,3,4|2,1,4,3|4,3,2,1'
通过以上步骤,我们成功地使用LangChain解决了一个4x4的数独问题。希望这个教程对你有所帮助!如果有任何问题,欢迎随时提问。