源代码
此笔记本介绍了如何使用特殊的方法通过语言解析来加载源代码文件:每个顶级函数和类在代码中会被分别加载到独立的文档中。任何已经在加载的函数和类之外的顶层代码将被加载到一个单独的文档中。
此方法有可能提高问答模型对源代码的准确性。
支持的代码解析语言有:
- C (*)
- C++ (*)
- C# (*)
- COBOL
- Elixir
- Go (*)
- Java (*)
- JavaScript(需要安装包
esprima) - Kotlin (*)
- Lua (*)
- Perl (*)
- Python
- Ruby (*)
- Rust (*)
- Scala (*)
- TypeScript (*)
标记有 (*) 的项目需要安装 tree_sitter 和 tree_sitter_languages 软件包。 使用 tree_sitter 可以轻松添加对其他语言的支持, 尽管目前这需要修改 LangChain。
The language used for parsing can be configured, along with the minimum number of lines required to activate the splitting based on syntax.
如果未显式指定语言,LanguageParser将从文件名扩展名(如有)中推断一个。
%pip install -qU esprima esprima tree_sitter tree_sitter_languages
import warnings
warnings.filterwarnings("ignore")
from pprint import pprint
from langchain_community.document_loaders.generic import GenericLoader
from langchain_community.document_loaders.parsers import LanguageParser
from langchain_text_splitters import Language
loader = GenericLoader.from_filesystem(
"./example_data/source_code",
glob="*",
suffixes=[".py", ".js"],
parser=LanguageParser(),
)
docs = loader.load()
len(docs)
6
for document in docs:
pprint(document.metadata)
{'content_type': 'functions_classes',
'language': <Language.PYTHON: 'python'>,
'source': 'example_data/source_code/example.py'}
{'content_type': 'functions_classes',
'language': <Language.PYTHON: 'python'>,
'source': 'example_data/source_code/example.py'}
{'content_type': 'simplified_code',
'language': <Language.PYTHON: 'python'>,
'source': 'example_data/source_code/example.py'}
{'content_type': 'functions_classes',
'language': <Language.JS: 'js'>,
'source': 'example_data/source_code/example.js'}
{'content_type': 'functions_classes',
'language': <Language.JS: 'js'>,
'source': 'example_data/source_code/example.js'}
{'content_type': 'simplified_code',
'language': <Language.JS: 'js'>,
'source': 'example_data/source_code/example.js'}
print("\n\n--8<--\n\n".join([document.page_content for document in docs]))
class MyClass:
def __init__(self, name):
self.name = name
def greet(self):
print(f"Hello, {self.name}!")
--8<--
def main():
name = input("Enter your name: ")
obj = MyClass(name)
obj.greet()
--8<--
# Code for: class MyClass:
# Code for: def main():
if __name__ == "__main__":
main()
--8<--
class MyClass {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, ${this.name}!`);
}
}
--8<--
function main() {
const name = prompt("Enter your name:");
const obj = new MyClass(name);
obj.greet();
}
--8<--
// Code for: class MyClass {
// Code for: function main() {
main();
The parser can be disabled for small files.
参数 parser_threshold 表示源代码文件必须具有的最少行数,才能使用解析器进行分段。
loader = GenericLoader.from_filesystem(
"./example_data/source_code",
glob="*",
suffixes=[".py"],
parser=LanguageParser(language=Language.PYTHON, parser_threshold=1000),
)
docs = loader.load()
len(docs)
1
print(docs[0].page_content)
class MyClass:
def __init__(self, name):
self.name = name
def greet(self):
print(f"Hello, {self.name}!")
def main():
name = input("Enter your name: ")
obj = MyClass(name)
obj.greet()
if __name__ == "__main__":
main()
分割
那些函数、类或脚本过大时,可能需要进行额外的拆分。
loader = GenericLoader.from_filesystem(
"./example_data/source_code",
glob="*",
suffixes=[".js"],
parser=LanguageParser(language=Language.JS),
)
docs = loader.load()
from langchain_text_splitters import (
Language,
RecursiveCharacterTextSplitter,
)
js_splitter = RecursiveCharacterTextSplitter.from_language(
language=Language.JS, chunk_size=60, chunk_overlap=0
)
result = js_splitter.split_documents(docs)
len(result)
7
print("\n\n--8<--\n\n".join([document.page_content for document in result]))
class MyClass {
constructor(name) {
this.name = name;
--8<--
}
--8<--
greet() {
console.log(`Hello, ${this.name}!`);
}
}
--8<--
function main() {
const name = prompt("Enter your name:");
--8<--
const obj = new MyClass(name);
obj.greet();
}
--8<--
// Code for: class MyClass {
// Code for: function main() {
--8<--
main();
添加语言使用Tree-sitter模板
使用Tree-Sitter模板扩展语言支持涉及几个关键步骤:
- 创建一个新的语言文件:
- 在指定目录(langchain/libs/community/langchain_community/document_loaders/parsers/language)下创建一个新文件。
- 基于现有语言文件如
cpp.py的结构和解析逻辑来构建这个文件。 - 您还需要在langchain目录下(langchain/libs/langchain/langchain/document_loaders/parsers/language)创建一个文件。
- 解析语言特定内容:
- Testing the Language Parser:
- Integration into the Parser and Text Splitter:
通过遵循这些步骤并确保全面的测试和集成,您将成功地使用Tree-Sitter模板扩展语言支持。
最佳祝运!