projects/repobot/v3/repobot.py

53 行 · 1.8 KB

程式碼和執行結果保留原樣(簡體中文),與實際執行時完全一致。

"""RepoBot v3:会自己查文档、翻源码的 httpx 答疑助手。

和 v2 的区别:v2 每个问题固定走"改写 → 检索 → 回答";v3 是一个智能体,
自己决定先查文档还是翻源码、查几次、什么时候可以回答。

    python repobot.py            开始对话,输入空行退出
    python repobot.py --quiet    不显示每一步的工具调用
"""
import sys

import openai

import agent
import tools
from retrieval import Retriever

CACHE_DIR = tools.HERE / ".cache"
MAX_MESSAGES = 20


def main():
    quiet = "--quiet" in sys.argv
    tools.ensure_source()
    print("正在加载文档和模型……", flush=True)
    tools.retriever = Retriever(tools.DOCS_DIR, CACHE_DIR)
    print(f"RepoBot v3({agent.llm.MODEL})。可以查文档和源码。问我 httpx 的问题,输入空行退出。")

    history, total = [], 0.0
    interactive = sys.stdin.isatty()
    while True:
        try:
            question = input("\n你:" if interactive else "").strip()
        except EOFError:
            break
        if not question:
            break
        if not interactive:
            print(f"\n你:{question}")
        try:
            answer, stats = agent.run(question, history, show=(lambda *a: None) if quiet else print)
        except openai.APIError as e:
            print(f"[出错了:{type(e).__name__},这一轮作废,可以再问一次]")
            continue
        total += stats["cost"]
        print(f"RepoBot:{answer}")
        print(f"[{stats['steps']} 次模型调用,{stats['tool_calls']} 次工具调用,本轮 {stats['cost']:.5f} 美元,累计 {total:.5f} 美元]")
        history += [{"role": "user", "content": question}, {"role": "assistant", "content": answer}]
        history = history[-MAX_MESSAGES:]


if __name__ == "__main__":
    main()